在公司写了个MediaPlayer+SurfaceHolder工具类,用来播放本地视频,支持seekbar定位播放
特地做个笔记,如果有写的不好的地方,欢迎指出,我会及时改正。
直接上代码:
package com.wirelesscamera.view;
import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Handler;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.securesmart.camera.R;
import java.io.IOException;
public class IMediaPlayer extends FrameLayout implements
MediaPlayer.OnCompletionListener,
MediaPlayer.OnPreparedListener,
MediaPlayer.OnSeekCompleteListener,
MediaPlayer.OnErrorListener,
MediaPlayer.OnBufferingUpdateListener,
SurfaceHolder.Callback {
private String TAG = "IMediaPlayer";
private Context context;
private Activity activity;
// SurfaceView的创建比较耗时,要注意
private SurfaceHolder surfaceHolder;
private MediaPlayer mediaPlayer;
// 标记暂停和播放状态
private boolean isPlaying = true;
private boolean isFirstPlay = false;
private boolean isPrepare = false;
//地址
private String videoPath;
private int video_position = 0;
private AudioManager audioManager;
// 控件实例化
private SurfaceView player_surfaceView;
private boolean isMute = false;
public IMediaPlayer(@NonNull Context context) {
this(context, null);
}
public IMediaPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public IMediaPlayer(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
this.activity = (Activity) context;
initView();
}
private void initView() {
View view = View.inflate(context, R.layout.media_player_layout, this);
player_surfaceView = (SurfaceView) view.findViewById(R.id.player_surfaceView);
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
initSurfaceView();
}
private void initSurfaceView() {
surfaceHolder = player_surfaceView.getHolder();
surfaceHolder.addCallback(this);
}
/**
* 播放视频
*
* @param url 视频地址
*/
public void playVideo(String url) {
playVideo(url, video_position);
}
private void playVideo(String url, int position) {
if (TextUtils.isEmpty(url)) {
Toast.makeText(context, context.getString(R.string.playback_file_not_exist), Toast.LENGTH_SHORT).show();
return;
}
videoPath = url;
video_position = position;
isPrepare = false;
isPlaying = true;
resetMediaplayer();
}
/**
* 设置视频信息
*
* @param url 视频地址
*/
public void setDataSource(String url) {
//赋值
videoPath = url;
}
public boolean isPlaying() {
return mediaPlayer != null && mediaPlayer.isPlaying();
}
// 播放视频
public void startVideo() {
if (mediaPlayer != null) {
mediaPlayer.start();
isPlaying = true;
}
}
/**
* 暂停视频
*/
public void pauseVideo() {
if (mediaPlayer != null) {
mediaPlayer.pause();
video_position = mediaPlayer.getCurrentPosition();
isPlaying = false;
}
}
private void resetMediaplayer() {
try {
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
mediaPlayer.stop();
}
mediaPlayer.reset();
mediaPlayer.setDataSource(videoPath);
if (isMute) {
mediaPlayer.setVolume(0f, 0f);
} else {
if (mediaPlayer != null) {
mediaPlayer.setVolume(1f, 1f);
}
}
// 准备开始,异步准备,自动在子线程中
mediaPlayer.prepareAsync();
//视频缩放模式
mediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);
} else {
Toast.makeText(context, "Init MediaPlayer Failed", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void destroyVideo() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
}
if (surfaceHolder != null) {
surfaceHolder.addCallback(null);
surfaceHolder = null;
}
if (player_surfaceView != null) {
player_surfaceView.getHolder().getSurface().release();
player_surfaceView = null;
}
video_position = 0;
if (onPreparedListener != null) {
onPreparedListener = null;
}
if (onCompletionListener != null) {
onCompletionListener = null;
}
}
public void seekTo(int position) {
if (mediaPlayer != null) {
mediaPlayer.seekTo(position);
}
}
public int getCurrentPosition() {
return mediaPlayer != null ? mediaPlayer.getCurrentPosition() : 0;
}
public int getDuration() {
return mediaPlayer != null ? mediaPlayer.getDuration() : 0;
}
public void setMediaVolum(boolean isMute) {
this.isMute = isMute;
if (isMute) {
if (mediaPlayer != null) {
mediaPlayer.setVolume(0f, 0f);
}
} else {
// Request audio focus for playback
int result = audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
if (mediaPlayer != null) {
mediaPlayer.setVolume(1f, 1f);
}
}
}
}
public void setAutoPlay(boolean isAuto) {
this.isFirstPlay = isAuto;
}
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}
@Override
public void onCompletion(MediaPlayer mp) {
isPlaying = false;
video_position = 0;
if (onCompletionListener != null) {
onCompletionListener.onCompletion(mediaPlayer);
}
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.i(TAG, "onPrepared");
// 开始播放
mediaPlayer.start();
if (!isPlaying) {
mediaPlayer.pause();
} else {
}
isPrepare = true;
if (onPreparedListener != null) {
onPreparedListener.onPrepared();
}
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//跳转指定位置
if (video_position > 0) {
Log.i(TAG, "onPrepared---video_position:" + video_position);
IMediaPlayer.this.mediaPlayer.seekTo(video_position);
video_position = 0;
}
}
}, 33);
}
@Override
public void onSeekComplete(MediaPlayer mp) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.i(TAG, "surfaceCreated");
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDisplay(holder);
// 播放完成的监听
mediaPlayer.setOnCompletionListener(this);
// 异步准备的一个监听函数,准备好了就调用里面的方法
mediaPlayer.setOnPreparedListener(this);
// 播放错误的监听
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnBufferingUpdateListener(this);
if (isFirstPlay) {
//添加播放路径
try {
mediaPlayer.setDataSource(videoPath);
if (isMute) {
mediaPlayer.setVolume(0f, 0f);
} else {
if (mediaPlayer != null) {
mediaPlayer.setVolume(1f, 1f);
}
}
// 准备开始,异步准备,自动在子线程中
mediaPlayer.prepareAsync();
//视频缩放模式
mediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);
} catch (IOException e) {
e.printStackTrace();
}
}
isFirstPlay = true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i(TAG, "surfaceDestroyed");
if (mediaPlayer != null) {
mediaPlayer.pause();
video_position = mediaPlayer.getCurrentPosition();
}
}
//SurfaceView初始化完成回调
private OnPreparedListener onPreparedListener;
public void setOnPreparedListener(OnPreparedListener onPreparedListener) {
this.onPreparedListener = onPreparedListener;
}
public interface OnPreparedListener {
void onPrepared();
}
//-----------------------播放完回调
private OnCompletionListener onCompletionListener;
public void setOnCompletionListener(OnCompletionListener onCompletionListener) {
this.onCompletionListener = onCompletionListener;
}
public interface OnCompletionListener {
void onCompletion(MediaPlayer mediaPlayer);
}
}