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