PreviewVideoActivity.java 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /**
  2. * ownCloud Android client application
  3. *
  4. * @author David A. Velasco
  5. * Copyright (C) 2015 ownCloud Inc.
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2,
  9. * as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. package com.owncloud.android.ui.preview;
  21. import android.accounts.Account;
  22. import android.content.DialogInterface;
  23. import android.content.Intent;
  24. import android.media.MediaPlayer;
  25. import android.media.MediaPlayer.OnCompletionListener;
  26. import android.media.MediaPlayer.OnErrorListener;
  27. import android.media.MediaPlayer.OnPreparedListener;
  28. import android.net.Uri;
  29. import android.os.Bundle;
  30. import android.support.v7.app.AlertDialog;
  31. import android.widget.MediaController;
  32. import android.widget.VideoView;
  33. import com.owncloud.android.R;
  34. import com.owncloud.android.datamodel.OCFile;
  35. import com.owncloud.android.lib.common.accounts.AccountUtils;
  36. import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
  37. import com.owncloud.android.lib.common.utils.Log_OC;
  38. import com.owncloud.android.media.MediaService;
  39. import com.owncloud.android.ui.activity.FileActivity;
  40. import com.owncloud.android.utils.MimeTypeUtil;
  41. /**
  42. * Activity implementing a basic video player.
  43. *
  44. * Used as an utility to preview video files contained in an ownCloud account.
  45. *
  46. * Currently, it always plays in landscape mode, full screen. When the playback ends,
  47. * the activity is finished.
  48. */
  49. public class PreviewVideoActivity extends FileActivity implements OnCompletionListener, OnPreparedListener, OnErrorListener {
  50. /** Key to receive a flag signaling if the video should be started immediately */
  51. public static final String EXTRA_AUTOPLAY = "AUTOPLAY";
  52. /** Key to receive the position of the playback where the video should be put at start */
  53. public static final String EXTRA_START_POSITION = "START_POSITION";
  54. private static final String TAG = PreviewVideoActivity.class.getSimpleName();
  55. private static final String SCREEN_NAME = "Video Preview";
  56. private int mSavedPlaybackPosition; // in the unit time handled by MediaPlayer.getCurrentPosition()
  57. private boolean mAutoplay; // when 'true', the playback starts immediately with the activity
  58. private VideoView mVideoPlayer; // view to play the file; both performs and show the playback
  59. private MediaController mMediaController; // panel control used by the user to control the playback
  60. /**
  61. * Called when the activity is first created.
  62. *
  63. * Searches for an {@link OCFile} and ownCloud {@link Account} holding it in the starting {@link Intent}.
  64. *
  65. * The {@link Account} is unnecessary if the file is downloaded; else, the {@link Account} is used to
  66. * try to stream the remote file - TODO get the streaming works
  67. *
  68. * {@inheritDoc}
  69. */
  70. @Override
  71. public void onCreate(Bundle savedInstanceState) {
  72. super.onCreate(savedInstanceState);
  73. Log_OC.v(TAG, "onCreate");
  74. setContentView(R.layout.video_layout);
  75. if (savedInstanceState == null) {
  76. Bundle extras = getIntent().getExtras();
  77. mSavedPlaybackPosition = extras.getInt(EXTRA_START_POSITION);
  78. mAutoplay = extras.getBoolean(EXTRA_AUTOPLAY);
  79. } else {
  80. mSavedPlaybackPosition = savedInstanceState.getInt(EXTRA_START_POSITION);
  81. mAutoplay = savedInstanceState.getBoolean(EXTRA_AUTOPLAY);
  82. }
  83. mVideoPlayer = (VideoView) findViewById(R.id.videoPlayer);
  84. // set listeners to get more contol on the playback
  85. mVideoPlayer.setOnPreparedListener(this);
  86. mVideoPlayer.setOnCompletionListener(this);
  87. mVideoPlayer.setOnErrorListener(this);
  88. // keep the screen on while the playback is performed (prevents screen off by battery save)
  89. mVideoPlayer.setKeepScreenOn(true);
  90. }
  91. @Override
  92. protected void onResume() {
  93. super.onResume();
  94. AnalyticsUtils.setCurrentScreenName(this, SCREEN_NAME, TAG);
  95. }
  96. /**
  97. * {@inheritDoc}
  98. */
  99. @Override
  100. public void onSaveInstanceState(Bundle outState) {
  101. super.onSaveInstanceState(outState);
  102. outState.putInt(PreviewVideoActivity.EXTRA_START_POSITION, mVideoPlayer.getCurrentPosition());
  103. outState.putBoolean(PreviewVideoActivity.EXTRA_AUTOPLAY , mVideoPlayer.isPlaying());
  104. }
  105. @Override
  106. public void onBackPressed() {
  107. Log_OC.v(TAG, "onBackPressed");
  108. Intent i = new Intent();
  109. i.putExtra(EXTRA_AUTOPLAY, mVideoPlayer.isPlaying());
  110. i.putExtra(EXTRA_START_POSITION, mVideoPlayer.getCurrentPosition());
  111. setResult(RESULT_OK, i);
  112. super.onBackPressed();
  113. }
  114. /**
  115. * Called when the file is ready to be played.
  116. *
  117. * Just starts the playback.
  118. *
  119. * @param mp {@link MediaPlayer} instance performing the playback.
  120. */
  121. @Override
  122. public void onPrepared(MediaPlayer mp) {
  123. Log_OC.v(TAG, "onPrepare");
  124. mVideoPlayer.seekTo(mSavedPlaybackPosition);
  125. if (mAutoplay) {
  126. mVideoPlayer.start();
  127. }
  128. mMediaController.show(5000);
  129. }
  130. /**
  131. * Called when the file is finished playing.
  132. *
  133. * Rewinds the video
  134. *
  135. * @param mp {@link MediaPlayer} instance performing the playback.
  136. */
  137. @Override
  138. public void onCompletion(MediaPlayer mp) {
  139. mVideoPlayer.seekTo(0);
  140. }
  141. /**
  142. * Called when an error in playback occurs.
  143. *
  144. * @param mp {@link MediaPlayer} instance performing the playback.
  145. * @param what Type of error
  146. * @param extra Extra code specific to the error
  147. */
  148. @Override
  149. public boolean onError(MediaPlayer mp, int what, int extra) {
  150. Log_OC.e(TAG, "Error in video playback, what = " + what + ", extra = " + extra);
  151. if (mMediaController != null) {
  152. mMediaController.hide();
  153. }
  154. if (mVideoPlayer.getWindowToken() != null) {
  155. String message = MediaService.getMessageForMediaError(this, what, extra);
  156. new AlertDialog.Builder(this)
  157. .setMessage(message)
  158. .setPositiveButton(android.R.string.VideoView_error_button,
  159. new DialogInterface.OnClickListener() {
  160. public void onClick(DialogInterface dialog, int whichButton) {
  161. PreviewVideoActivity.this.onCompletion(null);
  162. }
  163. })
  164. .setCancelable(false)
  165. .show();
  166. }
  167. return true;
  168. }
  169. @Override
  170. protected void onAccountSet(boolean stateWasRecovered) {
  171. super.onAccountSet(stateWasRecovered);
  172. if (getAccount() != null) {
  173. OCFile file = getFile();
  174. /// Validate handled file (first image to preview)
  175. if (file == null) {
  176. throw new IllegalStateException("Instanced with a NULL OCFile");
  177. }
  178. if (!MimeTypeUtil.isVideo(file)) {
  179. throw new IllegalArgumentException("Non-video file passed as argument");
  180. }
  181. file = getStorageManager().getFileById(file.getFileId());
  182. if (file != null) {
  183. if (file.isDown()) {
  184. mVideoPlayer.setVideoURI(file.getStorageUri());
  185. } else {
  186. // not working yet
  187. String url;
  188. try {
  189. url = AccountUtils.constructFullURLForAccount(this, getAccount()) + file.getRemotePath();
  190. mVideoPlayer.setVideoURI(Uri.parse(url));
  191. } catch (AccountNotFoundException e) {
  192. onError(null, MediaService.OC_MEDIA_ERROR, R.string.media_err_no_account);
  193. }
  194. }
  195. // create and prepare control panel for the user
  196. mMediaController = new MediaController(this);
  197. mMediaController.setMediaPlayer(mVideoPlayer);
  198. mMediaController.setAnchorView(mVideoPlayer);
  199. mVideoPlayer.setMediaController(mMediaController);
  200. } else {
  201. finish();
  202. }
  203. } else {
  204. finish();
  205. }
  206. }
  207. }