android 基于ijkplayer项目进行的播放器
jjdxm_ijkplayer
项目地址: jjdxm_ijkplayer 简介:基于 ijkplayer 简单的 UI 界面 当前项目是基于 ijkplayer 项目进行的播放器界面 UI 封装。 是一个适用于 Android 的 RTMP 直播推流 SDK,可高度定制化和二次开发。特色是同时支持 H.264 软编/硬编和 AAC 软编/硬编。主要是支持 RIMP、HLS、MP4、M4A 等视频格式的播放。Copyright notice
我在网上写的文章、项目都可以转载,但请注明出处,这是我唯一的要求。当然纯我个人原创的成果被转载了,不注明出处也是没有关系的,但是由我转载或者借鉴了别人的成果的请注明他人的出处,算是对前辈们的一种尊重吧!
虽然我支持写禁止转载的作者,这是他们的成果,他们有这个权利,但我不觉得强行扭转用户习惯会有一个很好的结果。纯属个人的观点,没有特别的意思。可能我是一个版权意识很差的人吧,所以以前用了前辈们的文章、项目有很多都没有注明出处,实在是抱歉!有想起或看到的我都会逐一补回去。
从一开始,就没指望从我写的文章、项目上获得什么回报,一方面是为了自己以后能够快速的回忆起曾经做过的事情,避免重复造轮子做无意义的事,另一方面是为了锻炼下写文档、文字组织的能力和经验。如果在方便自己的同时,对你们也有很大帮助,自然是求之不得的事了。要是有人转载或使用了我的东西觉得有帮助想要打赏给我,多少都行哈,心里却很开心,被人认可总归是件令人愉悦的事情。
站在了前辈们的肩膀上,才能走得更远视野更广。前辈们写的文章、项目给我带来了很多知识和帮助,我没有理由不去努力,没有理由不让自己成长的更好。写出好的东西于人于己都是好的,但是由于本人自身视野和能力水平有限,错误或者不好的望多多指点交流。
项目中如有不同程度的参考借鉴前辈们的文章、项目会在下面注明出处的,纯属为了个人以后开发工作或者文档能力的方便。如有侵犯到您的合法权益,对您造成了困惑,请联系协商解决,望多多谅解哈!若您也有共同的兴趣交流技术上的问题加入交流群 QQ: 548545202
感谢作者tcking、Bilibili,本项目借鉴了GiraffePlayer项目,项目一开始的灵感来源于GiraffePlayer项目,后期做纯粹做了视频播放器的界面的定制,基于ijkplayer项目进行的播放器界面 UI 封装。
Introduction
当前项目是基于ijkplayer项目进行的播放器界面 UI 封装。 是一个适用于 Android 的 RTMP 直播推流 SDK,可高度定制化和二次开发。特色是同时支持 H.264 软编/硬编和 AAC 软编/硬编。主要是支持 RIMP、HLS、MP4、M4A 等视频格式的播放。
Features
- 基于 ijkplayer 封装的视频播放器界面,支持 RTMP , HLS (http & https) , MP4,M4A 等;
- 可根据需求去定制部分界面样式;
- 常用的手势操作左边上下亮度,右边上下声音,左右滑动播放进度调整;
- 支持多种分辨率流的切换播放;
- 播放出错尝试重连;
- 界面裁剪显示样式;
Screenshots
Download
demo apk 下载
Download or grab via Maven:
com.dou361.ijkplayer jjdxm-ijkplayer x.x.x
or Gradle:
compile 'com.dou361.ijkplayer:jjdxm-ijkplayer:x.x.x'
历史版本:
compile 'com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.6'compile 'com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.5'compile 'com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.4'compile 'com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.3'compile 'com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.2'compile 'com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.1'compile 'com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.0'
jjdxm-ijkplayer requires at minimum Java 9 or Android 2.3.
架包的打包引用以及冲突解决
Proguard
根据你的混淆器配置和使用,您可能需要在你的 proguard 文件内配置以下内容:
-keep com.dou361.ijkplayer.** {*;}
AndroidStudio 代码混淆注意的问题
Get Started
step1:
依赖本项目类库
该项目是基于 ijkplayer 项目进行的视频 UI 的二次封装,目前只是默认在:
compile 'com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.5'
中加入了以下依赖:
compile 'tv.danmaku.ijk.media:ijkplayer-java:0.6.0'compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.6.0'
如果你的项目中已经有依赖了 v4 或者 v7 包并且使用的版本不一样可能会造成冲突,可以类似下面的方式进行引入依赖
compile('com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.5') { exclude group: 'com.android.support', module: 'appcompat-v7'}
如果要支持多种 ABI 类型的机型,可以根据需要添加以下依赖:
# required, enough for most devices.compile 'tv.danmaku.ijk.media:ijkplayer-java:0.6.0'compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.6.0'# Other ABIs: optionalcompile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.6.0'compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.6.0' //最小版本 21compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.6.0'compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.6.0' //最小版本 21
ijkplayer 打包不同的 ABI 后,应该是对 EXO 支持才把部分 ABI 的最小版本设置为 21,考虑到部分机型需要 64 的支持,然而项目最小版本又不行改到 21,当前在项目中加入 x86、x86_64、arm64 文件,以下是提供最小版本为 9 的 compile 依赖出来
//对应 ijkplayer 的 compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.6.0'compile 'com.dou361.ijkplayer-armv7a:jjdxm-ijkplayer-armv7a:1.0.0' //对应 ijkplayer 的 compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.6.0'compile 'com.dou361.ijkplayer-armv5:jjdxm-ijkplayer-armv5:1.0.0' //对应 ijkplayer 的 compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.6.0'compile 'com.dou361.ijkplayer-arm64:jjdxm-ijkplayer-arm64:1.0.0' //对应 ijkplayer 的 compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.6.0'compile 'com.dou361.ijkplayer-x86:jjdxm-ijkplayer-x86:1.0.0' //对应 ijkplayer 的 compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.6.0'compile 'com.dou361.ijkplayer-x86_64:jjdxm-ijkplayer-x86_64:1.0.0'
demo 中原来的 jniLibs 目录下的文件,已经移除,都是使用上面的依赖方式,如果网络环境差 compile 不下来,可以到项目的 release 目录中去下载
step2:
多种分辨率流切换的案例,例如播放器的标清、高清、超清、720P 等。
1.简单的播放器实现
rootView = getLayoutInflater().from(this).inflate(R.layout.simple_player_view_player, null);setContentView(rootView);String url = "http://9890.vod.myqcloud.com/9890_9c1fa3e2aea011e59fc841df10c92278.f20.mp4";player = new PlayerView(this,rootView) .setTitle("什么") .setScaleType(PlayStateParams.fitparent) .hideMenu(true) .forbidTouch(false) .showThumbnail(new OnShowThumbnailListener() { @Override public void onShowThumbnail(ImageView ivThumbnail) { Glide.with(mContext) .load("http://pic2.nipic.com/20090413/406638_125424003_2.jpg") .placeholder(R.color.cl_default) .error(R.color.cl_error) .into(ivThumbnail); } }) .setPlaySource(url) .startPlay();
2.多种不同的分辨率流的播放器实现
在布局中使用 simple_player_view_player.xml 布局
代码中创建一个播放器对象
/**播放资源*/ist list = new ArrayList();String url1 = "http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4";String url2 = "http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f30.mp4";VideoijkBean m1 = new VideoijkBean();m1.setStream("标清");m1.setUrl(url1);VideoijkBean m2 = new VideoijkBean();m2.setStream("高清");m2.setUrl(url2);list.add(m1);list.add(m2);/**播放器*/rootView = getLayoutInflater().from(this).inflate(你的布局, null);setContentView(rootView);player = new PlayerView(this,rootView) .setTitle("什么") .setScaleType(PlayStateParams.fitparent) .hideMenu(true) .forbidTouch(false) .showThumbnail(new OnShowThumbnailListener() { @Override public void onShowThumbnail(ImageView ivThumbnail) { /**加载前显示的缩略图*/ Glide.with(mContext) .load("http://pic2.nipic.com/20090413/406638_125424003_2.jpg") .placeholder(R.color.cl_default) .error(R.color.cl_error) .into(ivThumbnail); } }) .setPlaySource(list) .startPlay();
step3:
配置生命周期方法,为了让播放器同步 Activity 生命周期,建议以下方法都去配置,注释的代码,主要作用是播放时屏幕常亮和暂停其它媒体的播放。
@Overrideprotected void onPause() { super.onPause(); if (player != null) { player.onPause(); } /**demo 的内容,恢复系统其它媒体的状态*/ //MediaUtils.muteAudioFocus(mContext, true);}@Overrideprotected void onResume() { super.onResume(); if (player != null) { player.onResume(); } /**demo 的内容,暂停系统其它媒体的状态*/ MediaUtils.muteAudioFocus(mContext, false); /**demo 的内容,激活设备常亮状态*/ //if (wakeLock != null) { // wakeLock.acquire(); //}}@Overrideprotected void onDestroy() { super.onDestroy(); if (player != null) { player.onDestroy(); }}@Overridepublic void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (player != null) { player.onConfigurationChanged(newConfig); }}@Overridepublic void onBackPressed() { if (player != null && player.onBackPressed()) { return; } super.onBackPressed(); /**demo 的内容,恢复设备亮度状态*/ //if (wakeLock != null) { // wakeLock.release(); //}}
More Actions
1.视频界面裁剪设置,可通过方法 setScaleType(int type)去设置
1. PlayStateParams.fitParent:可能会剪裁,保持原视频的大小,显示在中心,当原视频的大小超过 view 的大小超过部分裁剪处理2. PlayStateParams.fillParent:可能会剪裁,等比例放大视频,直到填满 View 为止,超过 View 的部分作裁剪处理3. PlayStateParams.wrapcontent:将视频的内容完整居中显示,如果视频大于 view,则按比例缩视频直到完全显示在 view 中4. PlayStateParams.fitXY:不剪裁,非等比例拉伸画面填满整个 View5. PlayStateParams.f16_9:不剪裁,非等比例拉伸画面到 16:9,并完全显示在 View 中6. PlayStateParams.f4_3:不剪裁,非等比例拉伸画面到 4:3,并完全显示在 View 中
2.自定义视频界面,可以复制以下布局内容到自己的项目中,注意已有的 id 不能修改或删除,可以增加 view,可以对以下布局内容调整显示位置或者自行隐藏
<?xml version="1.0" encoding="utf-8"?>
3.播放器 PlayerView 对象的方法如下:
PlayerView(Activity activity)//生命周期方法回调PlayerView onPause()PlayerView onResume()PlayerView onDestroy()PlayerView onConfigurationChanged(final Configuration newConfig)boolean onBackPressed()//显示缩略图PlayerView showThumbnail(OnShowThumbnailListener onShowThumbnailListener)//设置播放信息监听回调PlayerView setOnInfoListener(IMediaPlayer.OnInfoListener onInfoListener)//设置播放器中的返回键监听PlayerView setPlayerBackListener(OnPlayerBackListener listener)//设置控制面板显示隐藏监听PlayerView setOnControlPanelVisibilityChangListenter(OnControlPanelVisibilityChangeListener listener)//百分比显示切换PlayerView toggleAspectRatio()//设置播放区域拉伸类型PlayerView setScaleType(int showType)//旋转角度PlayerView setPlayerRotation()//旋转指定角度PlayerView setPlayerRotation(int rotation)//设置播放地址包括视频清晰度列表对应地址列表PlayerView setPlaySource(List list)//设置播放地址单个视频 VideoijkBeanPlayerView setPlaySource(VideoijkBean videoijkBean)//设置播放地址单个视频地址时带流名称PlayerView setPlaySource(String stream, String url)//设置播放地址单个视频地址时PlayerView setPlaySource(String url)//自动播放PlayerView autoPlay(String path)//开始播放PlayerView startPlay()//设置视频名称PlayerView setTitle(String title)//选择要播放的流PlayerView switchStream(int index)//暂停播放PlayerView pausePlay()//停止播放PlayerView stopPlay()//设置播放位置PlayerView seekTo(int playtime)//获取当前播放位置int getCurrentPosition()//获取视频播放总时长long getDuration()//设置 2/3/4/5G 和 WiFi 网络类型提示 true 为进行 2/3/4/5G 网络类型提示 false 不进行网络类型提示PlayerView setNetWorkTypeTie(boolean isGNetWork)//是否仅仅为全屏PlayerView setOnlyFullScreen(boolean isFull)//设置是否禁止双击PlayerView setForbidDoulbeUp(boolean flag)//当前播放的是否是直播boolean isLive()//是否禁止触摸PlayerView forbidTouch(boolean forbidTouch)//隐藏所有状态界面PlayerView hideAllUI()获取顶部控制 barviewView getTopBarView()//获取底部控制 barviewView getBottonBarView()//获取旋转 viewImageView getRationView()//获取返回 viewImageView getBackView()//获取菜单 viewImageView getMenuView()//获取全屏按钮 viewImageView getFullScreenView()//获取底部 bar 的播放 viewImageView getBarPlayerView()//获取中间的播放 viewImageView getPlayerView()//隐藏返回键,true 隐藏,false 为显示PlayerView hideBack(boolean isHide)//隐藏菜单键,true 隐藏,false 为显示PlayerView hideMenu(boolean isHide)//隐藏分辨率按钮,true 隐藏,false 为显示PlayerView hideSteam(boolean isHide)//隐藏旋转按钮,true 隐藏,false 为显示PlayerView hideRotation(boolean isHide)//隐藏全屏按钮,true 隐藏,false 为显示PlayerView hideFullscreen(boolean isHide)//隐藏中间播放按钮,ture 为隐藏,false 为不做隐藏处理,但不是显示PlayerView hideCenterPlayer(boolean isHide)//显示或隐藏操作面板PlayerView operatorPanl()//全屏切换PlayerView toggleFullScreen()//设置自动重连的模式或者重连时间,isAuto true 出错重连,false 出错不重连,connectTime 重连的时间setAutoReConnect(boolean isAuto, int connectTime)//进度条和时长显示的方向切换PlayerView toggleProcessDurationOrientation()//设置进度条和时长显示的方向,默认为上下显示,PlayStateParams.PROCESS_PORTRAIT 为上下显示 PlayStateParams.PROCESS_LANDSCAPE 为左右显示 PlayStateParams.PROCESS_CENTER 为中间两边样式setProcessDurationOrientation(int portrait)//显示菜单设置showMenu()//获取界面方向int getScreenOrientation()//显示加载网速PlayerView setShowSpeed(boolean isShow)//是否隐藏 topbar,true 为隐藏,false 为不隐藏,但不一定是显示PlayerView hideHideTopBar(boolean isHide)//是否隐藏 bottonbar,true 为隐藏,false 为不隐藏,但不一定是显示PlayerView hideBottonBar(boolean isHide)//是否隐藏上下 bar,true 为隐藏,false 为不隐藏,但不一定是显示PlayerView hideControlPanl(boolean isHide)//设置是否禁止隐藏 bar,优先级低于 hideControlPanlPlayerView setForbidHideControlPanl(boolean flag)
4.全屏隐藏虚拟按键方法
参考 HPlayerActivity 类,获取 Activity 的根目录
main = getLayoutInflater().from(this).inflate(R.layout.activity_h, null);
然在在 oncreate()方法中设置监听
/**虚拟按键的隐藏方法*/ main.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //比较 Activity 根布局与当前布局的大小 int heightDiff = main.getRootView().getHeight() - main.getHeight(); if (heightDiff > 100) { //大小超过 100 时,一般为显示虚拟键盘事件 main.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } else { //大小小于 100 时,为不显示虚拟键盘或虚拟键盘隐藏 main.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); } } });
5.半屏视频,横竖屏切换时不填满问题
1.确保 Activity 中调用生命周期方法
@Overridepublic void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (player != null) { player.onConfigurationChanged(newConfig); }}
2.确保清单文件中配置属性
android:configChanges="orientation|keyboardHidden|screenSize" android:screenOrientation="portrait"
例如
关于定制
隐藏部分不想要的界面
//隐藏返回键,true 隐藏,false 为显示PlayerView hideBack(boolean isHide)//隐藏菜单键,true 隐藏,false 为显示PlayerView hideMenu(boolean isHide)//隐藏分辨率按钮,true 隐藏,false 为显示PlayerView hideSteam(boolean isHide)//隐藏旋转按钮,true 隐藏,false 为显示PlayerView hideRotation(boolean isHide)//隐藏全屏按钮,true 隐藏,false 为显示PlayerView hideFullscreen(boolean isHide)//隐藏中间播放按钮,ture 为隐藏,false 为不做隐藏处理,但不是显示PlayerView hideCenterPlayer(boolean isHide)
加载时显示网速
默认加载时不显示网速,可以通过 setShowSpeed(boolean isShow)设置加载时是否需要显示,true 为显示,false 为不显示
播放器底部 bar 播放进度条样式定制
默认的进度样式是竖屏为上下样式,即进度条在播放时长的上面,横屏为左右样式,即进度条在播放时长的中间。样式定制主要是两个方法搭配使用 toggleProcessDurationOrientation 方法和 setProcessDurationOrientation 方法,横竖屏切换 2 中情况,和 3 种进度条样式
/**上下样式*/PlayStateParams.PROCESS_PORTRAIT/**左右样式*/PlayStateParams.PROCESS_LANDSCAPE/**中间两边样式*/PlayStateParams.PROCESS_CENTER
总共有 2 的 3 次方中样式,下面只罗列几种样式
1.横竖屏都为上下样式
rootView = getLayoutInflater().from(this).inflate(你的布局, null);setContentView(rootView);player = new PlayerView(this,rootView) { @Override public PlayerView toggleProcessDurationOrientation() { return setProcessDurationOrientation(PlayStateParams.PROCESS_PORTRAIT); } } .setTitle("什么") .setProcessDurationOrientation(PlayStateParams.PROCESS_PORTRAIT) .setScaleType(PlayStateParams.fitparent) .forbidTouch(false) .hideCenterPlayer(true) .setPlaySource(list) .startPlay();
2.横竖屏都为左右样式
rootView = getLayoutInflater().from(this).inflate(你的布局, null);setContentView(rootView);player = new PlayerView(this,rootView) { @Override public PlayerView toggleProcessDurationOrientation() { return setProcessDurationOrientation(PlayStateParams.PROCESS_LANDSCAPE); } } .setTitle("什么") .setProcessDurationOrientation(PlayStateParams.PROCESS_LANDSCAPE) .setScaleType(PlayStateParams.fitparent) .forbidTouch(false) .hideCenterPlayer(true) .setPlaySource(list) .startPlay();
3.横屏为上下样式竖屏为左右样式
rootView = getLayoutInflater().from(this).inflate(你的布局, null);setContentView(rootView);player = new PlayerView(this,rootView) { @Override public PlayerView toggleProcessDurationOrientation() { return setProcessDurationOrientation(getScreenOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE?PlayStateParams.PROCESS_LANDSCAPE:PlayStateParams.PROCESS_PORTRAIT); } } .setTitle("什么") .setProcessDurationOrientation(PlayStateParams.PROCESS_LANDSCAPE) .setScaleType(PlayStateParams.fitparent) .forbidTouch(false) .hideCenterPlayer(true) .setPlaySource(list) .startPlay();
4.横屏为左右样式竖屏为上下样式
rootView = getLayoutInflater().from(this).inflate(你的布局, null);setContentView(rootView);player = new PlayerView(this,rootView) { @Override public PlayerView toggleProcessDurationOrientation() { return setProcessDurationOrientation(getScreenOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT?PlayStateParams.PROCESS_PORTRAIT:PlayStateParams.PROCESS_LANDSCAPE); } } .setTitle("什么") .setProcessDurationOrientation(PlayStateParams.PROCESS_CENTER) .setScaleType(PlayStateParams.fitparent) .forbidTouch(false) .hideCenterPlayer(true) .setPlaySource(list) .startPlay();
5.横屏为左右样式竖屏为中间两边样式
rootView = getLayoutInflater().from(this).inflate(你的布局, null);setContentView(rootView);player = new PlayerView(this,rootView) { @Override public PlayerView toggleProcessDurationOrientation() { return setProcessDurationOrientation(getScreenOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT?PlayStateParams.PROCESS_CENTER:PlayStateParams.PROCESS_LANDSCAPE); } } .setTitle("什么") .setProcessDurationOrientation(PlayStateParams.PROCESS_CENTER) .setScaleType(PlayStateParams.fitparent) .forbidTouch(false) .hideCenterPlayer(true) .setPlaySource(list) .startPlay();
3.ijkplayer 封装的视频播放信息返回码监听,可以通过 setOnInfoListener 去监听
/* * Do not change these values without updating their counterparts in native */int MEDIA_INFO_UNKNOWN = 1;//未知信息int MEDIA_INFO_STARTED_AS_NEXT = 2;//播放下一条int MEDIA_INFO_VIDEO_RENDERING_START = 3;//视频开始整备中int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700;//视频日志跟踪int MEDIA_INFO_BUFFERING_START = 701;//开始缓冲中int MEDIA_INFO_BUFFERING_END = 702;//缓冲结束int MEDIA_INFO_NETWORK_BANDWIDTH = 703;//网络带宽,网速方面int MEDIA_INFO_BAD_INTERLEAVING = 800;//int MEDIA_INFO_NOT_SEEKABLE = 801;//不可设置播放位置,直播方面int MEDIA_INFO_METADATA_UPDATE = 802;//int MEDIA_INFO_TIMED_TEXT_ERROR = 900;int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901;//不支持字幕int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;//字幕超时int MEDIA_INFO_VIDEO_INTERRUPT= -10000;//数据连接中断int MEDIA_INFO_VIDEO_ROTATION_CHANGED = 10001;//视频方向改变int MEDIA_INFO_AUDIO_RENDERING_START = 10002;//音频开始整备中int MEDIA_ERROR_UNKNOWN = 1;//未知错误int MEDIA_ERROR_SERVER_DIED = 100;//服务挂掉int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200;//数据错误没有有效的回收int MEDIA_ERROR_IO = -1004;//IO 错误int MEDIA_ERROR_MALFORMED = -1007;int MEDIA_ERROR_UNSUPPORTED = -1010;//数据不支持int MEDIA_ERROR_TIMED_OUT = -110;//数据超时
ChangeLog
2016.09.05 修改支持非 Activity 中使用当前播放器 view,例如 fragment、holder 之类使用,添加直播地址获取,提供可观看案例(如直播地址有不妥的地方可联系删除,多有得罪啦) 遗留问题: 触摸时,隐藏动作取消 触摸时,进度条面会有点共用 直播停止开始卡帧 手动换源卡帧 直播判断问题 进度条隐藏提取方法出来 修改初始化方法 本地视频播放问题 播放加载状态的监听问题比如说链接失效,请求超时,断流了,断网了之类的 缓冲好内容使用 seekto 之后还是需要重新缓冲 乐视手机 点开亮度为 0
2016.08.30 修复播放时长为零问题;修复使用拉伸方法横屏方向不起效问题;修改最小支持版本为 9;添加了 SO 文件的最小版本为 9 的类库;添加 VideoijkBean 比较方法,可以比对视频对象是不是同一个;添加横竖屏配置说明;添加隐藏虚拟按键的方法。
2016.08.26 1.0.5 添加上下操作工具栏的隐藏定制,主要是 hideControlPanl,hideHideTopBar 和 hideBottonBar 方法控制
2016.08.26 1.0.4 打包修复播放进度样式点击返回键不起效
2016.08.25 1.0.3 添加视频播放进度条样式,添加菜单设置
2016.08.24 1.0.2 修复播放出错点击没有反应,这是修改旋转视频方向是造成的 bug,当前默认为 5 秒无操作自动重试,修改加载进度条的显示时间,之前是加载回调整备中才显示,改为点击加载立即显示,新增修改自动重试的方式和重试的时间
2016.08.20 修复视频进入后台继续播放,切换视频源是画面卡住等问题
2016.08.20 1.0.1 修复点击播放、点击暂停、再点击播放时,加载进度条一直显示问题;修复第一次打开播放器,触摸视频界面,视频重新播放问题;恢复视频拖动条默认样式,修复显示不完整问题;添加对外操作的 view,可通过 getxxxView()方法获得;添加了 PlayerView 对象的方法及说明,可链式开发。
About Author
个人网站:http://www.dou361.com
GitHub:jjdxmashl
QQ:316988670
交流 QQ 群:548545202
更多相关文章
- android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K
- Android自动化测试学习之robotium笔记
- Android(安卓)Studio中Git的配置及协同开发
- ubuntu下整合eclipse和javah生成jni头文件开发android的native程
- 自定义 Android(安卓)对话框 (AlertDialog) 的样式
- Ubantu云服务器上配置Gradle 命令自动打包Android(安卓)Studio
- android studio 各种设置以及常见问题
- N 个小程序开发视频免费下载
- Android——自定义Toast(含源码下载)