1 /* ownCloud Android client application 
   2  *   Copyright (C) 2012-2013 ownCloud Inc. 
   4  *   This program is free software: you can redistribute it and/or modify 
   5  *   it under the terms of the GNU General Public License as published by 
   6  *   the Free Software Foundation, either version 2 of the License, or 
   7  *   (at your option) any later version. 
   9  *   This program is distributed in the hope that it will be useful, 
  10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  12  *   GNU General Public License for more details. 
  14  *   You should have received a copy of the GNU General Public License 
  15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  19 package com
.owncloud
.android
.ui
.preview
; 
  21 import android
.accounts
.Account
; 
  22 import android
.app
.Activity
; 
  23 import android
.app
.AlertDialog
; 
  24 import android
.content
.DialogInterface
; 
  25 import android
.content
.Intent
; 
  26 import android
.media
.MediaPlayer
; 
  27 import android
.media
.MediaPlayer
.OnCompletionListener
; 
  28 import android
.media
.MediaPlayer
.OnErrorListener
; 
  29 import android
.media
.MediaPlayer
.OnPreparedListener
; 
  30 import android
.net
.Uri
; 
  31 import android
.os
.Bundle
; 
  32 import android
.util
.Log
; 
  33 import android
.view
.MotionEvent
; 
  34 import android
.widget
.MediaController
; 
  35 import android
.widget
.VideoView
; 
  37 import com
.owncloud
.android
.AccountUtils
; 
  38 import com
.owncloud
.android
.R
; 
  39 import com
.owncloud
.android
.datamodel
.OCFile
; 
  40 import com
.owncloud
.android
.media
.MediaService
; 
  43  *  Activity implementing a basic video player. 
  45  *  Used as an utility to preview video files contained in an ownCloud account. 
  47  *  Currently, it always plays in landscape mode, full screen. When the playback ends, 
  48  *  the activity is finished.  
  50  *  @author David A. Velasco 
  52 public class PreviewVideoActivity 
extends Activity 
implements OnCompletionListener
, OnPreparedListener
, OnErrorListener 
{ 
  54     /** Key to receive an {@link OCFile} to play as an extra value in an {@link Intent} */ 
  55     public static final String EXTRA_FILE 
= "FILE"; 
  57     /** Key to receive the ownCloud {@link Account} where the file to play is saved as an extra value in an {@link Intent} */ 
  58     public static final String EXTRA_ACCOUNT 
= "ACCOUNT"; 
  60     /** Key to receive a flag signaling if the video should be started immediately */ 
  61     public static final String EXTRA_AUTOPLAY 
= "AUTOPLAY"; 
  63     /** Key to receive the position of the playback where the video should be put at start */ 
  64     public static final String EXTRA_START_POSITION 
= "START_POSITION"; 
  66     private static final String TAG 
= PreviewVideoActivity
.class.getSimpleName(); 
  68     private OCFile mFile
;                       // video file to play 
  69     private Account mAccount
;                   // ownCloud account holding mFile 
  70     private int mSavedPlaybackPosition
;         // in the unit time handled by MediaPlayer.getCurrentPosition() 
  71     private boolean mAutoplay
;                  // when 'true', the playback starts immediately with the activity 
  72     private VideoView mVideoPlayer
;             // view to play the file; both performs and show the playback 
  73     private MediaController mMediaController
