RTMP视频播放器

article/2025/11/6 19:12:55

感谢作者tcking、Bilibili,本项目借鉴了GiraffePlayer项目,项目一开始的灵感来源于GiraffePlayer项目,后期做纯粹做了视频播放器的界面的定制,基于ijkplayer项目进行的播放器界面UI封装。

简介

当前项目是基于ijkplayer项目进行的播放器界面UI封装。
是一个适用于 Android 的 RTMP 直播推流 SDK,可高度定制化和二次开发。特色是同时支持 H.264 软编/硬编和 AAC 软编/硬编。主要是支持RIMP、HLS、MP4、M4A等视频格式的播放。
项目地址:http://www.github.com/jjdxmashl/jjdxm_ijkplayer

特性

  1. 基于ijkplayer封装的视频播放器界面,支持 RTMP , HLS (http & https) , MP4,M4A 等;
  2. 可根据需求去定制部分界面样式;
  3. 常用的手势操作左边上下亮度,右边上下声音,左右滑动播放进度调整;
  4. 支持多种分辨率流的切换播放;
  5. 播放出错尝试重连;
  6. 界面裁剪显示样式;

截图







demo下载

demo apk下载

代码混淆

根据你的混淆器配置和使用,您可能需要在你的proguard文件内配置以下内容:

-keep com.dou361.ijkplayer.** {
*;
}

快速开始

step1:

依赖本项目类库

该项目已经打包到jcenter中心了,可以通过compile命令直接依赖,在主程序目录build.gradle中,添加以下代码:

 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'
compile 'com.android.support:support-v7:23.3.0'

如果你的项目中已经有依赖了v4或者v7包并且使用的版本不一样可能会造成冲突,可以类似下面的方式进行引入依赖

compile('com.dou361.ijkplayer:jjdxm-ijkplayer:1.0.5') {exclude group: 'com.android.support', module: 'appcompat-v7'
}

更多关于冲突问题可看这里:架包的打包引用以及冲突解决

该项目是基于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'

如果要支持多种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: optional
compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.6.0'
compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.6.0'
compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.6.0'
compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.6.0'

step2:

多种分辨率流切换的案例,例如播放器的标清、高清、超清、720P等。

1.简单的播放器实现

setContentView(R.layout.simple_player_view_player);
String url = "http://9890.vod.myqcloud.com/9890_9c1fa3e2aea011e59fc841df10c92278.f20.mp4";
player = new PlayerView(this).setTitle("什么").setScaleType(PlayStateParams.fitparent).hideMenu(true).forbidTouch(false).showThumbnail(new OnShowThumbnailListener() {@Overridepublic 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布局

<includelayout="@layout/simple_player_view_player"android:layout_width="match_parent"android:layout_height="180dp"/>

代码中创建一个播放器对象

/**播放资源*/
ist<VideoijkBean> list = new ArrayList<VideoijkBean>();
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);
/**播放器*/
player = new PlayerView(this).setTitle("什么").setScaleType(PlayStateParams.fitparent).hideMenu(true).forbidTouch(false).showThumbnail(new OnShowThumbnailListener() {@Overridepublic 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生命周期,建议以下方法都去配置,注释的代码,主要作用是播放时屏幕常亮和暂停其它媒体的播放。

 @Override
protected void onPause() {super.onPause();if (player != null) {player.onPause();}/**demo的内容,恢复系统其它媒体的状态*///MediaUtils.muteAudioFocus(mContext, true);
}@Override
protected void onResume() {super.onResume();if (player != null) {player.onResume();}/**demo的内容,暂停系统其它媒体的状态*/MediaUtils.muteAudioFocus(mContext, false);/**demo的内容,激活设备常亮状态*///if (wakeLock != null) {//    wakeLock.acquire();//}
}@Override
protected void onDestroy() {super.onDestroy();if (player != null) {player.onDestroy();}
}@Override
public void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);if (player != null) {player.onConfigurationChanged(newConfig);}
}@Override
public void onBackPressed() {if (player != null && player.onBackPressed()) {return;}super.onBackPressed();/**demo的内容,恢复设备亮度状态*///if (wakeLock != null) {//    wakeLock.release();//}
}

更多UI样式的设置

1.视频界面裁剪设置,可通过方法setScaleType(int type)去设置

1). PlayStateParams.fitParent:可能会剪裁,保持原视频的大小,显示在中心,当原视频的大小超过view的大小超过部分裁剪处理
(2). PlayStateParams.fillParent:可能会剪裁,等比例放大视频,直到填满View为止,超过View的部分作裁剪处理
(3). PlayStateParams.wrapcontent:将视频的内容完整居中显示,如果视频大于view,则按比例缩视频直到完全显示在view中
(4). PlayStateParams.fitXY:不剪裁,非等比例拉伸画面填满整个View
(5). PlayStateParams.f16_9:不剪裁,非等比例拉伸画面到16:9,并完全显示在View中
(6). PlayStateParams.f4_3:不剪裁,非等比例拉伸画面到4:3,并完全显示在View中

