一、目的
在上一篇简单的使用ijkplayer播放出了视屏,但是其中只是最简单的视屏播放就连停止功能都没有,所以在这一偏里就可以根据个人需要查询需要的功能添加到项目中。
上一篇 IjkPlayer【1】 Demo Android的最简单实现
如果想对Ijkplayer的底层结构有更深的了解可以看下一篇 IjkPLayer【3】源码项目结构分析
二、主要功能类的结构
1)概述
IjkPlayer从使用角度上主要有五个文件分别是IMediaPlayer、AbstractMediaPlayer、AndroidMediaPlayer、IjkMediaPlayer、IjkExoMediaPlayer,除了IjkExoMediaPlayer.java 是独立的一个库文件中其他的四个都是在源码ijkplayer-java的Model中。其中AndroidMediaPlayer、IjkMediaPlayer、IjkExoMediaPlayer三个类都是播放器的实现,所以三个类是独立的,但是由于都是对IMediaPlayer的实现,所以虽然这三个类内部处理方式不同,但是在使用上是基本一致的,其中只有IjkMediaPlayer是使用ijkplayer底层库处理视频。以下就是各个类的介绍。
2)类简介
IMediaPlayer:定义了一个播放器的类应该需要实现的基础功能。所以播放视屏的功能函数在这里都能找到。
AbstractMediaPlayer:实现了IMediaPlayer接口,将播放器通用的响应事件进行了统一实现,但是主要功能任然需要子类实现。播放过程中的事件的操作就可以在这里查。
AndroidMediaPlayer:继承AbstractMediaPlayer,使用Android系统的编解码对视屏进行操作。
IjkMediaPlayer:继承AbstractMediaPlayer,使用Ijkplayer对视屏进行编解码处理。
IjkExoMediaPlayer:继承AbstractMediaPlayer,使用ExoPlayer对视屏进行处理。
3)UML 类图
4)IMediaPlayer
IMediaPlayer是对播放器的定义,所以要对IjkMediaPlayer进行操作主要查看当前接口就可以了。
//设置显示控件
void setDisplay(SurfaceHolder sh);//设置数据资源地址
void setDataSource(Context context, Uri uri)
void setDataSource(Context context, Uri uri, Map<String, String> headers)
void setDataSource(FileDescriptor fd)
void setDataSource(String path)//获取资源地址
String getDataSource();
//播放前准备
void prepareAsync()
//开始
void start()
//停止
void stop()
//暂停
void pause()
//
void setScreenOnWhilePlaying(boolean screenOn);
//获取视屏的宽度
int getVideoWidth();
//获取视屏的高度
int getVideoHeight();
//获取当前播放状态
boolean isPlaying();//滑动到指定播放位置
void seekTo(long msec);//获取当前播放位置
long getCurrentPosition();//获取资源时长
long getDuration();//释放资源
void release();
//重置
void reset();
//设置音量 0-1 表示百分比
void setVolume(float leftVolume, float rightVolume);int getAudioSessionId();MediaInfo getMediaInfo();void setLogEnabled(boolean enable);
//是否正在播放
boolean isPlayable();
5)AbstractMediaPlayer
AbstractMediaPlayer是IMediaPlayer接口事件的实现,所以播放器有哪些事件可以处理就可以查这个类。
//资源准备就绪事件回调
private OnPreparedListener mOnPreparedListener;
//播放结束事件回调
private OnCompletionListener mOnCompletionListener;
//缓存更新事件回调
private OnBufferingUpdateListener mOnBufferingUpdateListener;
//滑动到指定位置操作结果回调
private OnSeekCompleteListener mOnSeekCompleteListener;
//视屏尺寸发生变化回调
private OnVideoSizeChangedListener mOnVideoSizeChangedListener;
//异常回调
private OnErrorListener mOnErrorListener;
//视屏信息回调
private OnInfoListener mOnInfoListener;
//时间相关回调
private OnTimedTextListener mOnTimedTextListener;
6) IjkMediaPlayer
IjkMediaPlayer是继承AbstractMediaPlayer所以主要的功能和响应事件都分别在IMediaPlayer、IjkMediaPlayer中可以查到,这个类主要是对抽象函数的实现,所以查询功能函数还是在IMediaPlayer、IjkMediaPlayer中查找方便得多。
除了IMediaPlayer定义的主要功能外IjkMediaPlayer还要个性化的设置,IjkMediaPlayer的个性化设置时通过setOption函数实现的,一下就是setOption函数的解释以及列出了主要常用的配置,如果想要查看所有可配置参数在下面也列出了所有参数在源码中的位置。
// ijkplayer 个性化配置函数
public void setOption(int category, String name, long value)
参数一:category视屏处理不同阶段的配置,在Native源码中有六个配置,但是开放到Java的主要有一下四个。
参数二:配置的名称
参数三:配置的具体值
//在IjkMediaPlayer类中可以找到四个可以配置的category,以下就是可以配置的的参数在源文件的位置和常用配置1)格式配置//可用参数是ffmpeg/libavformat/options_table.h 中的配置public static final int OPT_CATEGORY_FORMAT = 1;//常用配置:1、设置播放前的最大探测时间"analyzemaxduration" 值:100L;2、设置播放前的探测时间 1,达到首屏秒开效果"analyzeduration" 值:1;3、播放前的探测Size,默认是1M, 改小一点会出画面更快"probesize" 值:1024*10;4、每处理一个packet之后刷新io上下文"flush_packets" 值:1L;5、解决m3u8文件拖动问题 比如:一个3个多少小时的音频文件,开始播放几秒中,然后拖动到2小时左右的时间,要loading 10分钟"fflags" 值:"fastseek";//设置seekTo能够快速seek到指定位置并播放2)编解码配置//可用参数是ffmpeg/libavcodec/options_table.h 中的配置public static final int OPT_CATEGORY_CODEC = 2;//常用配置1、设置是否开启环路过滤: "skip_loop_filter" 值 :0开启,画面质量高,解码开销大,48关闭,画面质量差点,解码开销小3)视屏缩放处理配置//可用参数是ffmpeg/libswscale/options.c中的配置public static final int OPT_CATEGORY_SWS = 3;4)视屏播放配置//所有可选配置在 ff_ffplay_options.h 文件中public static final int OPT_CATEGORY_PLAYER = 4;//常用配置:1、设置是否开启变调"soundtouch" 值为:0或12、是否开启预缓冲,一般直播项目会开启,达到秒开的效果,不过带来了播放丢帧卡顿的体验"packet-buffering"值是1或03、播放重连次数"reconnect" 值是具体重连次数4、最大缓冲大小,单位kb"max-buffer-size",maxCacheSize);5、跳帧处理,放CPU处理较慢时,进行跳帧处理,保证播放流程,画面和声音同步"framedrop" 值是音视屏不同步时跳过的帧数 6、最大fps"max-fps" 值是最大播放帧率的具体值7、设置硬解码方式jkPlayer支持硬解码和软解码。 软解码时不会旋转视频角度这时需要你通过onInfo的what == IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED去获取角度,自己旋转画面。或者开启硬解硬解码,不过硬解码容易造成黑屏无声(硬件兼容问题),下面是设置硬解码相关的代码"mediacodec" 当值为1时表示使用硬解码0表示使用软解吗mediacodec-auto-rotate", 1;"mediacodec-handle-resolution-change", 1;8、SeekTo设置优化"enable-accurate-seek" Seek的策略1表示播放指定时刻,0表示从指定时刻的前一个关键帧位置;