2.1 demo说明
- 大牛直播SDK提供C++/C#两套接口,对外提供32/64位debug/release库,C++和C#接口一一对应,C#接口比C++接口增加前缀NT_PB_;
- WIN-PlayerSDK-CPP-Demo:播放端SDK对应的C++接口的demo;
- WIN-PlayerSDK-CSharp-Demo:播放端SDK对应的C#接口的demo;
- 播放端SDK支持Win7及以上系统;
- 本demo基于VS2013开发。
2.2 界面UI展示
2.3集成说明
C++头文件:
- [类型定义]nt_type_define.h
- [Log定义]smart_log.h
- [Log定义]smart_log_define.h
- [base code定义]nt_base_code_define.h
- [player接口]smart_player_define.h
- [player参数定义]smart_player_sdk.h
C#头文件:
- [base code定义]nt_base_code_define.cs
- [player接口]smart_player_define.cs
- [player参数定义]smart_player_sdk.cs
相关Lib:
- SmartLog.dll
- SmartLog.lib
- SmartPlayerSDK.dll
- SmartPlayerSDK.lib
- avcodec-56.dll
- avdevice-56.dll
- avfilter-5.dll
- avformat-56.dll
- avutil-54.dll
- postproc-53.dll
- swresample-1.dll
- swscale-3.dll
集成步骤:
- 把lib目录下debug/release库拷贝到需要集成的工程对应的debug或release目录下(确保32位/64位库debug/release目录一一对应);
lib目录如下:
-
- 32位debug库:debug
- 32位release库:release
- 64位debug库:x64\debug
- 64位release库:x64\release
2. 相关cs头文件,加入需要集成的工程;
3. 在需要集成的工程,右键->Properties->
Application->Assembly name,大牛直播SDK按照APP名称授权,未授权版本,此处请改成“SmartPlayer”,如需授权,可直接联系商务;
4. 正式授权版,需要在Init()接口调用之前添加设置license的代码(相关Key和CID请根据正式授权版邮件说明填写):
2.4 接口调用时序(以C#为例)
2.4.1 设置授权license
C#的SDK,请在在NT.NTSmartPlayerSDK.NT_SP_Init之前添加下面的代码:
NT.NTSmartPlayerSDK.NT_SP_SetSDKClientKey("xxxxxxxxxx", "xxxxxxxxxx", 0, IntPtr.Zero);
UInt32 isInited = NT.NTSmartPlayerSDK.NT_SP_Init(0, IntPtr.Zero);
if (isInited != 0)
{
MessageBox.Show("调用NT_SP_Init失败..");
return;
}
C++的SDK,请在player_api_.Init之前添加下面的代码:
NT_SP_SetSDKClientKey(NT_SP_SetSDKClientKey("xxxxxxxxxx", "xxxxxxxxxx", 0, nullptr);
if ( NT_ERC_OK != player_api_.Init(0, NULL) )
{
return FALSE;
}
2.4.2 设置日志存放路径
需要在player_api_.Init之前添加下面的代码:
// 设置日志路径(请确保目录存在)
String log_path = "D:\\playerlog";
NTSmartLog.NT_SL_SetPath(log_path);
如目录存在,并具备文件写入权限,关闭应用程序后,相关文件夹下会有smart_sdk.log生成。
2.4.3 初始化SDK
NT_SP_Init:SDK初始化,多实例播放,此接口仅需调用一次即可。
2.4.4 特定机型硬解码检测
如系统用于特定机型环境下,特别是多路播放场景,需用到硬解码的话,可以用以下两组接口检测系统是否支持硬解。
注:在软解性能满足系统需求的前提下,一般建议优先使用软解。
/*
* 检查是否支持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();
如需使用硬解码,调用如下接口即可:
NTSmartPlayerSDK.NT_SP_SetH264HardwareDecoder(player_handle_, is_support_h264_hardware_decoder_ ? 1 : 0, 0);
NTSmartPlayerSDK.NT_SP_SetH265HardwareDecoder(player_handle_, is_support_h265_hardware_decoder_ ? 1 : 0, 0);
2.4.5 Open生成播放实例
NT_SP_Open:每调用一次Open接口,对应一个播放实例,如需播放多实例,对应多个player handler。
if (player_handle_ == IntPtr.Zero)
{
player_handle_ = new IntPtr();
UInt32 ret_open = NTSmartPlayerSDK.NT_SP_Open(out player_handle_, IntPtr.Zero, 0, IntPtr.Zero);
if (ret_open != 0)
{
player_handle_ = IntPtr.Zero;
MessageBox.Show("调用NT_SP_Open失败..");
return;
}
}
2.4.6 设置回调事件
- NT_SP_SetEventCallBack:用于回调网络链接状态、buffer状态(开始、buffer比例、结束)、实时带宽等,对应EventID如下:
/*事件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*/
/* 接下来请从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)*/
}
- NT_SP_SetVideoSizeCallBack:设置视频分辨率回调,如流数据携带视频数据,SDK会回上来视频宽高信息:
//video resolution callback
video_size_call_back_ = new SP_SDKVideoSizeCallBack(SP_SDKVideoSizeHandle);
NTSmartPlayerSDK.NT_SP_SetVideoSizeCallBack(player_handle_, IntPtr.Zero, video_size_call_back_);
注意:视频宽高回上来或绘制窗口发生变化时,记得调用NT_SP_OnWindowSize()更新,如不调用可能会引起视频模糊。
private void PlaybackWindowResized(Int32 width,Int32 height)
{
width_=width;
height_=height;
int left=playWnd.Left;
int top=playWnd.Top;
textBox_resolution.Text=width+"*"+height;
if(player_handle_==IntPtr.Zero)
{
return;
}
NTSmartPlayerSDK.NT_SP_OnWindowSize(player_handle_,playWnd.Width,playWnd.Height);
}
- NT_SP_SetVideoFrameCallBack:设置YUV/RGB32数据回调,可用于对接第三方视频分析,或自行绘制等,如系统不支持D3D绘制,可设置回调数据,上层GDI模式绘制:
/*定义视频帧图像格式*/
public enum NT_SP_E_VIDEO_FRAME_FORMAT : uint
{
NT_SP_E_VIDEO_FRAME_FORMAT_RGB32 = 1, // 32位的rgb格式, r, g, b各占8, 另外一个字节保留, 内存字节格式为: bb gg rr xx, 主要是和windows位图匹配, 在小端模式下,按DWORD类型操作,最高位是xx, 依次是rr, gg, bb
NT_SP_E_VIDEO_FRAME_FORMAT_ARGB = 2, // 32位的argb格式,内存字节格式是: bb gg rr aa 这种类型,和windows位图匹配
NT_SP_E_VIDEO_FRAME_FROMAT_I420 = 3, // YUV420格式, 三个分量保存在三个面上
}
- NT_SP_SetVideoFrameCallBackV2:设置YUV/RGB32数据回调,与NT_SP_SetVideoFrameCallBack接口的不同在于,吐出来的视频数据, 可以指定宽高;
- NT_SP_SetRenderVideoFrameTimestampCallBack:设置绘制视频帧时,视频帧时间戳回调,一般播放器无时间戳回调需求的话,无需设置:
//video timestamp callback
video_frame_ts_callback_ = new SP_SDKRenderVideoFrameTimestampCallBack(SP_SDKRenderVideoFrameTimestampCallBack);
NTSmartPlayerSDK.NT_SP_SetRenderVideoFrameTimestampCallBack(player_handle_, IntPtr.Zero, video_frame_ts_callback_);
- NT_SP_SetAudioPCMFrameCallBack:设置音频PCM帧回调, 吐PCM数据出来,目前每帧大小是10ms,一般播放器无使用需求的话,无需设置;
- NT_SP_SetUserDataCallBack:设置用户数据回调,此接口需要和推送端SDK配套使用,用于返回推送端设定的实时用户数据(如时间戳、经纬度等各种扩展指令或信息),如只是单纯使用播放SDK,无需设置;
- NT_SP_SetSEIDataCallBack:设置视频SEI数据回调,如只是单纯使用播放SDK,不需要额外处理扩展SEI数据的话,无需设置。
2.4.7 D3DRender检测
目前,几乎很少存在不支持D3D绘制的情况,考虑到系统通用性,我们在播放之前,先做检测,具体调用接口如下:
/*
* handle: 播放句柄
* hwnd: 这个要传入真正用来绘制的窗口句柄
* is_support: 如果支持的话 *is_support 为1, 不支持的话为0
* 接口调用成功返回NT_ERC_OK
*/
[DllImport(@"SmartPlayerSDK.dll")]
public static extern UInt32 NT_SP_IsSupportD3DRender(IntPtr handle, IntPtr hwnd, ref Int32 is_support);
对于不支持D3D绘制的情况下,设置回调YUV数据,上层直接用GDI模式绘制,注意:GDI绘制效率偏低。
Int32 in_support_d3d_render = 0;
if (NT.NTBaseCodeDefine.NT_ERC_OK == NTSmartPlayerSDK.NT_SP_IsSupportD3DRender(player_handle_, playWnd.Handle, ref in_support_d3d_render))
{
if (1 == in_support_d3d_render)
{
is_support_d3d_render = true;
}
}
if (is_support_d3d_render)
{
is_gdi_render_ = false;
// 支持d3d绘制的话,就用D3D绘制
NTSmartPlayerSDK.NT_SP_SetRenderWindow(player_handle_, playWnd.Handle);
if (btn_check_render_scale_mode.Checked)
{
NTSmartPlayerSDK.NT_SP_SetRenderScaleMode(player_handle_, 1);
}
else
{
NTSmartPlayerSDK.NT_SP_SetRenderScaleMode(player_handle_, 0);
}
}
else
{
is_gdi_render_ = true;
playWnd.Visible = false;
// 不支持D3D就让播放器吐出数据来,用GDI绘制
//video frame callback (YUV/RGB)
//format请参见 NT_SP_E_VIDEO_FRAME_FORMAT,如需回调YUV,请设置为 NT_SP_E_VIDEO_FRAME_FROMAT_I420
video_frame_call_back_ = new SP_SDKVideoFrameCallBack(SetVideoFrameCallBack);
NTSmartPlayerSDK.NT_SP_SetVideoFrameCallBack(player_handle_, (Int32)NT.NTSmartPlayerDefine.NT_SP_E_VIDEO_FRAME_FORMAT.NT_SP_E_VIDEO_FRAME_FORMAT_RGB32, IntPtr.Zero, video_frame_call_back_);
}
2.4.8 设置播放URL
NT_SP_SetURL:支持rtsp/rtmp/本地FLV文件(全路径)。
2.4.9 设置回调PCM
NT_SP_SetIsOutputAudioDevice:设置是否播放出声音,这个和静音接口是有区别的,这个接口的主要目的是为了用户设置了外部PCM回调接口后,又不想让SDK播放出声音时使用。
2.4.10 RTMP/RTSP播放参数设置
具体可参照Demo源码里面InitCommonSDKParam():
2.4.10.1 播放前可选设置接口
- NT_SP_SetBuffer:设置视频播放缓冲buffer大小,单位:毫秒;
- 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_SetReportDownloadSpeed:设置下载速度上报, 默认不上报下载速度;
* is_report: 上报开关, 1: 表上报. 0: 表示不上报. 其他值无效.
* report_interval: 上报时间间隔(上报频率),单位是秒,最小值是1秒1次. 如果小于1且设置了上报,将调用失败
* 注意:如果设置上报的话,请设置SetEventCallBack, 然后在回调函数里面处理这个事件.
* 上报事件是:NT_SP_E_EVENT_ID_DOWNLOAD_SPEED
- NT_SP_GetDownloadSpeed:主动获取下载速度,speed: 返回下载速度,单位是Byte/s;
- NT_SP_SetParam:万能接口, 设置参数, 大多数问题, 这些接口都能解决;
- NT_SP_GetParam:万能接口, 得到参数, 大多数问题,这些接口都能解决;
2.4.10.2 播放前后可实时调用的接口
- NT_SP_SetMute:播放过程中,实时静音、取消静音,可播放之前调用,亦或播放过程中实时调用;
- NT_SP_SetAudioVolume:不同于实时静音接口,此接口可以更细粒度的控制音量,默认范围[0,100],其中0是静音,100是最大音量, 默认是100;
- NT_SP_SetOnlyDecodeVideoKeyFrame:多窗口播放场景下,部分窗口可能只需要播放关键帧,如有类似场景需求,可用此接口;
- NT_SP_SetRotation:设置视频View旋转,顺时针旋转,degress: 设置0, 90, 180, 270度有效,其他值无效,注意:除了0度,其他角度播放会耗费更多CPU;
- NT_SP_SetFlipVertical:设置视频View上下反转(垂直反转);
- NT_SP_SetFlipHorizontal:设置视频View水平反转;
- NT_SP_SetRenderScaleMode:设置视频画面的填充模式,如填充整个绘制窗口、等比例填充绘制窗口,如不设置,默认填充整个绘制窗口;
2.4.11 开始播放
NT_SP_StartPlay
开始播放RTMP或RTSP流数据。
2.4.12 RTMP/RTSP拉流端录像
- 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:停止录像
2.4.13 实时快照
NT_SP_CaptureImage
用于播放端实时截取当前播放图片,图片以PNG形式保存至本地。
String name = capture_image_path_ + "\\" + DateTime.Now.ToString("hh-mm-ss") + ".png";
byte[] buffer1 = Encoding.Default.GetBytes(name);
byte[] buffer2 = Encoding.Convert(Encoding.Default, Encoding.UTF8, buffer1, 0, buffer1.Length);
byte[] buffer3 = new byte[buffer2.Length + 1];
buffer3[buffer2.Length] = 0;
Array.Copy(buffer2, buffer3, buffer2.Length);
IntPtr file_name_ptr = Marshal.AllocHGlobal(buffer3.Length);
Marshal.Copy(buffer3, 0, file_name_ptr, buffer3.Length);
capture_image_call_back_ = new SP_SDKCaptureImageCallBack(SDKCaptureImageCallBack);
UInt32 ret = NTSmartPlayerSDK.NT_SP_CaptureImage(player_handle_, file_name_ptr, IntPtr.Zero, capture_image_call_back_);
Marshal.FreeHGlobal(file_name_ptr);
if (NT.NTBaseCodeDefine.NT_ERC_OK == ret)
{
// 发送截图请求成功
}
else if ((UInt32)NT.NTSmartPlayerDefine.SP_E_ERROR_CODE.NT_ERC_SP_TOO_MANY_CAPTURE_IMAGE_REQUESTS == ret)
{
// 通知用户延时
MessageBox.Show("Too many capture image requests!");
}
else
{
// 其他失败
}
2.4.14 快速切换URL
NT_SP_SwitchURL
快速切换URL,用于不用析构整个player实例的前提下,实时切换播放的URL。
2.4.15 用户数据回调
NT_SP_SetUserDataCallBack
设置用户数据回调,用于接收扩展SEI模块发送的用户数据信息,如不是配合我们扩展SEI发送DK,此接口无需调用。
2.4.16 SEI数据回调
NT_SP_SetSEIDataCallBack
设置视频sei数据回调,用于接收SEI数据回调,如流数据不存在SEI或不准备处理SEI数据,此接口无需调用。
2.4.17 停止播放
NT_SP_StopPlay
停止播放RTMP或RTSP流数据。
2.4.18 关闭播放实例
NT_SP_Close
调用Close接口后,player handler置空。
if ( player_handle_ != IntPtr.Zero)
{
NTSmartPlayerSDK.NT_SP_Close(player_handle_);
player_handle_ = IntPtr.Zero;
}
2.4.19 Uninit
NT_SP_UnInit
UnInit() 是SDK最后一个调用的接口,多实例环境下,只需要调用一次即可。