2.播放器底部bar播放进度条样式定制
默认的进度样式是竖屏为上下样式,即进度条在播放时长的上面,横屏为左右样式,即进度条在播放时长的中间。样式定制主要是两个方法搭配使用toggleProcessDurationOrientation方法和setProcessDurationOrientation方法,横竖屏切换2中情况,和3种进度条样式

/**上下样式*/
PlayStateParams.PROCESS_PORTRAIT
/**左右样式*/
PlayStateParams.PROCESS_LANDSCAPE
/**中间两边样式*/
PlayStateParams.PROCESS_CENTER

总共有2的3次方中样式,下面只罗列几种样式

(1).横竖屏都为上下样式

player = new PlayerView(this) {@Overridepublic PlayerView toggleProcessDurationOrientation() {return setProcessDurationOrientation(PlayStateParams.PROCESS_PORTRAIT);}}.setTitle("什么").setProcessDurationOrientation(PlayStateParams.PROCESS_PORTRAIT).setScaleType(PlayStateParams.fitparent).forbidTouch(false).hideCenterPlayer(true).setPlaySource(list).startPlay();

(2).横竖屏都为左右样式

player = new PlayerView(this) {@Overridepublic PlayerView toggleProcessDurationOrientation() {return setProcessDurationOrientation(PlayStateParams.PROCESS_LANDSCAPE);}}.setTitle("什么").setProcessDurationOrientation(PlayStateParams.PROCESS_LANDSCAPE).setScaleType(PlayStateParams.fitparent).forbidTouch(false).hideCenterPlayer(true).setPlaySource(list).startPlay();

(3).横屏为上下样式竖屏为左右样式

player = new PlayerView(this) {@Overridepublic 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).横屏为左右样式竖屏为上下样式

player = new PlayerView(this) {@Overridepublic 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).横屏为左右样式竖屏为中间两边样式

player = new PlayerView(this) {@Overridepublic 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.隐藏部分不想要的界面

//隐藏返回键,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)

4.视频移动流量是播放提醒

//设置2/3/4/5G和WiFi网络类型提示 true为进行2/3/4/5G网络类型提示 false 不进行网络类型提示
PlayerView setNetWorkTypeTie(boolean isGNetWork)

5.视频加载前显示缩略图

player.showThumbnail(new OnShowThumbnailListener() {@Overridepublic 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);}})

6.默认显示上下操作栏bar

//设置是否禁止隐藏bar,true为一直显示,false为点击可以隐藏或显示
PlayerView setForbidHideControlPanl(boolean flag)

7.设置播放出错后尝试重连的方式和重连的时间

//设置自动重连的模式或者重连时间,isAuto true 出错重连,false出错不重连,connectTime重连的时间
setAutoReConnect(boolean isAuto, int connectTime)

8.视频界面的旋转,当前默认使用setPlayerRotation方法为90、270、0轮询切换,如果需要指定角度旋转可以使用setPlayerRotation方法

//旋转角度
PlayerView setPlayerRotation()
//旋转指定角度
PlayerView setPlayerRotation(int rotation)