;   // panel control used by the user to control the playback 
  76      *  Called when the activity is first created. 
  78      *  Searches for an {@link OCFile} and ownCloud {@link Account} holding it in the starting {@link Intent}. 
  80      *  The {@link Account} is unnecessary if the file is downloaded; else, the {@link Account} is used to  
  81      *  try to stream the remote file - TODO get the streaming works 
  86     public void onCreate(Bundle savedInstanceState
) { 
  87         super.onCreate(savedInstanceState
); 
  89         setContentView(R
.layout
.video_layout
); 
  91         Bundle extras 
= getIntent().getExtras(); 
  92         mFile 
= extras
.getParcelable(EXTRA_FILE
); 
  93         mAccount 
= extras
.getParcelable(EXTRA_ACCOUNT
); 
  94         mSavedPlaybackPosition 
= extras
.getInt(EXTRA_START_POSITION
); 
  95         mAutoplay 
= extras
.getBoolean(EXTRA_AUTOPLAY
); 
  97         mVideoPlayer 
= (VideoView
) findViewById(R
.id
.videoPlayer
); 
  99         // set listeners to get more contol on the playback 
 100         mVideoPlayer
.setOnPreparedListener(this); 
 101         mVideoPlayer
.setOnCompletionListener(this); 
 102         mVideoPlayer
.setOnErrorListener(this); 
 104         // keep the screen on while the playback is performed (prevents screen off by battery save) 
 105         mVideoPlayer
.setKeepScreenOn(true
); 
 108             if (mFile
.isDown()) { 
 109                 mVideoPlayer
.setVideoPath(mFile
.getStoragePath()); 
 111             } else if (mAccount 
!= null
) { 
 113                 String url 
= AccountUtils
.constructFullURLForAccount(this, mAccount
) + mFile
.getRemotePath(); 
 114                 mVideoPlayer
.setVideoURI(Uri
.parse(url
)); 
 117                 onError(null
, MediaService
.OC_MEDIA_ERROR
, R
.string
.media_err_no_account
); 
 120             // create and prepare control panel for the user 
 121             mMediaController 
= new MediaController(this); 
 122             mMediaController
.setMediaPlayer(mVideoPlayer
); 
 123             mMediaController
.setAnchorView(mVideoPlayer
); 
 124             mVideoPlayer
.setMediaController(mMediaController
); 
 127             onError(null
, MediaService
.OC_MEDIA_ERROR
, R
.string
.media_err_nothing_to_play
); 
 133     public void onBackPressed() { 
 134         Intent i 
= new Intent(); 
 135         i
.putExtra(EXTRA_AUTOPLAY
, mVideoPlayer
.isPlaying()); 
 136         i
.putExtra(EXTRA_START_POSITION
, mVideoPlayer
.getCurrentPosition()); 
 137         setResult(RESULT_OK
, i
); 
 138         super.onBackPressed(); 
 143      * Called when the file is ready to be played. 
 145      * Just starts the playback. 
 147      * @param   mp    {@link MediaPlayer} instance performing the playback. 
 150     public void onPrepared(MediaPlayer vp
) { 
 151         mVideoPlayer
.seekTo(mSavedPlaybackPosition
); 
 153             mVideoPlayer
.start(); 
 155         mMediaController
.show(5000);   
 160      * Called when the file is finished playing. 
 164      * @param   mp    {@link MediaPlayer} instance performing the playback. 
 167     public void onCompletion(MediaPlayer  mp
) { 
 168         mVideoPlayer
.seekTo(0); 
 173      * Called when an error in playback occurs. 
 175      * @param   mp      {@link MediaPlayer} instance performing the playback. 
 176      * @param   what    Type of error 
 177      * @param   extra   Extra code specific to the error 
 180     public boolean onError(MediaPlayer mp
, int what
, int extra
) { 
 181         Log
.e(TAG
, "Error in video playback, what = " + what 
+ ", extra = " + extra
); 
 183         if (mMediaController 
!= null
) { 
 184             mMediaController
.hide(); 
 187         if (mVideoPlayer
.getWindowToken() != null
) { 
 188             String message 
= MediaService
.getMessageForMediaError(this, what
, extra
); 
 189             new AlertDialog
.Builder(this) 
 191                     .setPositiveButton(android
.R
.string
.VideoView_error_button
, 
 192                             new DialogInterface
.OnClickListener() { 
 193                                 public void onClick(DialogInterface dialog
, int whichButton
) { 
 194                                     PreviewVideoActivity
.this.onCompletion(null
); 
 197                     .setCancelable(false
) 
 205      * Screen touches trigger the appearance of the control panel for a limited time. 
 210     public boolean onTouchEvent (MotionEvent ev
){  
 211         if (ev
.getAction() == MotionEvent
.ACTION_DOWN
) { 
 212             mMediaController
.show(MediaService
.MEDIA_CONTROL_SHORT_LIFE
);