Fork me on GitHub

基于IJKPlayer视频播放器简单封装设计

播放器的简单设计

播放器基于IJKPlayer来设计的, 播放器大致分三层

1.播放内核(基于ijkMediaplayer)
2.播放器View
3.播放器的MediaController

1、封装播放内核

我们都知道需要播放一个视频需要三个过程 1.create MediaPlayer 2.MediaPlayer prepare 3.MediaPlayer 与 Surface 绑定
xinvideoplayer中使用了VideoManager来控制ijkmediaplayer 所有的操作

三个过程 我们使用 HandlerThread + Hander 来实现 第一个过程创建大致可能需要100ms左右,严重影响UI线程!!!

  • 第一个过程: create MediaPlayer

    new IjkMediaPlayer() 设置一些播放器回调方法

1
2
3
4
5
6
7
8
9
10
11
12
//IJK 的 Mediaplayer api 类似 Android 系统播放器api
//IMediaPlayer.class
public interface IMediaPlayer{
void setOnPreparedListener(IMediaPlayer.OnPreparedListener var1); //prepareAsync 之后回调方法
void setOnCompletionListener(IMediaPlayer.OnCompletionListener var1); //播放完成回调方法
void setOnBufferingUpdateListener(IMediaPlayer.OnBufferingUpdateListener var1);//当播放网络的数据流的buffer发生变化的时候
void setOnSeekCompleteListener(IMediaPlayer.OnSeekCompleteListener var1);//当seek定位操作完成后
void setOnVideoSizeChangedListener(IMediaPlayer.OnVideoSizeChangedListener var1);//当视频的大小第一次被知道或者发生改变时
void setOnErrorListener(IMediaPlayer.OnErrorListener var1);//当有发生错误
void setOnInfoListener(IMediaPlayer.OnInfoListener var1);//当有信息或者警告
void setOnTimedTextListener(IMediaPlayer.OnTimedTextListener var1); //当媒体的时间数据需要被显示
}
  • 第二个阶段 prepare

    mediaPlayer.prepareAsync(); 等待回调 IMediaPlayer.OnPreparedListener#onPrepare()

  • 第三个阶段 给IJKMediaPlayer 绑定 Surface 呈现画面

    mediaPlayer.setSurface();

2、播放器View

实现 播放器基本方法(IViewPlayer)和 播放内核回调方法(IMediaPlayerListener)
IMediaPlayerListener 是包装 IMediaPlayer 所有接口并通过 Handle 发送到主线程中实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//IVideoPlayer.java
interface IVideoPlayer{
void start();//开始播放
void pause();//暂停播放
void seekTo(long time); //seekto time
void release();//关闭播放
void setVideoPath();//设置视频路径
void onStartFullScreen();//全屏播放
void onBackFullScreen(); //退出全屏
void onResumeVideo();//播放器后台唤起
void onPauseVideo();//切换后台
int getCurrentState();//视频的当前状态
int getCurrentScreenState(); //当前屏幕的状态 例如小屏,大屏,竖屏
long getTcpSpeed();//获取网速
void switchVideoSource(String url,long delay);//切换清晰度 并流畅的切换
}
public interface MediaPlayerListener extends IVideoPlayer {

void onPrepared();
void onAutoCompletion();
void onCompletion();
void onBufferingUpdate(int percent);
void onSeekComplete(long currentPosition);
void onError(int what, int extra);
void onInfo(int what, int extra);
void onVideoSizeChanged();
}

以上接口大致满足了所有播放器的功能要求!!

3.MediaController

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface IVideoController {
//顾名思义
View bindPlayer(IVideoPlayer player);
void onChangeVideoStatus(IVideoPlayer player, int old_status, int new_status);
void onChangeScreenStatus(IVideoPlayer player, int old_status, int new_status);
boolean onChangedNetWork(int currentNetState);
void onVideoProgress(int percent, long curr_position, long duration);
void unbindPlayer(IVideoPlayer player);
boolean isLock();
void onVideoDefinitionSwitched();
void show();
void hide();
boolean isShowing();

BaseVideoPlayer#setVideoController()

  • 播放器的简单接入使用
1
2
3
4
5
6
7
8
9
10
11
videoplayer.setVideoPath(url);
videoplayer.start();//开始播放
//如果需要后台暂停唤起继续播放
videoplayer.onVideoResume();
videoplayer.onVideoPause();
//如果需要后台暂停唤起继续播放
全屏时控制返回键问题:
if (!VideoPlayerUtils.onBackPressed()) {
//返回的正常逻辑
}
...

播放器的内部实现

start

预加载需求 & 复用播放器

预加载

智能后台&唤起处理

智能后台&唤起处理

播放器的扩展实现

-------------本文结束感谢您的阅读-------------

本文标题:基于IJKPlayer视频播放器简单封装设计

文章作者:zoudong

发布时间:2018年05月02日 - 10:05

最后更新:2019年03月16日 - 15:03

原始链接:http://blog.zoudongq123.cn/2018/05/02/视频播放器设计/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

分享