10.自定义视频界面,可以复制以下布局内容到自己的项目中,注意已有的id不能修改或删除,可以增加view,可以对以下布局内容调整显示位置或者自行隐藏

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutandroid:id="@+id/app_video_box"xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/black"android:orientation="vertical"><com.dou361.ijkplayer.widget.IjkVideoViewandroid:id="@+id/video_view"android:layout_width="match_parent"android:layout_height="match_parent"/><LinearLayoutandroid:id="@+id/ll_bg"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/black"android:orientation="vertical"><!-- 封面显示--><ImageViewandroid:id="@+id/iv_trumb"android:layout_width="match_parent"android:layout_height="match_parent"android:scaleType="fitXY"android:visibility="visible"/></LinearLayout><!--重新播放--><LinearLayoutandroid:id="@+id/app_video_replay"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#33000000"android:gravity="center"android:orientation="vertical"android:visibility="gone"><!-- 播放状态--><TextViewandroid:id="@+id/app_video_status_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/small_problem"android:textColor="@android:color/white"android:textSize="14dp"/><ImageViewandroid:id="@+id/app_video_replay_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_marginTop="8dp"android:src="@drawable/simple_player_circle_outline_white_36dp"/></LinearLayout><!-- 网络提示--><LinearLayoutandroid:id="@+id/app_video_netTie"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#33000000"android:gravity="center"android:orientation="vertical"android:visibility="gone"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginBottom="8dp"android:gravity="center"android:paddingLeft="8dp"android:paddingRight="8dp"android:text="您正在使用移动网络播放视频\n可能产生较高流量费用"android:textColor="@android:color/white"/><TextViewandroid:id="@+id/app_video_netTie_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/simple_player_btn"android:gravity="center"android:paddingLeft="8dp"android:paddingRight="8dp"android:text="继续"android:textColor="@android:color/white"/></LinearLayout><!--加载中--><LinearLayoutandroid:id="@+id/app_video_loading"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"android:visibility="gone"><ProgressBarandroid:layout_width="50dp"android:layout_height="50dp"android:indeterminateBehavior="repeat"android:indeterminateOnly="true"/><TextViewandroid:id="@+id/app_video_speed"android:layout_width="wrap_content"android:layout_marginTop="4dp"android:layout_height="wrap_content"android:gravity="center"android:visibility="gone"android:text="188Kb/s"android:textColor="@android:color/white"/></LinearLayout><!-- 中间触摸提示--><includelayout="@layout/simple_player_touch_gestures"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"/><!-- 顶部栏--><include layout="@layout/simple_player_topbar"/><!-- 底部栏--><includelayout="@layout/simple_player_controlbar"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"/><!--声音亮度控制--><LinearLayoutandroid:id="@+id/simple_player_settings_container"android:layout_width="250dp"android:layout_height="match_parent"android:layout_alignParentLeft="true"android:background="#80000000"android:gravity="center_vertical"android:orientation="vertical"android:visibility="visible"><LinearLayoutandroid:id="@+id/simple_player_volume_controller_container"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:orientation="horizontal"><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@drawable/qcloud_player_icon_audio_vol_mute"/><SeekBarandroid:id="@+id/simple_player_volume_controller"style="?android:attr/progressBarStyleHorizontal"android:layout_width="150dp"android:layout_height="wrap_content"/><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@drawable/qcloud_player_icon_audio_vol"/></LinearLayout><LinearLayoutandroid:id="@+id/simple_player_brightness_controller_container"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:gravity="center"android:orientation="horizontal"><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:padding="5dp"android:src="@drawable/qcloud_player_icon_brightness"/><SeekBarandroid:id="@+id/simple_player_brightness_controller"style="?android:attr/progressBarStyleHorizontal"android:layout_width="150dp"android:layout_height="wrap_content"/><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@drawable/qcloud_player_icon_brightness"/></LinearLayout></LinearLayout><!--分辨率选择--><LinearLayoutandroid:id="@+id/simple_player_select_stream_container"android:layout_width="150dp"android:layout_height="match_parent"android:layout_alignParentRight="true"android:background="#80000000"android:gravity="center_vertical"android:visibility="gone"><ListViewandroid:id="@+id/simple_player_select_streams_list"android:layout_width="150dp"android:layout_height="wrap_content"/></LinearLayout><ImageViewandroid:id="@+id/play_icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:layout_marginTop="8dp"android:src="@drawable/simple_player_center_play"/></RelativeLayout>

