庖丁解牛之Android平台RTSP|RTMP播放器设计

志不强者智不达,言不信者行不果。这篇文章主要讲述庖丁解牛之Android平台RTSP|RTMP播放器设计相关的知识,希望能为你提供帮助。
?

背景我们在做android平台RTSP或者RTMP播放器开发的时候,需要注意的点非常多,以下,以大牛直播SDK(??官方??)的接口为例,大概介绍下相关接口设计:
接口设计1. Open() 接口
Open接口的目的,主要是创建实例,正常返回player实例句柄,如有多路播放诉求,创建多个实例即可。




/**
* Initialize Player(启动播放实例)
*
* @param ctx: get by this.getApplicationContext()
*
* < pre> This function must be called firstly.< /pre>
*
* @return player handle if successful, if return 0, which means init failed.
*/

public native long SmartPlayerOpen(Object ctx);

【庖丁解牛之Android平台RTSP|RTMP播放器设计】
2. Close()接口
Close接口,和Open()接口对应,负责释放相应实例的资源,调用Close()接口后,记得实例句柄置0即可。
注意:比如一个实例既可以实现播放,又可同时录像,亦或拉流(转发),这种情况下,调Close()接口时,需要确保录像、拉流都正常停止后,再调用。





/**
* 关闭播放实例,结束时必须调用close接口释放资源
*
* @param handle: return value from SmartPlayerOpen()
*
* < pre> NOTE: it could not use player handle after call this function. < /pre>
*
* @return {0} if successful
*/
public native int SmartPlayerClose(long handle);


3. 网络状态回调
一个好的播放器,好的状态回调必不可少,比如网络连通状态、快照、录像状态、当前下载速度等实时反馈,可以让上层开发者更好的掌控播放端状态,给用户更好的播放体验。




/**
* Set callback event(设置事件回调)
*
* @param handle: return value from SmartPlayerOpen()
*
* @param callbackv2: callback function
*
* @return {0} if successful
*/
public native int SetSmartPlayerEventCallbackV2(long handle, NTSmartEventCallbackV2 callbackv2);


demo实现实例:




class EventHandeV2 implements NTSmartEventCallbackV2 {
@Override
public void onNTSmartEventCallbackV2(long handle, int id, long param1,
long param2, String param3, String param4, Object param5) {

//Log.i(TAG, "EventHandeV2: handle=" + handle + " id:" + id);

String player_event = "";

switch (id) {
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_STARTED:
player_event = "开始..";
break;
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTING:
player_event = "连接中..";
break;
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTION_FAILED:
player_event = "连接失败..";
break;
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CONNECTED:
player_event = "连接成功..";
break;
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_DISCONNECTED:
player_event = "连接断开..";
break;
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_STOP:
player_event = "停止播放..";
break;
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_RESOLUTION_INFO:
player_event = "分辨率信息: width: " + param1 + ", height: " + param2;
break;
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_NO_MEDIADATA_RECEIVED:
player_event = "收不到媒体数据,可能是url错误..";
break;
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_SWITCH_URL:
player_event = "切换播放URL..";
break;
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_CAPTURE_IMAGE:
player_event = "快照: " + param1 + " 路径:" + param3;

if (param1 == 0) {
player_event = player_event + ", 截取快照成功";
} else {
player_event = player_event + ", 截取快照失败";
}
break;

case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_RECORDER_START_NEW_FILE:
player_event = "[record]开始一个新的录像文件 : " + param3;
break;
case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_ONE_RECORDER_FILE_FINISHED:
player_event = "[record]已生成一个录像文件 : " + param3;
break;

case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_START_BUFFERING:
Log.i(TAG, "Start Buffering");
break;

case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_BUFFERING:
Log.i(TAG, "Buffering:" + param1 + "%");
break;

case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_STOP_BUFFERING:
Log.i(TAG, "Stop Buffering");
break;

case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_DOWNLOAD_SPEED:
player_event = "download_speed:" + param1 + "Byte/s" + ", "
+ (param1 * 8 / 1000) + "kbps" + ", " + (param1 / 1024)
+ "KB/s";
break;

case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_RTSP_STATUS_CODE:
Log.e(TAG, "RTSP error code received, please make sure username/password is correct, error code:" + param1);
player_event = "RTSP error code:" + param1;
break;

case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_NEED_KEY:
Log.e(TAG, "RTMP加密流,请设置播放需要的Key..");
player_event = "RTMP加密流,请设置播放需要的Key..";
break;

case NTSmartEventID.EVENT_DANIULIVE_ERC_PLAYER_KEY_ERROR:
Log.e(TAG, "RTMP加密流,Key错误,请重新设置..");
player_event = "RTMP加密流,Key错误,请重新设置..";
break;
}

if (player_event.length() > 0) {
Log.i(TAG, player_event);
Message message = new Message();
message.what = PLAYER_EVENT_MSG;
message.obj

    推荐阅读