13f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu/* 23f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * Copyright (C) 2012 The Android Open Source Project 33f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * 43f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 53f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * you may not use this file except in compliance with the License. 63f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * You may obtain a copy of the License at 73f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * 83f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * http://www.apache.org/licenses/LICENSE-2.0 93f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * 103f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * Unless required by applicable law or agreed to in writing, software 113f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * distributed under the License is distributed on an "AS IS" BASIS, 123f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * See the License for the specific language governing permissions and 143f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu * limitations under the License. 153f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu */ 163f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 173f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhupackage com.android.gallery3d.app; 183f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 192abaaf7caa9a83ba1ea759868aabde7f21387184John Reckimport android.app.ActionBar; 202abaaf7caa9a83ba1ea759868aabde7f21387184John Reckimport android.app.Activity; 213f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.app.ProgressDialog; 223f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.content.Context; 233f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.content.Intent; 243f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.media.MediaPlayer; 253f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.net.Uri; 263f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.os.Bundle; 273f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.os.Handler; 282833355c86cff90163457779adb2bc78a6ca0faaTeng-Hui Zhuimport android.provider.MediaStore; 293f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.view.View; 303f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.view.ViewGroup; 31028ecd4e3bbd68c3b5b2fb91d3e7a666bc151765Teng-Hui Zhuimport android.view.Window; 32028ecd4e3bbd68c3b5b2fb91d3e7a666bc151765Teng-Hui Zhuimport android.widget.TextView; 333f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.widget.Toast; 343f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport android.widget.VideoView; 353f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 363f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhuimport com.android.gallery3d.R; 37648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhuimport com.android.gallery3d.util.SaveVideoFileInfo; 38648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhuimport com.android.gallery3d.util.SaveVideoFileUtils; 393f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 4015ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhuimport java.io.File; 4115ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhuimport java.io.IOException; 423f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 432abaaf7caa9a83ba1ea759868aabde7f21387184John Reckpublic class TrimVideo extends Activity implements 443f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu MediaPlayer.OnErrorListener, 453f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu MediaPlayer.OnCompletionListener, 463f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu ControllerOverlay.Listener { 473f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 483f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private VideoView mVideoView; 49bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu private TextView mSaveVideoTextView; 503f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private TrimControllerOverlay mController; 513f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private Context mContext; 523f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private Uri mUri; 533f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private final Handler mHandler = new Handler(); 543f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public static final String TRIM_ACTION = "com.android.camera.action.TRIM"; 553f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 563f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public ProgressDialog mProgress; 573f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 583f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private int mTrimStartTime = 0; 593f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private int mTrimEndTime = 0; 603f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private int mVideoPosition = 0; 613f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public static final String KEY_TRIM_START = "trim_start"; 623f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public static final String KEY_TRIM_END = "trim_end"; 633f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public static final String KEY_VIDEO_POSITION = "video_pos"; 643f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private boolean mHasPaused = false; 653f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 6615ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu private String mSrcVideoPath = null; 6715ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu private static final String TIME_STAMP_NAME = "'TRIM'_yyyyMMdd_HHmmss"; 68648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhu private SaveVideoFileInfo mDstFileInfo = null; 6915ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu 703f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 713f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onCreate(Bundle savedInstanceState) { 723f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mContext = getApplicationContext(); 733f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu super.onCreate(savedInstanceState); 743f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 755e92668f42b5f29a0e55653b0bbf2df342723a6dTeng-Hui Zhu requestWindowFeature(Window.FEATURE_ACTION_BAR); 765e92668f42b5f29a0e55653b0bbf2df342723a6dTeng-Hui Zhu requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); 775e92668f42b5f29a0e55653b0bbf2df342723a6dTeng-Hui Zhu 782abaaf7caa9a83ba1ea759868aabde7f21387184John Reck ActionBar actionBar = getActionBar(); 79028ecd4e3bbd68c3b5b2fb91d3e7a666bc151765Teng-Hui Zhu int displayOptions = ActionBar.DISPLAY_SHOW_HOME; 80028ecd4e3bbd68c3b5b2fb91d3e7a666bc151765Teng-Hui Zhu actionBar.setDisplayOptions(0, displayOptions); 81028ecd4e3bbd68c3b5b2fb91d3e7a666bc151765Teng-Hui Zhu displayOptions = ActionBar.DISPLAY_SHOW_CUSTOM; 825e92668f42b5f29a0e55653b0bbf2df342723a6dTeng-Hui Zhu actionBar.setDisplayOptions(displayOptions, displayOptions); 83028ecd4e3bbd68c3b5b2fb91d3e7a666bc151765Teng-Hui Zhu actionBar.setCustomView(R.layout.trim_menu); 84028ecd4e3bbd68c3b5b2fb91d3e7a666bc151765Teng-Hui Zhu 85bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu mSaveVideoTextView = (TextView) findViewById(R.id.start_trim); 864450e439731d12638525c86a36cd26ac97bdc735Teng-Hui Zhu mSaveVideoTextView.setOnClickListener(new View.OnClickListener() { 87028ecd4e3bbd68c3b5b2fb91d3e7a666bc151765Teng-Hui Zhu @Override 884450e439731d12638525c86a36cd26ac97bdc735Teng-Hui Zhu public void onClick(View arg0) { 894450e439731d12638525c86a36cd26ac97bdc735Teng-Hui Zhu trimVideo(); 90028ecd4e3bbd68c3b5b2fb91d3e7a666bc151765Teng-Hui Zhu } 91028ecd4e3bbd68c3b5b2fb91d3e7a666bc151765Teng-Hui Zhu }); 92bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu mSaveVideoTextView.setEnabled(false); 933f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 943f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu Intent intent = getIntent(); 953f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mUri = intent.getData(); 9615ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu mSrcVideoPath = intent.getStringExtra(PhotoPage.KEY_MEDIA_ITEM_PATH); 973f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu setContentView(R.layout.trim_view); 983f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu View rootView = findViewById(R.id.trim_view_root); 993f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1003f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView = (VideoView) rootView.findViewById(R.id.surface_view); 1013f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1023f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mController = new TrimControllerOverlay(mContext); 10315ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu ((ViewGroup) rootView).addView(mController.getView()); 1043f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mController.setListener(this); 1053f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mController.setCanReplay(true); 1063f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1073f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.setOnErrorListener(this); 1083f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.setOnCompletionListener(this); 1093f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.setVideoURI(mUri); 1103f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1113f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu playVideo(); 1123f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1133f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1143f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1153f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onResume() { 1163f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu super.onResume(); 1173f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mHasPaused) { 1183f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.seekTo(mVideoPosition); 1193f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.resume(); 1203f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mHasPaused = false; 1213f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1223f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mHandler.post(mProgressChecker); 1233f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1243f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1253f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1263f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onPause() { 1273f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mHasPaused = true; 1283f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mHandler.removeCallbacksAndMessages(null); 1293f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoPosition = mVideoView.getCurrentPosition(); 1303f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.suspend(); 1313f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu super.onPause(); 1323f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1333f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1343f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 13515ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu public void onStop() { 13615ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu if (mProgress != null) { 13715ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu mProgress.dismiss(); 13815ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu mProgress = null; 13915ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu } 14015ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu super.onStop(); 14115ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu } 14215ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu 14315ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu @Override 1443f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onDestroy() { 1453f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.stopPlayback(); 1463f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu super.onDestroy(); 1473f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1483f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1493f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private final Runnable mProgressChecker = new Runnable() { 1503f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1513f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void run() { 1523f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int pos = setProgress(); 1533f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mHandler.postDelayed(mProgressChecker, 200 - (pos % 200)); 1543f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1553f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu }; 1563f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1573f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1583f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onSaveInstanceState(Bundle savedInstanceState) { 1593f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu savedInstanceState.putInt(KEY_TRIM_START, mTrimStartTime); 1603f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu savedInstanceState.putInt(KEY_TRIM_END, mTrimEndTime); 1613f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu savedInstanceState.putInt(KEY_VIDEO_POSITION, mVideoPosition); 1623f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu super.onSaveInstanceState(savedInstanceState); 1633f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1643f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1653f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 1663f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onRestoreInstanceState(Bundle savedInstanceState) { 1673f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu super.onRestoreInstanceState(savedInstanceState); 1683f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTrimStartTime = savedInstanceState.getInt(KEY_TRIM_START, 0); 1693f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTrimEndTime = savedInstanceState.getInt(KEY_TRIM_END, 0); 1703f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoPosition = savedInstanceState.getInt(KEY_VIDEO_POSITION, 0); 1713f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1723f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1733f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // This updates the time bar display (if necessary). It is called by 1743f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // mProgressChecker and also from places where the time bar needs 1753f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // to be updated immediately. 1763f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private int setProgress() { 1773f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoPosition = mVideoView.getCurrentPosition(); 1783f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // If the video position is smaller than the starting point of trimming, 1793f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // correct it. 1803f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mVideoPosition < mTrimStartTime) { 1813f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.seekTo(mTrimStartTime); 1823f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoPosition = mTrimStartTime; 1833f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1843f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // If the position is bigger than the end point of trimming, show the 1853f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu // replay button and pause. 1863f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mVideoPosition >= mTrimEndTime && mTrimEndTime > 0) { 1873f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mVideoPosition > mTrimEndTime) { 1883f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.seekTo(mTrimEndTime); 1893f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoPosition = mTrimEndTime; 1903f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1913f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mController.showEnded(); 1923f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.pause(); 1933f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1943f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 1953f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu int duration = mVideoView.getDuration(); 1963f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (duration > 0 && mTrimEndTime == 0) { 1973f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTrimEndTime = duration; 1983f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 1993f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mController.setTimes(mVideoPosition, duration, mTrimStartTime, mTrimEndTime); 20070df03bea1eb05ac5adf9c5425e5e4a0cc6aed16ztenghui // Enable save if there's modifications 20170df03bea1eb05ac5adf9c5425e5e4a0cc6aed16ztenghui mSaveVideoTextView.setEnabled(isModified()); 2023f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return mVideoPosition; 2033f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2043f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2053f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private void playVideo() { 2063f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.start(); 2073f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mController.showPlaying(); 2083f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu setProgress(); 2093f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2103f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2113f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu private void pauseVideo() { 2123f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.pause(); 2133f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mController.showPaused(); 2143f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2153f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 21615ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu 217bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu private boolean isModified() { 218d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu int delta = mTrimEndTime - mTrimStartTime; 219bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu 220d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu // Considering that we only trim at sync frame, we don't want to trim 221d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu // when the time interval is too short or too close to the origin. 222bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu if (delta < 100 || Math.abs(mVideoView.getDuration() - delta) < 100) { 223bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu return false; 224bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu } else { 225bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu return true; 226d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu } 227bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu } 228648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhu 229bf1677a434760fcb7389a30c18e05cc3e7926d40Doris Liu private void trimVideo() { 23015ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu 231648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhu mDstFileInfo = SaveVideoFileUtils.getDstMp4FileInfo(TIME_STAMP_NAME, 232648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhu getContentResolver(), mUri, getString(R.string.folder_download)); 233648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhu final File mSrcFile = new File(mSrcVideoPath); 23415ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu 23515ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu showProgressDialog(); 23615ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu 23715ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu new Thread(new Runnable() { 23815ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu @Override 23915ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu public void run() { 24015ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu try { 241648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhu VideoUtils.startTrim(mSrcFile, mDstFileInfo.mFile, 2428b9de91b3c01664b24deda202acb5db8594db503ztenghui mTrimStartTime, mTrimEndTime); 243d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu // Update the database for adding a new video file. 244648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhu SaveVideoFileUtils.insertContent(mDstFileInfo, 245648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhu getContentResolver(), mUri); 24615ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu } catch (IOException e) { 24715ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu e.printStackTrace(); 24815ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu } 24915ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu // After trimming is done, trigger the UI changed. 25015ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu mHandler.post(new Runnable() { 25115ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu @Override 25215ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu public void run() { 253d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu Toast.makeText(getApplicationContext(), 254648b339c74da2b863304ffc61c8528cc74c2afb3Teng-Hui Zhu getString(R.string.save_into, mDstFileInfo.mFolderName), 255d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu Toast.LENGTH_SHORT) 256d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu .show(); 25715ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu // TODO: change trimming into a service to avoid 25815ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu // this progressDialog and add notification properly. 25915ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu if (mProgress != null) { 26015ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu mProgress.dismiss(); 26115ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu mProgress = null; 262d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu // Show the result only when the activity not stopped. 263d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu Intent intent = new Intent(android.content.Intent.ACTION_VIEW); 264b5f374c30d06dc0409891f85a4bd5e1e3ddf8700Teng-Hui Zhu intent.setDataAndType(Uri.fromFile(mDstFileInfo.mFile), "video/*"); 2652833355c86cff90163457779adb2bc78a6ca0faaTeng-Hui Zhu intent.putExtra(MediaStore.EXTRA_FINISH_ON_COMPLETION, false); 266d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu startActivity(intent); 2672833355c86cff90163457779adb2bc78a6ca0faaTeng-Hui Zhu finish(); 26815ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu } 26915ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu } 27015ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu }); 27115ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu } 27215ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu }).start(); 27315ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu } 27415ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu 27515ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu private void showProgressDialog() { 27615ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu // create a background thread to trim the video. 27715ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu // and show the progress. 27815ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu mProgress = new ProgressDialog(this); 279d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu mProgress.setTitle(getString(R.string.trimming)); 280d44b0d8348a9f91259ecbd59ec48c9df9f058141Teng-Hui Zhu mProgress.setMessage(getString(R.string.please_wait)); 28115ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu // TODO: make this cancelable. 28215ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu mProgress.setCancelable(false); 28315ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu mProgress.setCanceledOnTouchOutside(false); 28415ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu mProgress.show(); 28515ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu } 28615ff1b1ca52bea348b8a490b5b5abe53fa43eaf2Teng-Hui Zhu 2873f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 2883f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onPlayPause() { 2893f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu if (mVideoView.isPlaying()) { 2903f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu pauseVideo(); 2913f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } else { 2923f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu playVideo(); 2933f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2943f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 2953f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 2963f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 2973f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onSeekStart() { 2983f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu pauseVideo(); 2993f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3003f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3013f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 3023f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onSeekMove(int time) { 3033f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.seekTo(time); 3043f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3053f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3063f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 3073f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onSeekEnd(int time, int start, int end) { 3083f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.seekTo(time); 3093f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTrimStartTime = start; 3103f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mTrimEndTime = end; 3113f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu setProgress(); 3123f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3133f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3143f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 3153f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onShown() { 3163f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3173f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3183f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 3193f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onHidden() { 3203f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3213f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3223f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 3233f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onReplay() { 3243f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mVideoView.seekTo(mTrimStartTime); 3253f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu playVideo(); 3263f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3273f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3283f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 3293f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public void onCompletion(MediaPlayer mp) { 3303f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu mController.showEnded(); 3313f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3323f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu 3333f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu @Override 3343f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu public boolean onError(MediaPlayer mp, int what, int extra) { 3353f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu return false; 3363f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu } 3373f1f1baf3a674927e25cd5cd885fb372796bd3a0Teng-Hui Zhu} 338