11.播放器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<VideoijkBean> list)
//设置播放地址单个视频VideoijkBean
PlayerView 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)
//设置是否禁止隐藏bar
PlayerView setForbidHideControlPanl(boolean flag)
//当前播放的是否是直播
boolean isLive()
//是否禁止触摸
PlayerView forbidTouch(boolean forbidTouch)
//隐藏所有状态界面
PlayerView hideAllUI()
获取顶部控制barview
View getTopBarView()
//获取底部控制barview
View getBottonBarView()
//获取旋转view
ImageView getRationView()
//获取返回view
ImageView getBackView()
//获取菜单view
ImageView getMenuView()
//获取全屏按钮view
ImageView getFullScreenView()
//获取底部bar的播放view
ImageView getBarPlayerView()
//获取中间的播放view
ImageView 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)

12.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;//数据超时

项目地址:http://www.github.com/jjdxmashl/jjdxm_ijkplayer



文/jjdxmashl(简书作者)
原文链接:http://www.jianshu.com/p/6c938df18413
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

http://chatgpt.dhexx.cn/article/m2NaanRL.shtml

相关文章

从零开发一款Android RTMP播放器

1. 背景介绍 15年移动端直播应用火起来的时候&#xff0c;主要的直播协议是RTMP&#xff0c;多媒体服务以Adobe的AMS、wowza、Red5、crtmpserver、nginx rtmp module等&#xff0c;后面过长RTMP服务SRS开始流行。Android端播放器主要以开始以EXOPlayer播放HLS&#xff0c;但是…

rtsp+rtmp多路网页播放

一、前言 之前博主有写过 一篇博文&#xff0c;讲的是使用videojs在谷歌浏览器网页上播放rtmp流媒体&#xff0c;具体可参考我之前的博客&#xff1a;videojshlsrtmp网页播放 - 蛋片鸡 - 博客园 最近又开始研究了一下网页播放流媒体&#xff0c;在这里我主要补充一些播放rtmp、…

低延时极简RTMP播放器

RtmpPlaySdk简介 近期将项目上RTMP播放相关功能进行打包整理&#xff0c;实现了一款低延时的极简接口RTMP播放器&#xff08;Windows版和Android版&#xff09;。市面上的RTMP播放器较多&#xff0c;有开源的ijkplayer及其衍生品&#xff0c;也有收费的功能繁多的播放器&#…

rtmp 点播系统之播放器篇

rtmp (Real Time Media Protocal) ,是实时流媒体协议,由Adobe公司提出,属于半开放的协议。此协议基于flash平台的音视频点播协议。 音视的点播系统分为两部分,分别为客户端和服务端。在本文中我会先讲解如何实现一个简单的rtmp播放器。至于rtmp服务器的实现,会在下文中分析…

pgsql 使用技巧

1.CASCADE 级联删除&#xff0c;如果表或模式或数据库有序列、分区相关 依赖时&#xff0c;需要修改表或模式或数据库&#xff0c;则使用它 DROP SCHEMA viid_facestatic CASCADE 2.pgsql隐藏字段ctid&#xff0c;一般用于去重 3. pg 表自连接使用场景 3.1 有一张卡口表 求…

pgsql

这里写目录标题 pgpool安装pgsql流复制备份与恢复客户端验证服务器设置及操作服务器配置监控数据活动 PostgreSQL是以加州大学伯克利分校计算机系开发的 POSTGRES, Version 4.2为基础的对象关系型数据库管理系统(ORDBMS)。 PostgreSQL是最初伯克利代码的一个开放源码的继承者。…

pgsql基本操作

pgsql基本操作 1. 修改postgresql.conf postgresql.conf存放位置在/etc/postgresql/9.x/main下&#xff0c;这里的x取决于你安装PostgreSQL的版本号&#xff0c;编辑或添加下面一行&#xff0c;使PostgreSQL可以接受来自任意IP的连接请求。 listen_addresses *2. 修改pg_hb…

pgsql常用sql和函数

常用pgsql -- 列出所有schema select * from information_schema.schemata; -- Schema下所有表 select * from pg_tables where schemaname query_db and tablename in(port,device,res_carry_business,hardware,shelf,device_hardware_relation); -- Schema下所有索引 select…

PGSQL大小写敏感总结

PGSQL大小写敏感总结 由于PGSQL使用会出现大小写敏感的问题&#xff0c;所以在设置字段名字的时候&#xff0c;如果字段名需要大写需要加上""号来表示&#xff0c;该字段需要大写 公司业务需要我使用PGSQL创建自增主键&#xff0c;我在使用 nextval() 绑定创建的序列…

PGSQL常用操作

