protected IjkMediaPlayer mMediaPlayer;
private int mBufferedPercent;
private Context mAppContext;
public IjkVideoPlayer(Context context) {
if (context instanceof Application){
mAppContext = context;
} else {
mAppContext = context.getApplicationContext();
}
}
@Override
public void initPlayer() {
mMediaPlayer = new IjkMediaPlayer();
//native日志
IjkMediaPlayer.native_setLogLevel(VideoLogUtils.isIsLog()
? IjkMediaPlayer.IJK_LOG_INFO : IjkMediaPlayer.IJK_LOG_SILENT);
setOptions();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
initListener();
}
@Override
public void setOptions() {
}
/**
* ijk视频播放器监听listener
*/
private void initListener() {
// 设置监听,可以查看ijk中的IMediaPlayer源码监听事件
// 设置视频错误监听器
mMediaPlayer.setOnErrorListener(onErrorListener);
// 设置视频播放完成监听事件
mMediaPlayer.setOnCompletionListener(onCompletionListener);
// 设置视频信息监听器
mMediaPlayer.setOnInfoListener(onInfoListener);
// 设置视频缓冲更新监听事件
mMediaPlayer.setOnBufferingUpdateListener(onBufferingUpdateListener);
// 设置准备视频播放监听事件
mMediaPlayer.setOnPreparedListener(onPreparedListener);
// 设置视频大小更改监听器
mMediaPlayer.setOnVideoSizeChangedListener(onVideoSizeChangedListener);
// 设置视频seek完成监听事件
mMediaPlayer.setOnSeekCompleteListener(onSeekCompleteListener);
// 设置时间文本监听器
mMediaPlayer.setOnTimedTextListener(onTimedTextListener);
mMediaPlayer.setOnNativeInvokeListener(new IjkMediaPlayer.OnNativeInvokeListener() {
@Override
public boolean onNativeInvoke(int i, Bundle bundle) {
return true;
}
});
}
/**
* 设置播放地址
*
* @param path 播放地址
* @param headers 播放地址请求头
*/
@Override
public void setDataSource(String path, Map<String, String> headers) {
// 设置dataSource
if(path==null || path.length()==0){
if (mPlayerEventListener!=null){
mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_URL_NULL, 0);
}
return;
}
try {
//解析path
Uri uri = Uri.parse(path);
if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())) {
RawDataSourceProvider rawDataSourceProvider = RawDataSourceProvider.create(mAppContext, uri);
mMediaPlayer.setDataSource(rawDataSourceProvider);
} else {
//处理UA问题
if (headers != null) {
String userAgent = headers.get("User-Agent");
if (!TextUtils.isEmpty(userAgent)) {
mMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "user_agent", userAgent);
}
}
mMediaPlayer.setDataSource(mAppContext, uri, headers);
}
} catch (Exception e) {
mPlayerEventListener.onError();
}
}
/**
* 用于播放raw和asset里面的视频文件
*/
@Override
public void setDataSource(AssetFileDescriptor fd) {
try {
mMediaPlayer.setDataSource(new RawDataSourceProvider(fd));
} catch (Exception e) {
mPlayerEventListener.onError();
}
}
/**
* 设置渲染视频的View,主要用于TextureView
* @param surface surface
*/
@Override
public void setSurface(Surface surface) {
mMediaPlayer.setSurface(surface);
}
/**
* 准备开始播放(异步)
*/
@Override
public void prepareAsync() {
try {
mMediaPlayer.prepareAsync();
} catch (IllegalStateException e) {
mPlayerEventListener.onError();
}
}
/**
* 暂停
*/
@Override
public void pause() {
try {
mMediaPlayer.pause();
} catch (IllegalStateException e) {
mPlayerEventListener.onError();
}
}
/**
* 播放
*/
@Override
public void start() {
try {
mMediaPlayer.start();
} catch (IllegalStateException e) {
mPlayerEventListener.onError();
}
}
/**
* 停止
*/
@Override
public void stop() {
try {
mMediaPlayer.stop();
} catch (IllegalStateException e) {
mPlayerEventListener.onError();
}
}
/**
* 重置播放器
*/
@Override
public void reset() {
mMediaPlayer.reset();
mMediaPlayer.setOnVideoSizeChangedListener(onVideoSizeChangedListener);
setOptions();
}
/**
* 是否正在播放
*/
@Override
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
/**
* 调整进度
*/
@Override
public void seekTo(long time) {
try {
mMediaPlayer.seekTo((int) time);
} catch (IllegalStateException e) {
mPlayerEventListener.onError();
}
}
/**
* 释放播放器
*/
@Override
public void release() {
mMediaPlayer.setOnErrorListener(null);
mMediaPlayer.setOnCompletionListener(null);
mMediaPlayer.setOnInfoListener(null);
mMediaPlayer.setOnBufferingUpdateListener(null);
mMediaPlayer.setOnPreparedListener(null);
mMediaPlayer.setOnVideoSizeChangedListener(null);
new Thread() {
@Override
public void run() {
try {
mMediaPlayer.release();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 获取当前播放的位置
*/
@Override
public long getCurrentPosition() {
return mMediaPlayer.getCurrentPosition();
}
/**
* 获取视频总时长
*/
@Override
public long getDuration() {
return mMediaPlayer.getDuration();
}
/**
* 获取缓冲百分比
*/
@Override
public int getBufferedPercentage() {
return mBufferedPercent;
}
/**
* 设置渲染视频的View,主要用于SurfaceView
*/
@Override
public void setDisplay(SurfaceHolder holder) {
mMediaPlayer.setDisplay(holder);
}
/**
* 设置音量
*/
@Override
public void setVolume(float v1, float v2) {
mMediaPlayer.setVolume(v1, v2);
}
/**
* 设置是否循环播放
*/
@Override
public void setLooping(boolean isLooping) {
mMediaPlayer.setLooping(isLooping);
}
/**
* 设置播放速度
*/
@Override
public void setSpeed(float speed) {
mMediaPlayer.setSpeed(speed);
}
/**
* 获取播放速度
*/
@Override
public float getSpeed() {
return mMediaPlayer.getSpeed(0);
}
/**
* 获取当前缓冲的网速
*/
@Override
public long getTcpSpeed() {
return mMediaPlayer.getTcpSpeed();
}
/**
* 设置视频错误监听器
* int MEDIA_INFO_VIDEO_RENDERING_START = 3;//视频准备渲染
* int MEDIA_INFO_BUFFERING_START = 701;//开始缓冲
* int MEDIA_INFO_BUFFERING_END = 702;//缓冲结束
* int MEDIA_INFO_VIDEO_ROTATION_CHANGED = 10001;//视频选择信息
* int MEDIA_ERROR_SERVER_DIED = 100;//视频中断,一般是视频源异常或者不支持的视频类型。
* int MEDIA_ERROR_IJK_PLAYER = -10000,//一般是视频源有问题或者数据格式不支持,比如音频不是AAC之类的
* int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200;//数据错误没有有效的回收
*/
private IMediaPlayer.OnErrorListener onErrorListener = new IMediaPlayer.OnErrorListener() {
@Override
public boolean onError(IMediaPlayer iMediaPlayer, int framework_err, int impl_err) {
mPlayerEventListener.onError();
VideoLogUtils.d("IjkVideoPlayer----listener---------onError ——> STATE_ERROR ———— what:" + framework_err + ", extra: " + impl_err);
return true;
}
};
/**
* 设置视频播放完成监听事件
*/
private IMediaPlayer.OnCompletionListener onCompletionListener = new IMediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(IMediaPlayer iMediaPlayer) {
mPlayerEventListener.onCompletion();
VideoLogUtils.d("IjkVideoPlayer----listener---------onCompletion ——> STATE_COMPLETED");
}
};
/**
* 设置视频信息监听器
*/
private IMediaPlayer.OnInfoListener onInfoListener = new IMediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(IMediaPlayer iMediaPlayer, int what, int extra) {
mPlayerEventListener.onInfo(what, extra);
VideoLogUtils.d("IjkVideoPlayer----listener---------onInfo ——> ———— what:" + what + ", extra: " + extra);
return true;
}
};
/**
* 设置视频缓冲更新监听事件
*/
private IMediaPlayer.OnBufferingUpdateListener onBufferingUpdateListener = new IMediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(IMediaPlayer iMediaPlayer, int percent) {
mBufferedPercent = percent;
}
};
/**
* 设置准备视频播放监听事件
*/
private IMediaPlayer.OnPreparedListener onPreparedListener = new IMediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(IMediaPlayer iMediaPlayer) {
mPlayerEventListener.onPrepared();
VideoLogUtils.d("IjkVideoPlayer----listener---------onPrepared ——> STATE_PREPARED");
}
};
/**
* 设置视频大小更改监听器
*/
private IMediaPlayer.OnVideoSizeChangedListener onVideoSizeChangedListener = new IMediaPlayer.OnVideoSizeChangedListener() {
@Override
public void onVideoSizeChanged(IMediaPlayer iMediaPlayer, int width, int height,
int sar_num, int sar_den) {
int videoWidth = iMediaPlayer.getVideoWidth();
int videoHeight = iMediaPlayer.getVideoHeight();
if (videoWidth != 0 && videoHeight != 0) {
mPlayerEventListener.onVideoSizeChanged(videoWidth, videoHeight);
}
VideoLogUtils.d("IjkVideoPlayer----listener---------onVideoSizeChanged ——> WIDTH:" + width + ", HEIGHT:" + height);
}
};
/**
* 设置时间文本监听器
*/
private IMediaPlayer.OnTimedTextListener onTimedTextListener = new IMediaPlayer.OnTimedTextListener() {
@Override
public void onTimedText(IMediaPlayer iMediaPlayer, IjkTimedText ijkTimedText) {
}
};
/**
* 设置视频seek完成监听事件
*/
private IMediaPlayer.OnSeekCompleteListener onSeekCompleteListener = new IMediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(IMediaPlayer iMediaPlayer) {
}
};
}
```
protected Context mAppContext;
protected SimpleExoPlayer mInternalPlayer;
protected MediaSource mMediaSource;
protected ExoMediaSourceHelper mMediaSourceHelper;
private PlaybackParameters mSpeedPlaybackParameters;
private int mLastReportedPlaybackState = Player.STATE_IDLE;
private boolean mLastReportedPlayWhenReady = false;
private boolean mIsPreparing;
private boolean mIsBuffering;
private LoadControl mLoadControl;
private RenderersFactory mRenderersFactory;
private TrackSelector mTrackSelector;
public ExoMediaPlayer(Context context) {
if (context instanceof Application){
mAppContext = context;
} else {
mAppContext = context.getApplicationContext();
}
mMediaSourceHelper = ExoMediaSourceHelper.getInstance(context);
}
@Override
public void initPlayer() {
//创建exo播放器
mInternalPlayer = new SimpleExoPlayer.Builder(
mAppContext,
mRenderersFactory == null ? mRenderersFactory = new DefaultRenderersFactory(mAppContext) : mRenderersFactory,
mTrackSelector == null ? mTrackSelector = new DefaultTrackSelector(mAppContext) : mTrackSelector,
mLoadControl == null ? mLoadControl = new DefaultLoadControl() : mLoadControl,
DefaultBandwidthMeter.getSingletonInstance(mAppContext),
Util.getLooper(),
new AnalyticsCollector(Clock.DEFAULT),
/* useLazyPreparation= */ true,
Clock.DEFAULT)
.build();
setOptions();
//播放器日志
if (VideoLogUtils.isIsLog() && mTrackSelector instanceof MappingTrackSelector) {
mInternalPlayer.addAnalyticsListener(new EventLogger((MappingTrackSelector) mTrackSelector, "ExoPlayer"));
}
initListener();
}
/**
* exo视频播放器监听listener
*/
private void initListener() {
mInternalPlayer.addListener(this);
mInternalPlayer.addVideoListener(this);
}
public void setTrackSelector(TrackSelector trackSelector) {
mTrackSelector = trackSelector;
}
public void setRenderersFactory(RenderersFactory renderersFactory) {
mRenderersFactory = renderersFactory;
}
public void setLoadControl(LoadControl loadControl) {
mLoadControl = loadControl;
}
/**
* 设置播放地址
*
* @param path 播放地址
* @param headers 播放地址请求头
*/
@Override
public void setDataSource(String path, Map<String, String> headers) {
// 设置dataSource
if(path==null || path.length()==0){
if (mPlayerEventListener!=null){
mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_URL_NULL, 0);
}
return;
}
mMediaSource = mMediaSourceHelper.getMediaSource(path, headers);
}
@Override
public void setDataSource(AssetFileDescriptor fd) {
//no support
}
/**
* 准备开始播放(异步)
*/
@Override
public void prepareAsync() {
if (mInternalPlayer == null){
return;
}
if (mMediaSource == null){
return;
}
if (mSpeedPlaybackParameters != null) {
mInternalPlayer.setPlaybackParameters(mSpeedPlaybackParameters);
}
mIsPreparing = true;
mMediaSource.addEventListener(new Handler(), mMediaSourceEventListener);
//准备播放
mInternalPlayer.prepare(mMediaSource);
}
/**
* 播放
*/
@Override
public void start() {
if (mInternalPlayer == null){
return;
}
mInternalPlayer.setPlayWhenReady(true);
}
/**
* 暂停
*/
@Override
public void pause() {
if (mInternalPlayer == null){
return;
}
mInternalPlayer.setPlayWhenReady(false);
}
/**
* 停止
*/
@Override
public void stop() {
if (mInternalPlayer == null){
return;
}
mInternalPlayer.stop();
}
private MediaSourceEventListener mMediaSourceEventListener = new MediaSourceEventListener() {
@Override
public void onReadingStarted(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId) {
if (mPlayerEventListener != null && mIsPreparing) {
mPlayerEventListener.onPrepared();
}
}
};
/**
* 重置播放器
*/
@Override
public void reset() {
if (mInternalPlayer != null) {
mInternalPlayer.stop(true);
mInternalPlayer.setVideoSurface(null);
mIsPreparing = false;
mIsBuffering = false;
mLastReportedPlaybackState = Player.STATE_IDLE;
mLastReportedPlayWhenReady = false;
}
}
/**
* 是否正在播放
*/
@Override
public boolean isPlaying() {
if (mInternalPlayer == null){
return false;
}
int state = mInternalPlayer.getPlaybackState();
switch (state) {
case Player.STATE_BUFFERING:
case Player.STATE_READY:
return mInternalPlayer.getPlayWhenReady();
case Player.STATE_IDLE:
case Player.STATE_ENDED:
default:
return false;
}
}
/**
* 调整进度
*/
@Override
public void seekTo(long time) {
if (mInternalPlayer == null){
return;
}
mInternalPlayer.seekTo(time);
}
/**
* 释放播放器
*/
@Override
public void release() {
if (mInternalPlayer != null) {
mInternalPlayer.removeListener(this);
mInternalPlayer.removeVideoListener(this);
final SimpleExoPlayer player = mInternalPlayer;
mInternalPlayer = null;
new Thread() {
@Override
public void run() {
//异步释放,防止卡顿
player.release();
}
}.start();
}
mIsPreparing = false;
mIsBuffering = false;
mLastReportedPlaybackState = Player.STATE_IDLE;
mLastReportedPlayWhenReady = false;
mSpeedPlaybackParameters = null;
}
/**
* 获取当前播放的位置
*/
@Override
public long getCurrentPosition() {
if (mInternalPlayer == null){
return 0;
}
return mInternalPlayer.getCurrentPosition();
}
/**
* 获取视频总时长
*/
@Override
public long getDuration() {
if (mInternalPlayer == null){
return 0;
}
return mInternalPlayer.getDuration();
}
/**
* 获取缓冲百分比
*/
@Override
public int getBufferedPercentage() {
return mInternalPlayer == null ? 0 : mInternalPlayer.getBufferedPercentage();
}
/**
* 设置渲染视频的View,主要用于SurfaceView
*/
@Override
public void setSurface(Surface surface) {
if (mInternalPlayer != null) {
mInternalPlayer.setVideoSurface(surface);
}
}
@Override
public void setDisplay(SurfaceHolder holder) {
if (holder == null){
setSurface(null);
} else{
setSurface(holder.getSurface());
}
}
/**
* 设置音量
*/
@Override
public void setVolume(float leftVolume, float rightVolume) {
if (mInternalPlayer != null){
mInternalPlayer.setVolume((leftVolume + rightVolume) / 2);
}
}
/**
* 设置是否循环播放
*/
@Override
public void setLooping(boolean isLooping) {
if (mInternalPlayer != null){
mInternalPlayer.setRepeatMode(isLooping ? Player.REPEAT_MODE_ALL : Player.REPEAT_MODE_OFF);
}
}
@Override
public void setOptions() {
//准备好就开始播放
mInternalPlayer.setPlayWhenReady(true);
}
/**
* 设置播放速度
*/
@Override
public void setSpeed(float speed) {
PlaybackParameters playbackParameters = new PlaybackParameters(speed);
mSpeedPlaybackParameters = playbackParameters;
if (mInternalPlayer != null) {
mInternalPlayer.setPlaybackParameters(playbackParameters);
}
}
/**
* 获取播放速度
*/
@Override
public float getSpeed() {
if (mSpeedPlaybackParameters != null) {
return mSpeedPlaybackParameters.speed;
}
return 1f;
}
/**
* 获取当前缓冲的网速
*/
@Override
public long getTcpSpeed() {
// no support
return 0;
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (mPlayerEventListener == null){
return;
}
if (mIsPreparing){
return;
}
if (mLastReportedPlayWhenReady != playWhenReady || mLastReportedPlaybackState != playbackState) {
switch (playbackState) {
//最开始调用的状态
case Player.STATE_IDLE:
break;
//开始缓充
case Player.STATE_BUFFERING:
mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_BUFFERING_START, getBufferedPercentage());
mIsBuffering = true;
break;
//开始播放
case Player.STATE_READY:
if (mIsBuffering) {
mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_BUFFERING_END, getBufferedPercentage());
mIsBuffering = false;
}
break;
//播放器已经播放完了媒体
case Player.STATE_ENDED:
mPlayerEventListener.onCompletion();
break;
default:
break;
}
mLastReportedPlaybackState = playbackState;
mLastReportedPlayWhenReady = playWhenReady;
}
}
@Override
public void onPlayerError(ExoPlaybackException error) {
if (mPlayerEventListener != null) {
mPlayerEventListener.onError();
}
}
@Override
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
if (mPlayerEventListener != null) {
mPlayerEventListener.onVideoSizeChanged(width, height);
if (unappliedRotationDegrees > 0) {
mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_VIDEO_ROTATION_CHANGED, unappliedRotationDegrees);
}
}
}
@Override
public void onRenderedFirstFrame() {
if (mPlayerEventListener != null && mIsPreparing) {
mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_VIDEO_RENDERING_START, 0);
mIsPreparing = false;
}
}
}
```
public static ExoPlayerFactory create() {
return new ExoPlayerFactory();
}
@Override
public ExoMediaPlayer createPlayer(Context context) {
return new ExoMediaPlayer(context);
}
}
```
public static TxPlayerFactory create() {
return new TxPlayerFactory();
}
@Override
public TxMediaPlayer createPlayer(Context context) {
return new TxMediaPlayer(context);
}
}
public class TxMediaPlayer extends AbstractVideoPlayer {
//省略接口的实现方法代码
}
```
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。