原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
http://mikewang.blog.51cto.com/3826268/813611
package com.mike.activity;
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnInfoListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.LinearLayout;
public class VedioPlayByMediaPlayerDemoActivity extends Activity implements
OnCompletionListener, OnErrorListener, OnPreparedListener,
OnSeekCompleteListener, OnVideoSizeChangedListener,
SurfaceHolder.Callback, android.media.MediaPlayer.OnInfoListener,
OnBufferingUpdateListener {
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private MediaPlayer mMediaPlayer;
private int mVideoWidth = 0;
private int mVideoHeight = 0;
private boolean readyToPlay = false;
public static final String TAG = "MEDIA_PLAY_VEDIO_PLAY";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d( "path", "path is :" + Environment.getExternalStorageDirectory());
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback( this); // 添加到回调监听器
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 需要确保底层表面是一个推送缓冲区表面,需要将其应用于视频播放和摄像头预览
mMediaPlayer = new MediaPlayer();
// 设置各种监听
mMediaPlayer.setOnCompletionListener( this);
mMediaPlayer.setOnErrorListener( this);
mMediaPlayer.setOnInfoListener( this);
mMediaPlayer.setOnPreparedListener( this);
mMediaPlayer.setOnSeekCompleteListener( this);
mMediaPlayer.setOnVideoSizeChangedListener( this);
mMediaPlayer.setOnBufferingUpdateListener( this);
String path = Environment.getExternalStorageDirectory()
+ "/Movies/vedio1.mp4";
try {
mMediaPlayer.setDataSource(path); // 此处可能抛出异常
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
Log.v(TAG, e.getMessage());
this.finish();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
Log.v(TAG, e.getMessage());
this.finish();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.v(TAG, e.getMessage());
this.finish();
}
mMediaPlayer.setDisplay(mSurfaceHolder); // mediaPlayer将在其表面播放
try {
mMediaPlayer.prepare(); // prepare方法是同步的(synchronous),所以可能会阻塞,prepareAsync()是异步方法(asynchronous)。
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
Log.v(TAG, e.getMessage());
this.finish();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.v(TAG, e.getMessage());
this.finish();
}
// 设置表面大小以匹配视频或显示器大小,取决于那个大小较小
mVideoWidth = mMediaPlayer.getVideoWidth();
mVideoHeight = mMediaPlayer.getVideoHeight();
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
if (mVideoWidth > screenWidth
|| mVideoHeight > getWindowManager().getDefaultDisplay()
.getHeight()) { //如果视频宽度大于显示器大小,得到比率
float heightRatio = ( float)mVideoHeight / ( float)screenHeight;
float widthRatio = ( float)mVideoWidth / ( float)screenWidth;
if (heightRatio > 1 || widthRatio >1) { //只需宽或高一个方向超出即可
if (heightRatio > widthRatio) { //以高为准
mVideoHeight = ( int) Math.ceil(( float)mVideoHeight / ( float)heightRatio);
mVideoWidth = ( int) Math.ceil(( float)mVideoWidth / ( float)heightRatio);
} else { //以宽为准
mVideoHeight = ( int) Math.ceil(( float)mVideoHeight / ( float)widthRatio);
mVideoWidth = ( int) Math.ceil(( float)mVideoWidth / ( float)widthRatio);
}
}
}
//设置显示大小----
mSurfaceView.setLayoutParams( new LinearLayout.LayoutParams(mVideoWidth, mVideoHeight));
mMediaPlayer.start(); //播放视频
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) { // 当SurfaceView的底层表面的宽度,高度或者其他参数发生变化时,将调用SurfaceChanged方法
// TODO Auto-generated method stub
Log.v(TAG, "surfaceChanged");
}
public void surfaceCreated(SurfaceHolder holder) { // 因为实现了SurfaceHolder.Callback,并将其指定为回调监听器,所以将触发Surface的3个方法
// TODO Auto-generated method stub
Log.v(TAG, "surfaceCreated");
}
public void surfaceDestroyed(SurfaceHolder holder) { // 当Surface表面销毁时,将调用SurfaceDestroy方法
// TODO Auto-generated method stub
Log.v(TAG, "surfaceDestroyed");
}
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
// TODO Auto-generated method stub
Log.v(TAG, "onVideoSizeChanged");
}
public void onSeekComplete(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.v(TAG, "onSeekComplete");
}
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.v(TAG, "onPrepared");
}
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
Log.v(TAG, "onError");
if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
Log.v(TAG, "MEDIA_ERROR_SERVER_DIED");
mMediaPlayer.reset(); // 可调用此方法重置
} else if (what == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
Log.v(TAG, "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK");
} else if (what == MediaPlayer.MEDIA_ERROR_UNKNOWN) {
Log.v(TAG, "MEDIA_ERROR_UNKNOWN");
}
return false; // 返回false,表示错误没有被处理
}
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.v(TAG, "onCompletion");
this.finish();
}
public void onBufferingUpdate(MediaPlayer arg0, int arg1) {
// TODO Auto-generated method stub
Log.v(TAG, "onBufferingUpdate");
}
public boolean onInfo(MediaPlayer mp, int what, int extra) { // 当出现关于播放媒体的特定信息需要发出警告时,将调用此方法
// TODO Auto-generated method stub
Log.v(TAG, "onInfo");
switch (what) {
case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING: // 当文件中的音频和视频数据不正确的交错时,将触发如下操作。
// 在一个正确交错的媒体文件中,音频和视频样本依序排列,从而使得播放能够有效平稳的进行。
Log.v(TAG, "MEDIA_INFO_BAD_INTERLEAVING extar is :" + extra);
break;
case MediaPlayer.MEDIA_INFO_METADATA_UPDATE: // 当心的元数据可用时,将触发它,android
// 2.0以上版本可用。
Log.v(TAG, "MEDIA_INFO_METADATA_UPDATE extar is :" + extra);
break;
case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE: // 媒体不能正确定位,意味着它可能是一个在线流
Log.v(TAG, "MEDIA_INFO_NOT_SEEKABLE extar is :" + extra);
break;
case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING: // 当无法播放视频时,可能是将要播放视频,但是视频太复杂
Log.v(TAG, "MEDIA_INFO_VIDEO_TRACK_LAGGING extar is :" + extra);
break;
case MediaPlayer.MEDIA_INFO_UNKNOWN:
Log.v(TAG, "MEDIA_INFO_UNKNOWN extar is :" + extra);
break;
}
return false;
}
}
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnInfoListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.LinearLayout;
public class VedioPlayByMediaPlayerDemoActivity extends Activity implements
OnCompletionListener, OnErrorListener, OnPreparedListener,
OnSeekCompleteListener, OnVideoSizeChangedListener,
SurfaceHolder.Callback, android.media.MediaPlayer.OnInfoListener,
OnBufferingUpdateListener {
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private MediaPlayer mMediaPlayer;
private int mVideoWidth = 0;
private int mVideoHeight = 0;
private boolean readyToPlay = false;
public static final String TAG = "MEDIA_PLAY_VEDIO_PLAY";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d( "path", "path is :" + Environment.getExternalStorageDirectory());
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback( this); // 添加到回调监听器
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 需要确保底层表面是一个推送缓冲区表面,需要将其应用于视频播放和摄像头预览
mMediaPlayer = new MediaPlayer();
// 设置各种监听
mMediaPlayer.setOnCompletionListener( this);
mMediaPlayer.setOnErrorListener( this);
mMediaPlayer.setOnInfoListener( this);
mMediaPlayer.setOnPreparedListener( this);
mMediaPlayer.setOnSeekCompleteListener( this);
mMediaPlayer.setOnVideoSizeChangedListener( this);
mMediaPlayer.setOnBufferingUpdateListener( this);
String path = Environment.getExternalStorageDirectory()
+ "/Movies/vedio1.mp4";
try {
mMediaPlayer.setDataSource(path); // 此处可能抛出异常
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
Log.v(TAG, e.getMessage());
this.finish();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
Log.v(TAG, e.getMessage());
this.finish();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.v(TAG, e.getMessage());
this.finish();
}
mMediaPlayer.setDisplay(mSurfaceHolder); // mediaPlayer将在其表面播放
try {
mMediaPlayer.prepare(); // prepare方法是同步的(synchronous),所以可能会阻塞,prepareAsync()是异步方法(asynchronous)。
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
Log.v(TAG, e.getMessage());
this.finish();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.v(TAG, e.getMessage());
this.finish();
}
// 设置表面大小以匹配视频或显示器大小,取决于那个大小较小
mVideoWidth = mMediaPlayer.getVideoWidth();
mVideoHeight = mMediaPlayer.getVideoHeight();
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
if (mVideoWidth > screenWidth
|| mVideoHeight > getWindowManager().getDefaultDisplay()
.getHeight()) { //如果视频宽度大于显示器大小,得到比率
float heightRatio = ( float)mVideoHeight / ( float)screenHeight;
float widthRatio = ( float)mVideoWidth / ( float)screenWidth;
if (heightRatio > 1 || widthRatio >1) { //只需宽或高一个方向超出即可
if (heightRatio > widthRatio) { //以高为准
mVideoHeight = ( int) Math.ceil(( float)mVideoHeight / ( float)heightRatio);
mVideoWidth = ( int) Math.ceil(( float)mVideoWidth / ( float)heightRatio);
} else { //以宽为准
mVideoHeight = ( int) Math.ceil(( float)mVideoHeight / ( float)widthRatio);
mVideoWidth = ( int) Math.ceil(( float)mVideoWidth / ( float)widthRatio);
}
}
}
//设置显示大小----
mSurfaceView.setLayoutParams( new LinearLayout.LayoutParams(mVideoWidth, mVideoHeight));
mMediaPlayer.start(); //播放视频
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) { // 当SurfaceView的底层表面的宽度,高度或者其他参数发生变化时,将调用SurfaceChanged方法
// TODO Auto-generated method stub
Log.v(TAG, "surfaceChanged");
}
public void surfaceCreated(SurfaceHolder holder) { // 因为实现了SurfaceHolder.Callback,并将其指定为回调监听器,所以将触发Surface的3个方法
// TODO Auto-generated method stub
Log.v(TAG, "surfaceCreated");
}
public void surfaceDestroyed(SurfaceHolder holder) { // 当Surface表面销毁时,将调用SurfaceDestroy方法
// TODO Auto-generated method stub
Log.v(TAG, "surfaceDestroyed");
}
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
// TODO Auto-generated method stub
Log.v(TAG, "onVideoSizeChanged");
}
public void onSeekComplete(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.v(TAG, "onSeekComplete");
}
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.v(TAG, "onPrepared");
}
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
Log.v(TAG, "onError");
if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
Log.v(TAG, "MEDIA_ERROR_SERVER_DIED");
mMediaPlayer.reset(); // 可调用此方法重置
} else if (what == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
Log.v(TAG, "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK");
} else if (what == MediaPlayer.MEDIA_ERROR_UNKNOWN) {
Log.v(TAG, "MEDIA_ERROR_UNKNOWN");
}
return false; // 返回false,表示错误没有被处理
}
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
Log.v(TAG, "onCompletion");
this.finish();
}
public void onBufferingUpdate(MediaPlayer arg0, int arg1) {
// TODO Auto-generated method stub
Log.v(TAG, "onBufferingUpdate");
}
public boolean onInfo(MediaPlayer mp, int what, int extra) { // 当出现关于播放媒体的特定信息需要发出警告时,将调用此方法
// TODO Auto-generated method stub
Log.v(TAG, "onInfo");
switch (what) {
case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING: // 当文件中的音频和视频数据不正确的交错时,将触发如下操作。
// 在一个正确交错的媒体文件中,音频和视频样本依序排列,从而使得播放能够有效平稳的进行。
Log.v(TAG, "MEDIA_INFO_BAD_INTERLEAVING extar is :" + extra);
break;
case MediaPlayer.MEDIA_INFO_METADATA_UPDATE: // 当心的元数据可用时,将触发它,android
// 2.0以上版本可用。
Log.v(TAG, "MEDIA_INFO_METADATA_UPDATE extar is :" + extra);
break;
case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE: // 媒体不能正确定位,意味着它可能是一个在线流
Log.v(TAG, "MEDIA_INFO_NOT_SEEKABLE extar is :" + extra);
break;
case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING: // 当无法播放视频时,可能是将要播放视频,但是视频太复杂
Log.v(TAG, "MEDIA_INFO_VIDEO_TRACK_LAGGING extar is :" + extra);
break;
case MediaPlayer.MEDIA_INFO_UNKNOWN:
Log.v(TAG, "MEDIA_INFO_UNKNOWN extar is :" + extra);
break;
}
return false;
}
}