0. 启动pgsl数据库 pg_ctl -D /xx/pgdata start 回到顶部 1. 查看pgsl版本 pg_ctl --version 回到顶部 1. 命令行登录数据库 1 psql -U username -d dbname -h hostip -p port 回到顶部 2. 列出所有数据库 \l 回到顶部 3. 切换数据库 1 \c dbname 回到顶部 …

PL/pgSQL

1.简介 L/pgSQL是一种用于PostgreSQL数据库系统的可载入的过程语言。 可以被用来创建函数和触发器过程对SQL语言增加控制结构可以执行复杂计算继承所有用户定义类型、函数和操作符可以被定义为受服务器信任便于使用 [1]使用PL/pgSQL的优点 SQL 是一种查询语言&#xff0c;可…

Windows 10 安装配置连接PostgreSQL教程

Windows 10 安装配置连接PostgreSQL教程 1.1 PostgreSQL 下载1.2 配置环境变量1.3 PostgreSQL 初始化1.4 创建postgres用户1.5 启动postgresql1.6 客户端连接测试1.6.1 SQL Shell (psql)命令行连接测试1.6.2 客户端 pdAdmin 4 连接测试1.6.3 客户端Navicat Permium 连接测试 1.…

Spring原理-IOC控制反转

spring相关文章 Spring原理-IOC控制反转 Spring框架七大核心模块 Spring Beans原理–bean生命周期 一、Spring概述 1、 定义 Spring是一个轻量级Java开发框架&#xff0c;最早有Rod Johnson创建&#xff0c;目的是为了解决企业级应用开发复杂性。它是一个分层的JavaSE/Java…

依赖倒置和控制反转

依赖倒置 定义 依赖反转原则&#xff08;Dependency inversion principle&#xff0c;DIP&#xff09;是指一种特定的解耦形式&#xff0c;使得高层次的类不依赖于低层次的类的实现细节&#xff0c;依赖关系被颠倒&#xff08;反转&#xff09;&#xff0c;从而使得低层次类依…

Inversion of Control (IOC)控制反转 有什么好处

要了解控制反转( Inversion of Control ), 我觉得有必要先了解软件设计的一个重要思想&#xff1a;依赖倒置原则&#xff08;Dependency Inversion Principle &#xff09;。 什么是依赖倒置原则&#xff1f;假设我们设计一辆汽车&#xff1a;先设计轮子&#xff0c;然后根据…

Spring学习:IOC控制反转

一、Spring概述&#xff1a; Spring是一个开源框架&#xff0c;其存在的根本使命就是简化JAVA开发。为了降低JAVA开发的复杂性&#xff0c;Spring采取了以下四种关键策略&#xff1a; 基于POJO的最轻量级和最小侵入性编程&#xff1b;通过依赖注入和面向接口实现松耦合&#x…

控制反转(IOC)简介

IOC是Inversion of Control的缩写&#xff0c;多数书籍翻译成“控制反转”&#xff0c;还有些书籍翻译成为“控制反向”或者“控制倒置”。 1996年&#xff0c;Michael Mattson在一篇有关探讨面向对象框架的文章中&#xff0c;首先提出了IOC 这个概念。对于面向对象设计及编程…

IoC 控制反转理解

控制反转——Inversion of Control&#xff0c;缩写为IoC &#xff0c;是一个重要的面向对象编程的法则&#xff0c;说到底它是一种设计思想&#xff0c;其可以降低程序中的耦合度&#xff0c;在以前&#xff0c;我们通过new进行创建对象&#xff0c;这是程序主动去创建依赖对象…

IOC控制反转理解

1. IOC基础 IOC&#xff1a;全称Inversion Of Control&#xff0c;中文翻译是控制反转的意思。初学Spring绕不过去的一个弯&#xff0c;需要好好理解IOC的思想。网上看了很多博客&#xff0c;也看了很多网课&#xff0c;但是还是云里云雾。终于看到一个容易理解的例子&#xf…

C# IoC控制反转学习笔记

一、什么是IOC IoC-Invertion of Control&#xff0c;即控制反转&#xff0c;是一种程序设计思想。 先初步了解几个概念&#xff1a; 依赖&#xff08;Dependency&#xff09;&#xff1a;就是有联系&#xff0c;表示一个类依赖于另一个类。 依赖倒置原则&#xff08;DIP&a…