TrimVideo.java revision 3f1f1baf3a674927e25cd5cd885fb372796bd3a0
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.gallery3d.app;
18
19import android.app.ActionBar;
20import android.app.Activity;
21import android.app.ProgressDialog;
22import android.content.Context;
23import android.content.Intent;
24import android.media.MediaPlayer;
25import android.net.Uri;
26import android.os.Bundle;
27import android.os.Handler;
28import android.view.Menu;
29import android.view.MenuInflater;
30import android.view.MenuItem;
31import android.view.View;
32import android.view.ViewGroup;
33import android.widget.Toast;
34import android.widget.VideoView;
35
36import com.android.gallery3d.R;
37
38
39public class TrimVideo extends Activity implements
40        MediaPlayer.OnErrorListener,
41        MediaPlayer.OnCompletionListener,
42        ControllerOverlay.Listener {
43
44    private VideoView mVideoView;
45    private TrimControllerOverlay mController;
46    private Context mContext;
47    private Uri mUri;
48    private final Handler mHandler = new Handler();
49    public static final String TRIM_ACTION = "com.android.camera.action.TRIM";
50
51    public ProgressDialog mProgress;
52
53    private int mTrimStartTime = 0;
54    private int mTrimEndTime = 0;
55    private int mVideoPosition = 0;
56    public static final String KEY_TRIM_START = "trim_start";
57    public static final String KEY_TRIM_END = "trim_end";
58    public static final String KEY_VIDEO_POSITION = "video_pos";
59    private boolean mHasPaused = false;
60
61    @Override
62    public void onCreate(Bundle savedInstanceState) {
63        mContext = getApplicationContext();
64        super.onCreate(savedInstanceState);
65
66        ActionBar actionBar = getActionBar();
67        actionBar.setDisplayHomeAsUpEnabled(true);
68
69        Intent intent = getIntent();
70        mUri = intent.getData();
71
72        setContentView(R.layout.trim_view);
73        View rootView = findViewById(R.id.trim_view_root);
74
75        mVideoView = (VideoView) rootView.findViewById(R.id.surface_view);
76
77        mController = new TrimControllerOverlay(mContext);
78        ((ViewGroup)rootView).addView(mController.getView());
79        mController.setListener(this);
80        mController.setCanReplay(true);
81
82        mVideoView.setOnErrorListener(this);
83        mVideoView.setOnCompletionListener(this);
84        mVideoView.setVideoURI(mUri);
85
86        playVideo();
87    }
88
89    @Override
90    public void onResume() {
91        super.onResume();
92        if (mHasPaused) {
93            mVideoView.seekTo(mVideoPosition);
94            mVideoView.resume();
95            mHasPaused = false;
96        }
97        mHandler.post(mProgressChecker);
98    }
99
100    @Override
101    public void onPause() {
102        mHasPaused = true;
103        mHandler.removeCallbacksAndMessages(null);
104        mVideoPosition = mVideoView.getCurrentPosition();
105        mVideoView.suspend();
106        super.onPause();
107    }
108
109    @Override
110    public void onDestroy() {
111        mVideoView.stopPlayback();
112        super.onDestroy();
113    }
114
115    private final Runnable mProgressChecker = new Runnable() {
116        @Override
117        public void run() {
118            int pos = setProgress();
119            mHandler.postDelayed(mProgressChecker, 200 - (pos % 200));
120        }
121    };
122
123    @Override
124    public void onSaveInstanceState(Bundle savedInstanceState) {
125        savedInstanceState.putInt(KEY_TRIM_START, mTrimStartTime);
126        savedInstanceState.putInt(KEY_TRIM_END, mTrimEndTime);
127        savedInstanceState.putInt(KEY_VIDEO_POSITION, mVideoPosition);
128        super.onSaveInstanceState(savedInstanceState);
129    }
130
131    @Override
132    public void onRestoreInstanceState(Bundle savedInstanceState) {
133        super.onRestoreInstanceState(savedInstanceState);
134        mTrimStartTime = savedInstanceState.getInt(KEY_TRIM_START, 0);
135        mTrimEndTime = savedInstanceState.getInt(KEY_TRIM_END, 0);
136        mVideoPosition = savedInstanceState.getInt(KEY_VIDEO_POSITION, 0);
137    }
138
139    // This updates the time bar display (if necessary). It is called by
140    // mProgressChecker and also from places where the time bar needs
141    // to be updated immediately.
142    private int setProgress() {
143        mVideoPosition = mVideoView.getCurrentPosition();
144        // If the video position is smaller than the starting point of trimming,
145        // correct it.
146        if (mVideoPosition < mTrimStartTime) {
147            mVideoView.seekTo(mTrimStartTime);
148            mVideoPosition = mTrimStartTime;
149        }
150        // If the position is bigger than the end point of trimming, show the
151        // replay button and pause.
152        if (mVideoPosition >= mTrimEndTime && mTrimEndTime > 0) {
153            if (mVideoPosition > mTrimEndTime) {
154                mVideoView.seekTo(mTrimEndTime);
155                mVideoPosition = mTrimEndTime;
156            }
157            mController.showEnded();
158            mVideoView.pause();
159        }
160
161        int duration = mVideoView.getDuration();
162        if (duration > 0 && mTrimEndTime == 0) {
163            mTrimEndTime = duration;
164        }
165        mController.setTimes(mVideoPosition, duration, mTrimStartTime, mTrimEndTime);
166        return mVideoPosition;
167    }
168
169    private void playVideo() {
170        mVideoView.start();
171        mController.showPlaying();
172        setProgress();
173    }
174
175    private void pauseVideo() {
176        mVideoView.pause();
177        mController.showPaused();
178    }
179
180    @Override
181    public boolean onCreateOptionsMenu(Menu menu) {
182        super.onCreateOptionsMenu(menu);
183        MenuInflater inflater = getMenuInflater();
184        inflater.inflate(R.menu.trim, menu);
185        return true;
186    };
187
188    @Override
189    public boolean onOptionsItemSelected(MenuItem item) {
190        int id = item.getItemId();
191        if (id == android.R.id.home) {
192            finish();
193            return true;
194        } else if (id == R.id.action_trim_video) {
195            // TODO: Add the new MediaMuxer API to support the trimming.
196            Toast.makeText(getApplicationContext(),
197                    "Trimming will be implemented soon!", Toast.LENGTH_SHORT).show();
198            return true;
199        }
200        return false;
201    }
202
203    @Override
204    public void onPlayPause() {
205        if (mVideoView.isPlaying()) {
206            pauseVideo();
207        } else {
208            playVideo();
209        }
210    }
211
212    @Override
213    public void onSeekStart() {
214        pauseVideo();
215    }
216
217    @Override
218    public void onSeekMove(int time) {
219        mVideoView.seekTo(time);
220    }
221
222    @Override
223    public void onSeekEnd(int time, int start, int end) {
224        mVideoView.seekTo(time);
225        mTrimStartTime = start;
226        mTrimEndTime = end;
227        setProgress();
228    }
229
230    @Override
231    public void onShown() {
232    }
233
234
235    @Override
236    public void onHidden() {
237    }
238
239    @Override
240    public void onReplay() {
241        mVideoView.seekTo(mTrimStartTime);
242        playVideo();
243    }
244
245    @Override
246    public void onCompletion(MediaPlayer mp) {
247        mController.showEnded();
248    }
249
250    @Override
251    public boolean onError(MediaPlayer mp, int what, int extra) {
252        return false;
253    }
254}
255