前段时间,我们在 https://blog.csdn.net/renhui1112/article/details/104143794 提到“RTSP播放器开发过程中需要考虑哪些关键因素”,本次主要介绍,如何调用SDK实现RTSP/RTMP播放能力。
本文以调用大牛直播SDK为例:
C++头文件:
C#头文件:
到以下目录,拷贝相关lib库到自己系统目录:
NT_SP_Init
如需配置log路径,请在NT_SP_Init之前,做如下设置(目录可自行指定):
// 设置日志路径(请确保目录存在)
//String log_path = “D:\playerlog”;
//NTSmartLog.NT_SL_SetPath(log_path);
NT_SP_Open:每调用一次Open接口,对应一个播放实例。
① NT_SP_SetEventCallBack:用于回调网络链接状态、buffer状态(开始、buffer比例、结束)、实时带宽等;
② NT_SP_SetVideoSizeCallBack:设置视频分辨率回调;
③ NT_SP_SetVideoFrameCallBack:设置YUV/RGB32数据回调,可用于对接第三方视频分析,或自行绘制等;
④ NT_SP_SetVideoFrameCallBackV2:设置YUV/RGB32数据回调,与NT_SP_SetVideoFrameCallBack接口的不同在于,吐出来的视频数据, 可以指定宽高;
⑤ NT_SP_SetRenderVideoFrameTimestampCallBack:设置绘制视频帧时,视频帧时间戳回调;
⑥ NT_SP_SetAudioPCMFrameCallBack:设置音频PCM帧回调, 吐PCM数据出来,目前每帧大小是10ms;
⑦ NT_SP_SetUserDataCallBack:设置用户数据回调,此接口需要和推送端SDK配套使用,用于返回推送端设定的实时用户数据(如时间戳、经纬度等各种扩展指令或信息);
⑧ NT_SP_SetSEIDataCallBack:设置视频SEI数据回调。
NT_SP_SetURL:支持rtsp/rtmp/本地FLV文件(全路径)
设置绘制窗口句柄(可选接口)
① NT_SP_IsSupportD3DRender
② NT_SP_SetRenderWindow
③ NT_SP_GDIDrawRGB32:使用GDI绘制RGB32数据
NT_SP_SetIsOutputAudioDevice:设置是否播放出声音,这个和静音接口是有区别的,这个接口的主要目的是为了用户设置了外部PCM回调接口后,又不想让SDK播放出声音时使用。
① NT_SP_SetBuffer:设置视频播放缓冲buffer大小,单位:毫秒;
② NT_SP_SetMute:播放过程中,实时静音、取消静音,可播放之前调用,亦或播放过程中实时调用;
③ NT_SP_SetRTSPTcpMode:设置RTSP TCP 模式, 1为TCP, 0为UDP, 此接口仅RTSP有效;
④ NT_SP_SetRtspTimeout:设置RTSP超时时间, timeout单位为秒,必须大于0;
NT_SP_SetRtspAutoSwitchTcpUdp:对于RTSP来说,有些可能支持rtp over udp方式,有些可能支持使用rtp over tcp方式. 为了方便使用,有些场景下可以开启自动尝试切换开关, 打开后如果udp无法播放,sdk会自动尝试tcp, 如果tcp方式播放不了,sdk会自动尝试udp, is_auto_switch_tcp_udp: 如果设置1的话, sdk将在tcp和udp之间尝试切换播放,如果设置为0,则不尝试切换;
⑤ NT_SP_SetFastStartup:设置秒开, 1为秒开, 0为不秒开,此接口用于如RTMP服务器缓存GOP时,酌情使用;
⑥ NT_SP_SetLowLatencyMode:设置低延时播放模式,默认是正常播放模式,mode: 1为低延时模式, 0为正常模式;
⑦ NT_SP_SetRotation:设置视频View旋转,顺时针旋转,degress: 设置0, 90, 180, 270度有效,其他值无效,注意:除了0度,其他角度播放会耗费更多CPU;
⑧ NT_SP_SetFlipVertical:设置视频View上下反转(垂直反转);
⑨ NT_SP_SetFlipHorizontal:设置视频View水平反转;
⑩ NT_SP_SetReportDownloadSpeed:设置下载速度上报, 默认不上报下载速度
/*
* 检查是否支持H264硬解码
* 如果支持的话返回NT_ERC_OK
*/
[DllImport(@"SmartPlayerSDK.dll")]
public static extern UInt32 NT_SP_IsSupportH264HardwareDecoder();
/*
* 检查是否支持H265硬解码
* 如果支持的话返回NT_ERC_OK
*/
[DllImport(@"SmartPlayerSDK.dll")]
public static extern UInt32 NT_SP_IsSupportH265HardwareDecoder();
/*
* 设置H264硬解
* is_hardware_decoder: 1:表示硬解, 0:表示不用硬解
* reserve: 保留参数, 当前传0就好
* 成功返回NT_ERC_OK
*/
[DllImport(@"SmartPlayerSDK.dll")]
public static extern UInt32 NT_SP_SetH264HardwareDecoder(IntPtr handle, Int32 is_hardware_decoder, Int32 reserve);
/*
* 设置H265硬解
* is_hardware_decoder: 1:表示硬解, 0:表示不用硬解
* reserve: 保留参数, 当前传0就好
* 成功返回NT_ERC_OK
*/
[DllImport(@"SmartPlayerSDK.dll")]
public static extern UInt32 NT_SP_SetH265HardwareDecoder(IntPtr handle, Int32 is_hardware_decoder, Int32 reserve);
NT_SP_StartPlay
NT_SP_OnWindowSize
如播放窗口大小调整,需调用此接口。
① NT_SP_SetRecorderDirectory:设置录像目录
② NT_SP_SetRecorderFileMaxSize:设置单个文件最大大小
③ NT_SP_SetRecorderFileNameRuler:设置录像文件名生成规则
④ NT_SP_SetRecorderCallBack:设置录像回调接口
⑤ NT_SP_SetRecorderAudioTranscodeAAC:设置录像时音频转AAC编码的开关, aac比较通用,sdk增加其他音频编码(比如speex, pcmu, pcma等)转aac的功能
⑥ NT_SP_SetRecorderVideo:设置是否录视频,默认的话,如果视频源有视频就录,没有就没得录, 但有些场景下可能不想录制视频,只想录音频,所以增加个开关
⑦ NT_SP_SetRecorderAudio:设置是否录音频,默认的话,如果视频源有音频就录,没有就没得录, 但有些场景下可能不想录制音频,只想录视频,所以增加个开关
⑧ NT_SP_StartRecorder:启动录像
⑨ NT_SP_StopRecorder:停止录像
NT_SP_CaptureImage:捕获图片
NT_SP_SwitchURL:切换URL,其中:switch_pos: 切换到新url以后,设置的播放位置, 默认请填0, 这个只对设置播放位置的点播url有效, 直播url无效
NT_SP_SetUserDataCallBack:设置用户数据回调,用于接收扩展SEI模块发送的用户数据信息
NT_SP_SetSEIDataCallBack:设置视频sei数据回调,用于接收SEI数据回调
/*
* 设置视频画面的填充模式,如填充整个绘制窗口、等比例填充绘制窗口,如不设置,默认填充整个绘制窗口
* handle: 播放句柄
* mode: 0: 填充整个绘制窗口; 1: 等比例填充绘制窗口, 默认值是0
* 成功返回NT_ERC_OK
*/
[DllImport(@"SmartPlayerSDK.dll")]
public static extern UInt32 NT_SP_SetRenderScaleMode(IntPtr handle, Int32 mode);
NT_SP_StopPlay
NT_SP_Close
NT_SP_UnInit
/*事件ID*/
public enum NT_SP_E_EVENT_ID : uint
{
NT_SP_E_EVENT_ID_BASE = NTBaseCodeDefine.NT_EVENT_ID_SMART_PLAYER_SDK,
NT_SP_E_EVENT_ID_CONNECTING = NT_SP_E_EVENT_ID_BASE | 0x2, /*连接中*/
NT_SP_E_EVENT_ID_CONNECTION_FAILED = NT_SP_E_EVENT_ID_BASE | 0x3, /*连接失败*/
NT_SP_E_EVENT_ID_CONNECTED = NT_SP_E_EVENT_ID_BASE | 0x4, /*已连接*/
NT_SP_E_EVENT_ID_DISCONNECTED = NT_SP_E_EVENT_ID_BASE | 0x5, /*断开连接*/
NT_SP_E_EVENT_ID_NO_MEDIADATA_RECEIVED = NT_SP_E_EVENT_ID_BASE | 0x8, /*收不到RTMP数据*/
NT_SP_E_EVENT_ID_RTSP_STATUS_CODE = NT_SP_E_EVENT_ID_BASE | 0xB, /*rtsp status code上报, 目前只上报401, param1表示status code*/
NT_SP_E_EVENT_ID_NEED_KEY = NT_SP_E_EVENT_ID_BASE | 0xC, /*需要输入解密key才能播放*/
NT_SP_E_EVENT_ID_KEY_ERROR = NT_SP_E_EVENT_ID_BASE | 0xD, /*解密key不正确*/
/* 接下来请从0x81开始*/
NT_SP_E_EVENT_ID_START_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x81, /*开始缓冲*/
NT_SP_E_EVENT_ID_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x82, /*缓冲中, param1 表示百分比进度*/
NT_SP_E_EVENT_ID_STOP_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x83, /*停止缓冲*/
NT_SP_E_EVENT_ID_DOWNLOAD_SPEED = NT_SP_E_EVENT_ID_BASE | 0x91, /*下载速度, param1表示下载速度,单位是(Byte/s)*/
NT_SP_E_EVENT_ID_PLAYBACK_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa1, /*播放结束, 直播流没有这个事件,点播流才有*/
NT_SP_E_EVENT_ID_RECORDER_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa2, /*录像结束, 直播流没有这个事件, 点播流才有*/
NT_SP_E_EVENT_ID_PULLSTREAM_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa3, /*拉流结束, 直播流没有这个事件,点播流才有*/
NT_SP_E_EVENT_ID_DURATION = NT_SP_E_EVENT_ID_BASE | 0xa8, /*视频时长,如果是直播,则不上报,如果是点播的话, 若能从视频源获取视频时长的话,则上报, param1表示视频时长,单位是毫秒(ms)*/
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NT_SP_PullStreamVideoDataInfo
{
public Int32 is_key_frame_; /* 1:表示关键帧, 0:表示非关键帧 */
public UInt64 timestamp_; /* 解码时间戳, 单位是毫秒 */
public Int32 width_; /* 一般是0 */
public Int32 height_; /* 一般也是0 */
public IntPtr parameter_info_; /* 一般是NULL */
public UInt32 parameter_info_size_; /* 一般是0 */
public UInt64 presentation_timestamp_; /*显示时间戳, 这个值要大于或等于timestamp_, 单位是毫秒*/
}
/*
*拉流吐音频数据时,一些相关的数据
*/
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NT_SP_PullStreamAuidoDataInfo
{
public Int32 is_key_frame_; /* 1:表示关键帧, 0:表示非关键帧 */
public UInt64 timestamp_; /* 单位是毫秒 */
public Int32 sample_rate_; /* 一般是0 */
public Int32 channel_; /* 一般是0 */
public IntPtr parameter_info_; /* 如果是AAC的话,这个是有值的, 其他编码一般忽略 */
public UInt32 parameter_info_size_; /*如果是AAC的话,这个是有值的, 其他编码一般忽略 */
public UInt64 reserve_; /* 保留 */
}
以上是基础的接口说明和调用流程,感兴趣的开发者可以参考下。