/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.gallery3d.app; import android.app.ActionBar; import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; import android.widget.VideoView; import com.android.gallery3d.R; public class TrimVideo extends Activity implements MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener, ControllerOverlay.Listener { private VideoView mVideoView; private TrimControllerOverlay mController; private Context mContext; private Uri mUri; private final Handler mHandler = new Handler(); public static final String TRIM_ACTION = "com.android.camera.action.TRIM"; public ProgressDialog mProgress; private int mTrimStartTime = 0; private int mTrimEndTime = 0; private int mVideoPosition = 0; public static final String KEY_TRIM_START = "trim_start"; public static final String KEY_TRIM_END = "trim_end"; public static final String KEY_VIDEO_POSITION = "video_pos"; private boolean mHasPaused = false; @Override public void onCreate(Bundle savedInstanceState) { mContext = getApplicationContext(); super.onCreate(savedInstanceState); ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(true); Intent intent = getIntent(); mUri = intent.getData(); setContentView(R.layout.trim_view); View rootView = findViewById(R.id.trim_view_root); mVideoView = (VideoView) rootView.findViewById(R.id.surface_view); mController = new TrimControllerOverlay(mContext); ((ViewGroup)rootView).addView(mController.getView()); mController.setListener(this); mController.setCanReplay(true); mVideoView.setOnErrorListener(this); mVideoView.setOnCompletionListener(this); mVideoView.setVideoURI(mUri); playVideo(); } @Override public void onResume() { super.onResume(); if (mHasPaused) { mVideoView.seekTo(mVideoPosition); mVideoView.resume(); mHasPaused = false; } mHandler.post(mProgressChecker); } @Override public void onPause() { mHasPaused = true; mHandler.removeCallbacksAndMessages(null); mVideoPosition = mVideoView.getCurrentPosition(); mVideoView.suspend(); super.onPause(); } @Override public void onDestroy() { mVideoView.stopPlayback(); super.onDestroy(); } private final Runnable mProgressChecker = new Runnable() { @Override public void run() { int pos = setProgress(); mHandler.postDelayed(mProgressChecker, 200 - (pos % 200)); } }; @Override public void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putInt(KEY_TRIM_START, mTrimStartTime); savedInstanceState.putInt(KEY_TRIM_END, mTrimEndTime); savedInstanceState.putInt(KEY_VIDEO_POSITION, mVideoPosition); super.onSaveInstanceState(savedInstanceState); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mTrimStartTime = savedInstanceState.getInt(KEY_TRIM_START, 0); mTrimEndTime = savedInstanceState.getInt(KEY_TRIM_END, 0); mVideoPosition = savedInstanceState.getInt(KEY_VIDEO_POSITION, 0); } // This updates the time bar display (if necessary). It is called by // mProgressChecker and also from places where the time bar needs // to be updated immediately. private int setProgress() { mVideoPosition = mVideoView.getCurrentPosition(); // If the video position is smaller than the starting point of trimming, // correct it. if (mVideoPosition < mTrimStartTime) { mVideoView.seekTo(mTrimStartTime); mVideoPosition = mTrimStartTime; } // If the position is bigger than the end point of trimming, show the // replay button and pause. if (mVideoPosition >= mTrimEndTime && mTrimEndTime > 0) { if (mVideoPosition > mTrimEndTime) { mVideoView.seekTo(mTrimEndTime); mVideoPosition = mTrimEndTime; } mController.showEnded(); mVideoView.pause(); } int duration = mVideoView.getDuration(); if (duration > 0 && mTrimEndTime == 0) { mTrimEndTime = duration; } mController.setTimes(mVideoPosition, duration, mTrimStartTime, mTrimEndTime); return mVideoPosition; } private void playVideo() { mVideoView.start(); mController.showPlaying(); setProgress(); } private void pauseVideo() { mVideoView.pause(); mController.showPaused(); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.trim, menu); return true; }; @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { finish(); return true; } else if (id == R.id.action_trim_video) { // TODO: Add the new MediaMuxer API to support the trimming. Toast.makeText(getApplicationContext(), "Trimming will be implemented soon!", Toast.LENGTH_SHORT).show(); return true; } return false; } @Override public void onPlayPause() { if (mVideoView.isPlaying()) { pauseVideo(); } else { playVideo(); } } @Override public void onSeekStart() { pauseVideo(); } @Override public void onSeekMove(int time) { mVideoView.seekTo(time); } @Override public void onSeekEnd(int time, int start, int end) { mVideoView.seekTo(time); mTrimStartTime = start; mTrimEndTime = end; setProgress(); } @Override public void onShown() { } @Override public void onHidden() { } @Override public void onReplay() { mVideoView.seekTo(mTrimStartTime); playVideo(); } @Override public void onCompletion(MediaPlayer mp) { mController.showEnded(); } @Override public boolean onError(MediaPlayer mp, int what, int extra) { return false; } }