VideoView 和 SurfaceView 实例

来源:互联网 发布:python 字符串倒叙截取 编辑:程序博客网 时间:2024/05/08 19:02

VideoView内部封装好了Mediaplayer.Android框架提供了VideoView类来封装MediaPalyer,这个VideoView类非常好用。Android自带的程序Gallery也是用VideoView实现的。相比之下,我们使用更方便 ,实现MediaPlayer.OnCompletionListener接口,将会在Video播完的时候得到通知,本例只是简单的结束程序如下:

import android.app.Activity;import android.content.Context;import android.content.Intent;import android.content.pm.ActivityInfo;import android.content.res.Configuration;import android.media.AudioManager;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.text.TextUtils;import android.view.Display;import android.view.GestureDetector.SimpleOnGestureListener;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.ImageView;public class VideoPlayerActivity extends Activity implements OnCompletionListener {private String mPath;private String mTitle;private VideoView mVideoView;private View mVolumeBrightnessLayout;private ImageView mOperationBg;private ImageView mOperationPercent;private AudioManager mAudioManager;/** 最大声音 */private int mMaxVolume;/** 当前声音 */private int mVolume = -1;/** 当前亮度 */private float mBrightness = -1f;/** 当前缩放模式 */private int mLayout = VideoView.VIDEO_LAYOUT_ZOOM;private GestureDetector mGestureDetector;private MediaController mMediaController;@Overridepublic void onCreate(Bundle icicle) {super.onCreate(icicle);Intent intent = getIntent();mPath = intent.getStringExtra("path");mTitle = intent.getStringExtra("title");if (TextUtils.isEmpty(mPath))mPath = Environment.getExternalStorageDirectory() + "/video/你太猖狂.flv";else if (intent.getData() != null)mPath = intent.getData().toString();setContentView(R.layout.videoview);mVideoView = (VideoView) findViewById(R.id.surface_view);mVolumeBrightnessLayout = findViewById(R.id.operation_volume_brightness);mOperationBg = (ImageView) findViewById(R.id.operation_bg);mOperationPercent = (ImageView) findViewById(R.id.operation_percent);mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);if (mPath.startsWith("http:"))mVideoView.setVideoURI(Uri.parse(mPath));elsemVideoView.setVideoPath(mPath);//mVideoView.setOnCompletionListener(this);mMediaController = new MediaController(this);//设置显示名称mMediaController.setFileName(mTitle);mVideoView.setMediaController(mMediaController);mVideoView.requestFocus();mGestureDetector = new GestureDetector(this, new MyGestureListener());setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);}@Overrideprotected void onPause() {super.onPause();if (mVideoView != null)mVideoView.pause();}@Overrideprotected void onResume() {super.onResume();if (mVideoView != null)mVideoView.resume();}@Overrideprotected void onDestroy() {super.onDestroy();if (mVideoView != null)mVideoView.stopPlayback();}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (mGestureDetector.onTouchEvent(event))return true;// 处理手势结束switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_UP:endGesture();break;}return super.onTouchEvent(event);}/** 手势结束 */private void endGesture() {mVolume = -1;mBrightness = -1f;// 隐藏mDismissHandler.removeMessages(0);mDismissHandler.sendEmptyMessageDelayed(0, 500);}private class MyGestureListener extends SimpleOnGestureListener {/** 双击 */@Overridepublic boolean onDoubleTap(MotionEvent e) {if (mLayout == VideoView.VIDEO_LAYOUT_ZOOM)mLayout = VideoView.VIDEO_LAYOUT_ORIGIN;elsemLayout++;if (mVideoView != null)mVideoView.setVideoLayout(mLayout, 0);return true;}/** 滑动 */@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {float mOldX = e1.getX(), mOldY = e1.getY();int y = (int) e2.getRawY();Display disp = getWindowManager().getDefaultDisplay();int windowWidth = disp.getWidth();int windowHeight = disp.getHeight();if (mOldX > windowWidth * 4.0 / 5)// 右边滑动onVolumeSlide((mOldY - y) / windowHeight);else if (mOldX < windowWidth / 5.0)// 左边滑动onBrightnessSlide((mOldY - y) / windowHeight);return super.onScroll(e1, e2, distanceX, distanceY);}}/** 定时隐藏 */private Handler mDismissHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {mVolumeBrightnessLayout.setVisibility(View.GONE);}};/** * 滑动改变声音大小 *  * @param percent */private void onVolumeSlide(float percent) {if (mVolume == -1) {mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);if (mVolume < 0)mVolume = 0;// 显示mOperationBg.setImageResource(R.drawable.video_volumn_bg);mVolumeBrightnessLayout.setVisibility(View.VISIBLE);}int index = (int) (percent * mMaxVolume) + mVolume;if (index > mMaxVolume)index = mMaxVolume;else if (index < 0)index = 0;// 变更声音mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);// 变更进度条ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();lp.width = findViewById(R.id.operation_full).getLayoutParams().width * index / mMaxVolume;mOperationPercent.setLayoutParams(lp);}/** * 滑动改变亮度 *  * @param percent */private void onBrightnessSlide(float percent) {if (mBrightness < 0) {mBrightness = getWindow().getAttributes().screenBrightness;if (mBrightness <= 0.00f)mBrightness = 0.50f;if (mBrightness < 0.01f)mBrightness = 0.01f;// 显示mOperationBg.setImageResource(R.drawable.video_brightness_bg);mVolumeBrightnessLayout.setVisibility(View.VISIBLE);}WindowManager.LayoutParams lpa = getWindow().getAttributes();lpa.screenBrightness = mBrightness + percent;if (lpa.screenBrightness > 1.0f)lpa.screenBrightness = 1.0f;else if (lpa.screenBrightness < 0.01f)lpa.screenBrightness = 0.01f;getWindow().setAttributes(lpa);ViewGroup.LayoutParams lp = mOperationPercent.getLayoutParams();lp.width = (int) (findViewById(R.id.operation_full).getLayoutParams().width * lpa.screenBrightness);mOperationPercent.setLayoutParams(lp);}@Overridepublic void onConfigurationChanged(Configuration newConfig) {if (mVideoView != null)mVideoView.setVideoLayout(mLayout, 0);super.onConfigurationChanged(newConfig);}@Overridepublic void onCompletion(MediaPlayer player) {finish();}}

videoView 是android 系统提供的一个媒体播放显示和控制的控件。其结构层次如下:

  原型:VideoView extends SurfaceView implements MediaController.MediaPlayerControl

  类结构:

      java.lang.Object
        ↳ android.view.View
          ↳ android.view.SurfaceView
            ↳ android.widget.VideoView

  通过VideoView 的原型可知:如果构建更为复杂和有特色个性的视频View,需要继承SurfaceView 和实现MediaPlayerControl接口。其中SurfaceView 为显示提供支持,MediaPlayerControl则为媒体控制提供了支持。


核心播放类:
import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;public class PlayerActivity extends Activity implements OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {private static final String TAG = "MediaPlayerDemo";private int mVideoWidth;private int mVideoHeight;private MediaPlayer mMediaPlayer;private SurfaceView mPreview;private SurfaceHolder holder;private String path = Environment.getExternalStorageDirectory() + "/Moon.mp4";private boolean mIsVideoSizeKnown = false;private boolean mIsVideoReadyToBePlayed = false;@Overridepublic void onCreate(Bundle icicle) {super.onCreate(icicle);setContentView(R.layout.mediaplayer);mPreview = (SurfaceView) findViewById(R.id.surface);holder = mPreview.getHolder();holder.addCallback(this);}private void playVideo() {doCleanUp();try {mMediaPlayer = new MediaPlayer(this);mMediaPlayer.setDataSource(path);mMediaPlayer.setDisplay(holder);mMediaPlayer.prepareAsync();mMediaPlayer.setScreenOnWhilePlaying(true);mMediaPlayer.setOnBufferingUpdateListener(this);mMediaPlayer.setOnCompletionListener(this);mMediaPlayer.setOnPreparedListener(this);mMediaPlayer.setOnVideoSizeChangedListener(this);} catch (Exception e) {Log.e(TAG, "error: " + e.getMessage(), e);}}@Override  public void onBufferingUpdate(MediaPlayer arg0, int percent) {Log.d(TAG, "onBufferingUpdate percent:" + percent);}@Override  public void onCompletion(MediaPlayer arg0) {Log.d(TAG, "onCompletion called");mMediaPlayer.release();}@Override  public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {Log.v(TAG, "onVideoSizeChanged called");if (width == 0 || height == 0) {Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");return;}mIsVideoSizeKnown = true;mVideoWidth = width;mVideoHeight = height;if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {startVideoPlayback();}}@Override  public void onPrepared(MediaPlayer mediaplayer) {Log.d(TAG, "onPrepared called");mIsVideoReadyToBePlayed = true;if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {startVideoPlayback();}}@Override  public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {Log.d(TAG, "surfaceChanged called" + i + "  " + j + "   " + k);}@Override  public void surfaceDestroyed(SurfaceHolder surfaceholder) {Log.d(TAG, "surfaceDestroyed called");}@Override  public void surfaceCreated(SurfaceHolder holder) {Log.d(TAG, "surfaceCreated called");playVideo();}@Overrideprotected void onPause() {super.onPause();releaseMediaPlayer();doCleanUp();}@Overrideprotected void onDestroy() {super.onDestroy();releaseMediaPlayer();doCleanUp();}private void releaseMediaPlayer() {if (mMediaPlayer != null) {mMediaPlayer.release();mMediaPlayer = null;}}private void doCleanUp() {mVideoWidth = 0;mVideoHeight = 0;mIsVideoReadyToBePlayed = false;mIsVideoSizeKnown = false;}private void startVideoPlayback() {Log.v(TAG, "startVideoPlayback");holder.setFixedSize(mVideoWidth, mVideoHeight);mMediaPlayer.start();}}
0 0
原创粉丝点击