C++头文件:
C#头文件:
相关Lib:
集成步骤:
lib目录如下:
2. 相关cs头文件,加入需要集成的工程;
3. 在需要集成的工程,右键->Properties->
Application->Assembly name,大牛直播SDK按照APP名称授权,未授权版本,此处请改成“SmartPlayer”,如需授权,可直接联系商务;
4. 正式授权版,需要在Init()接口调用之前添加设置license的代码(相关Key和CID请根据正式授权版邮件说明填写):
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;
}
需要在player_api_.Init之前添加下面的代码:
// 设置日志路径(请确保目录存在)
String log_path = "D:\\playerlog";
NTSmartLog.NT_SL_SetPath(log_path);
如目录存在,并具备文件写入权限,关闭应用程序后,相关文件夹下会有smart_sdk.log生成。
NT_SP_Init:SDK初始化,多实例播放,此接口仅需调用一次即可。
如系统用于特定机型环境下,特别是多路播放场景,需用到硬解码的话,可以用以下两组接口检测系统是否支持硬解。
注:在软解性能满足系统需求的前提下,一般建议优先使用软解。
/*
* 检查是否支持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);
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;
}
}
/*事件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)*/
}
//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);
}
/*定义视频帧图像格式*/
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格式, 三个分量保存在三个面上
}
//video timestamp callback
video_frame_ts_callback_ = new SP_SDKRenderVideoFrameTimestampCallBack(SP_SDKRenderVideoFrameTimestampCallBack);
NTSmartPlayerSDK.NT_SP_SetRenderVideoFrameTimestampCallBack(player_handle_, IntPtr.Zero, video_frame_ts_callback_);
目前,几乎很少存在不支持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文件(全路径)。
NT_SP_SetIsOutputAudioDevice:设置是否播放出声音,这个和静音接口是有区别的,这个接口的主要目的是为了用户设置了外部PCM回调接口后,又不想让SDK播放出声音时使用。
具体可参照Demo源码里面InitCommonSDKParam():
2.4.10.1 播放前可选设置接口
* is_report: 上报开关, 1: 表上报. 0: 表示不上报. 其他值无效.
* report_interval: 上报时间间隔(上报频率),单位是秒,最小值是1秒1次. 如果小于1且设置了上报,将调用失败
* 注意:如果设置上报的话,请设置SetEventCallBack, 然后在回调函数里面处理这个事件.
* 上报事件是:NT_SP_E_EVENT_ID_DOWNLOAD_SPEED
2.4.10.2 播放前后可实时调用的接口
NT_SP_StartPlay
开始播放RTMP或RTSP流数据。
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。
NT_SP_SetUserDataCallBack
设置用户数据回调,用于接收扩展SEI模块发送的用户数据信息,如不是配合我们扩展SEI发送DK,此接口无需调用。
NT_SP_SetSEIDataCallBack
设置视频sei数据回调,用于接收SEI数据回调,如流数据不存在SEI或不准备处理SEI数据,此接口无需调用。
NT_SP_StopPlay
停止播放RTMP或RTSP流数据。
NT_SP_Close
调用Close接口后,player handler置空。
if ( player_handle_ != IntPtr.Zero)
{
NTSmartPlayerSDK.NT_SP_Close(player_handle_);
player_handle_ = IntPtr.Zero;
}
NT_SP_UnInit
UnInit() 是SDK最后一个调用的接口,多实例环境下,只需要调用一次即可。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。