跨平台屏幕/摄像头RTMP推流模块设计要点

经常有企业或开发者有这样的疑惑,明明看到网上的demo,一个RTMP推送,五六个接口就搞定了,你们咋就搞得这么复杂?

以大牛直播SDK的(Github)Windows RTMP推流为例,我们的接口要100多个,下面我们就扯扯,为什么一个RTMP推送,怎么就这么难?

RTMP推送端SDK特点:

  1. 全自研框架,易于扩展,自适应算法让延迟更低、采集编码传输效率更高;
  2. 所有功能以SDK接口形式提供,所有状态,均有event回调,完美支持断网自动重连;
  3. SDK模块化,可和大牛直播播放器SDK组合实现流媒体数据转发、内置轻量级RTSP服务、连麦、一对一互动等场景;
  4. Windows推送端SDK以层级模式提供,开发者可以自行组合数据源(如多摄像头/屏幕/水印叠加);
  5. 支持外部YUV/RGB/H.264/AAC/SPEEX/PCMA/PCMU数据源接入;
  6. 所有参数均可通过SDK接口单独设置,亦可通过默认参数,傻瓜式设置;
  7. 推送、录像、内置轻量级RTSP服务模块完全分离,可单独使用亦可组合使用;
  8. 业内甚至很难找到效果接近的SDK。

上个图:

功能支持:

  •  [视频采集处理]Windows平台涵盖“Windows视频采集处理”功能;
  •  [音频采集处理]Windows平台涵盖“Windows音频采集处理”功能;
  •  [本地预览]Windows平台支持摄像头/屏幕/合成数据实时预览功能,Android/iOS平台支持本地前后置摄像头预览;
  •  [摄像头反转/旋转]Windows平台支持摄像头水平反转、垂直反转、0°/90°/180°/270°旋转;
  •  [摄像头采集]除常规YUV格式外,Windows平台还支持MJPEG格式的摄像头采集;
  •  [麦克风/扬声器采集]Windows平台音频输入端支持麦克风、扬声器,或麦克风和扬声器混音输入;
  •  [RTMP推流]超低延时的RTMP协议直播推流SDK(Windows/Android/iOS支持RTMP扩展H.265推送);
  •  [视频格式]Windows/Android平台支持H.264/H.265编码(Android H.265硬编码),iOS平台支持H.264编码;
  •  [音频格式]Windows/Android/iOS平台支持AAC编码,Windows/Android平台支持Speex编码;
  •  [音频编码]Windows/Android平台支持Speex推送、Speex编码质量设置;
  •  [音量调节]Windows/Android平台采集端支持实时音量调节(其中,Windows平台混音模式下支持单独控制麦克风、扬声器音量);
  •  [H.264硬编码]Windows/Android/iOS平台支持H.264特定机型硬编码;
  •  [H.265硬编码]Android/iOS平台支持H.265特定机型硬编码;
  •  [硬编码自适应]Android/iOS平台支持硬编码自适应,如检测到硬编码不支持,自动切换到软编(iOS如H.265硬编,先切换到H.264硬编码,如不支持再尝试H.264软编);
  •  [软硬编码参数配置]支持gop间隔、帧率、bit-rate设置;
  •  [软编码参数配置]支持软编码profile、软编码速度、可变码率设置;
  •  [多实例推送]支持多实例推送(如同时推送屏幕/摄像头和外部数据);
  •  [RTMP扩展H.265]Windows/Android/iOS推送SDK支持RTMP扩展H.265推送,Windows针对摄像头采集软编码,使用H.265可变码率,带宽大幅节省,效果直逼传统H.265编码摄像头,Android/iOS平台支持H.265硬编码;
  •  [横竖屏推流]Android/iOS平台支持支持横屏、竖屏推流;
  •  [多分辨率支持]支持摄像头或屏幕多种分辨率设置;
  •  [Windows推屏]Windows平台支持屏幕裁剪、窗口采集、屏幕/摄像头数据合成等多种模式推送;
  •  [移动端推屏]Android平台支持后台service推送屏幕(推送屏幕需要5.0+版本);
  •  [移动端推屏]iOS平台支持后台推送屏幕(基于ReplayKit,需要iOS 10.0+版本);
  •  [事件回调]支持各种状态实时回调;
  •  [水印]Windows平台支持文字水印、png水印、实时遮挡,Android平台支持文字水印、png水印;
  •  [RTMP推送模式]支持RTMP推送 live|record模式设置(需服务器支持);
  •  [镜像]Android/iOS平台支持前置摄像头实时镜像功能;
  •  [前后摄像头实时切换]Android/iOS平台支持采集过程中,前后摄像头切换;
  •  [复杂网络处理]支持断网重连等各种网络环境自动适配;
  •  [动态码率]支持根据网络情况自动调整推流码率;
  •  [实时静音]支持推送过程中,实时静音/取消静音;
  •  [实时快照]支持推流过程中,实时快照;
  •  [纯音频推流]支持仅采集音频流并发起推流功能;
  •  [纯视频推流]支持特殊场景下的纯视频推流功能;
  •  [降噪]Windows/Android平台支持环境音、手机干扰等引起的噪音降噪处理、自动增益、VAD检测;
  •  [回音消除]Android平台支持实时传递远端PCM数据,方便回音消除处理;
  •  [外部编码前视频数据对接]支持YUV数据对接;
  •  [外部编码前音频数据对接]支持PCM对接;
  •  [外部编码后视频数据对接]支持外部H.264数据对接;
  •  [外部编码后音频数据对接]外部AAC/PCMA/PCMU/SPEEX数据对接;
  •  [推送端休眠设置]Windows平台支持休眠接口(设置成休眠模式后CPU会适当降低);
  •  [编码后数据输出]Android平台支持输出编码后的H264/AAC数据到上层,方便对接第三方平台(如GB28181)对接;
  •  [扩展录像功能]完美支持和录像SDK组合使用,录像相关功能,可参见"Windows/Android/iOS录像";
  •  [裁剪模式]Android/iOS平台支持特定分辨率摄像头裁剪模式设置;
  •  [服务器兼容]支持自建服务器(如Nginx、SRS)或CDN。

支持平台架构

支持平台支持架构
Windows平台x86 debug/release, x64 debug/release
Android平台armeabi-v7a, arm64-v8a, x86, x86_64
iOS平台armv7, arm64, i386, x86_64

Windows视频采集处理相关:

  1. 支持视频源
  •  支持Windows屏幕采集、屏幕裁剪特定窗口采集、摄像头采集、扩展外部H.264数据对接;
  • 摄像头和屏幕合成
  •  [摄像头和屏幕实时切换]支持推送过程中,摄像头和屏幕互相切换,单画面显示摄像头或屏幕;
  •  [摄像头叠加到屏幕] 支持摄像头按照设置坐标,叠加到屏幕指定位置,并支持实时关闭叠加层;
  •  [屏幕叠加到摄像头] 支持屏幕按照设定坐标,叠加到摄像头指定位置,并支持实时关闭叠加层;
  1. 水印和透明度遮挡
  •  [实时水印]支持动态水印设置,完美支持文字水印、实时时间水印和图片水印
  •  [透明度]可以设置透明度处理(设置遮盖);

Windows音频采集处理相关

  1. 支持音频源
  •  支持Windows采集麦克风扬声器和外部AAC, Speex WB, PCMA, PCMU数据接口输入;
  1. 音频合成
  •  [音频]支持扬声器和麦克风音频混音输出(同时选择“采集扬声器”和“采集麦克风”);
  1. 音频处理
  •  支持音频“端点检测(VAD)”,自适应码流,音频码流更节省;
  •  支持回音消除功能;
  •  支持噪音抑制功能;
  •  支持自动增益控制。

Windows/Android/iOS录像SDK相关

  •  [拉流]支持拉取RTSP流录像;
  •  [拉流]支持拉取RTMP流录像;
  •  [推流端录像]支持推送端同步录像;
  •  [逻辑分离]大牛直播录像SDK不同于普通录像接口,更智能,和推送、播放、转发、内置轻量级RTSP服务SDK功能完全分离,支持随时录像;
  •  [url切换]在录像过程中,支持切换不同URL,如两个URL配置一致,则可以录制到同一个MP4文件,如不一致,可自动分割到下一个文件;
  •  [参数设置]支持设置单个录像文件大小、录像路径等,并支持纯音频、纯视频、音视频录制模式;
  •  [音频转码]支持音频(PCMU/PCMA,Speex等)转AAC后再录像;
  •  [265支持]支持RTSP/RTMP H.265录制到MP4文件;
  •  [推送端265录像]Windows/Android推送端SDK支持H265录像;
  •  [事件回调]从开始录像,到录像结束均有event callback上来,网络堵塞、音视频同步均做了非常友好的处理。

看过之后,你再思考下,一个能满足商业化目的的RTMP推流,真的是几个接口能搞定的吗?

附个Windows推送SDK的接口头文件:

#ifndef NT_SMART_PUBLISHER_SDK_H_
#define NT_SMART_PUBLISHER_SDK_H_// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the SMARTPUBLISHERSDK_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// SMARTPUBLISHERSDK_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef SMARTPUBLISHERSDK_EXPORTS
#define SMARTPUBLISHERSDK_API __declspec(dllexport)
#else
#define SMARTPUBLISHERSDK_API __declspec(dllimport)
#endif#include "nt_type_define.h"#include "nt_smart_publisher_define.h"#ifdef __cplusplus
extern "C"{
#endif/*Image处理提供单独的结构体, 降低存储空间,方便拷贝*/typedef struct _NT_SmartPublisherImageSDKAPI{/*分配Image, 分配后,SDK内部会初始化这个结构体, 失败的话返回NULL*/NT_PB_Image* (NT_API *AllocateImage)(NT_VOID);/*释放Image, 注意一定要调用这个接口释放内存,如果在你自己的模块中释放,Windows会出问题的,成功返回 NT_ERC_OK*/NT_UINT32(NT_API *FreeImage)(NT_PB_Image** ppImage);/*克隆一个Image, 失败返回NULL*/NT_PB_Image* (NT_API* CloneImage)(const NT_PB_Image* src);/*拷贝Image, 会先释放dst的资源,然后再拷贝成功返回 NT_ERC_OK*/NT_UINT32(NT_API* CopyImage)(NT_PB_Image* dst, const NT_PB_Image* src);/*给图像一个面设置数据,如果这个面已经有数据,将会释放掉再设置这个设置行为依赖于NT_PB_Image::format_成功返回 NT_ERC_OK*/NT_UINT32(NT_API* SetImagePlane)(NT_PB_Image* image, NT_INT32 plane,NT_INT32 planeStride, const NT_UINT8* planeData, NT_INT32 planeDataSize);/*加载PNG图片file_name_utf8: 必须是utf8编码成功返回 NT_ERC_OK*/NT_UINT32(NT_API* LoadImage)(NT_PCSTR file_name_utf8,NT_PB_Image** ppImage);} NT_SmartPublisherImageSDKAPI;/*绘制相关接口, 绘制后续可能会提供更多接口*/typedef struct _NT_SmartPublisherDrawImageSDKAPI{/*成功返回NT_ERC_OK*/NT_UINT32(NT_API *Draw)(NT_HDC hdc, NT_INT32 xDst, NT_INT32 yDst,NT_INT32 dstWidth, NT_INT32 dstHeight,NT_INT32 xSrc, NT_INT32 ySrc,NT_INT32 srcWidth, NT_INT32 srcHeight,const NT_PB_Image* image);} NT_SmartPublisherDrawImageSDKAPI;typedef struct _NT_SmartPublisherSDKAPI{/*flag目前传0,后面扩展用, pReserve传NULL,扩展用,成功返回 NT_ERC_OK*/NT_UINT32(NT_API *Init)(NT_UINT32 flag, NT_PVOID pReserve);/*这个是最后一个调用的接口成功返回 NT_ERC_OK*/NT_UINT32(NT_API *UnInit)();/*video_option 请参考 NT_PB_E_VIDEO_OPTION,auido_option 请参考 NT_PB_E_AUDIO_OPTIONflag目前传0,后面扩展用, pReserve传NULL,扩展用,获取Handle成功返回 NT_ERC_OK*/NT_UINT32(NT_API *Open)(NT_PHANDLE pHandle, NT_UINT32 video_option, NT_UINT32 auido_option, NT_UINT32 flag, NT_PVOID pReserve);/*调用这个接口之后handle失效,成功返回 NT_ERC_OK*/NT_UINT32(NT_API *Close)(NT_HANDLE handle);/*设置事件回调,如果想监听事件的话,建议调用Open成功后,就调用这个接口*/NT_UINT32(NT_API *SetEventCallBack)(NT_HANDLE handle,NT_PVOID call_back_data, NT_PB_SDKEventCallBack call_back);/*参数相关设置*//*设置屏幕裁剪left: 屏幕左上角x位置top:  屏幕左上角y位置width: 宽度, 必须是16的倍数height: 高度, 必须是16的倍数*/NT_UINT32(NT_API *SetScreenClip)(NT_HANDLE handle, NT_UINT32 left, NT_UINT32 top, NT_UINT32 width, NT_UINT32 height);/*移动屏幕剪切区域,这个接口只能推送或者录像中调用left: 屏幕左上角x位置top:  屏幕左上角y位置*/NT_UINT32(NT_API *MoveScreenClipRegion)(NT_HANDLE handle, NT_UINT32 left, NT_UINT32 top);/*允许使用DXGI屏幕采集方式, 这种方式需要win8及以上系统才支持is_enable: 1表示启用DXGI采集,0表示不启用, 其他值直接返回错误成功返回 NT_ERC_OK*/NT_UINT32(NT_API *EnableDXGIScreenCapturer)(NT_HANDLE handle, NT_INT32 is_enable);/**采集屏幕时停用Aero, 这个只对win7有影响,win8及以上系统, 微软已经抛弃了Aero Glass效果*is_disable: 1:表示停用,如果设置为1的话,在win7系统上开始捕屏时可能黑屏闪烁一下, 0:表示不停用* sdk内部默认值是1*成功返回 NT_ERC_OK*/NT_UINT32(NT_API *DisableAeroScreenCapturer)(NT_HANDLE handle, NT_INT32 is_disable);/*在使用GDI方式采集屏幕时, 如果需要采集WS_EX_LAYERED属性窗口,设置成1is_enable: 1表示采集WS_EX_LAYERED属性窗口, 0表示不采集WS_EX_LAYERED属性窗口. 默认系统是0,不采集.注意采集WS_EX_LAYERED属性窗口,鼠标会闪烁成功返回 NT_ERC_OK*/NT_UINT32(NT_API *EnableScreenCaptureLayeredWindow)(NT_HANDLE handle, NT_INT32 is_enable);/*这个接口主要判断顶层窗口能否能被捕获, 如果不能被捕获的话返回NT_ERC_FAILED如果返回NT_ERC_OK,表示可能能捕获*/NT_UINT32(NT_API *CheckCapturerWindow)(NT_HWND hwnd);/*设置要捕获的窗口的句柄*/NT_UINT32(NT_API *SetCaptureWindow)(NT_HANDLE handle, NT_HWND hwnd);/*设置帧率*/NT_UINT32(NT_API *SetFrameRate)(NT_HANDLE handle, NT_UINT32 frame_rate);/*+++摄像头相关接口+++*//*获取摄像头数量pNumer: 返回设备数量成功返回 NT_ERC_OK*/NT_UINT32(NT_API* GetVideoCaptureDeviceNumber)(NT_INT32* pNumer);/*返回摄像头设备信息device_index: 设备索引device_name_utf8:  设备名称,传NULL将不返回名称,如果不是NULL的话, device_name_length必须大于等于256, 返回utf8编码的设备名称device_name_length: 设备名称缓冲大小,如果device_name_utf8是NULL,则传入0, 否则必须大于等于256device_unique_id_utf8: 设备唯一ID, 传NULL将不返回ID,如果不传NULL的话,device_unique_id_length必须大于等于1024,返回utf8编码的设备IDdevice_unique_id_length: 设备唯一ID缓冲代销, 如果是device_unique_id_utf8NULL, 则传入0,否则必须大于等于1024成功返回 NT_ERC_OK*/NT_UINT32(NT_API* GetVideoCaptureDeviceInfo)(NT_INT32	device_index,NT_PSTR		device_name_utf8,NT_UINT32	device_name_length,NT_PSTR		device_unique_id_utf8,NT_UINT32	device_unique_id_length);/*返回摄像头能力数device_unique_id_utf8: 设备唯一idcapability_number: 返回的设备能力数成功返回 NT_ERC_OK*/NT_UINT32(NT_API* GetVideoCaptureDeviceCapabilityNumber)(NT_PCSTR device_unique_id_utf8,NT_INT32* capability_number);/*返回摄像头能力device_unique_id_utf8: 设备唯一id,device_capability_index: 设备能力索引capability: 设备能力成功返回 NT_ERC_OK*/NT_UINT32(NT_API* GetVideoCaptureDeviceCapability)(NT_PCSTR device_unique_id_utf8,NT_INT32 device_capability_index,NT_PB_VideoCaptureCapability* capability);/** 在多个实例推送多路时,对于一个摄像头来说,所有实例只能共享摄像头,那么只有一个实例可以改变摄像头分辨率,其他实例使用这个缩放后的图像.在使用多实例时,调用这个接口禁止掉实例的分辨率设置能力.只留一个实例能改变分辨,如果不设置,行为未定义.这个接口必须在 SetLayersConfig, AddLayerConfig 之前调用device_unique_id_utf8: 设备唯一id成功返回 NT_ERC_OK*/NT_UINT32(NT_API* DisableVideoCaptureResolutionSetting)(NT_HANDLE handle,NT_PCSTR device_unique_id_utf8);/*启动摄像头预览device_unique_id_utf8: 设备唯一idhwnd: 绘制的窗口句柄成功返回 NT_ERC_OK*/NT_UINT32(NT_API* StartVideoCaptureDevicePreview)(NT_PCSTR device_unique_id_utf8,NT_HWND hwnd);/**上下反转摄像头预览图像*is_flip: 1:表示反转, 0:表示不反转*/NT_UINT32(NT_API *FlipVerticalCameraPreview)(NT_HWND hwnd, NT_INT32 is_flip);/**水平反转摄像头预览图像*is_flip: 1:表示反转, 0:表示不反转*/NT_UINT32(NT_API *FlipHorizontalCameraPreview)(NT_HWND hwnd, NT_INT32 is_flip);/**旋转摄像头预览图像, 顺时针旋转degress: 设置0, 90, 180, 270度有效,其他值无效注意:除了0度,其他角度播放会耗费更多CPU*/NT_UINT32(NT_API *RotateCameraPreview)(NT_HWND hwnd, NT_INT32 degress);/*告诉SDK预览窗口大小改变hwnd: 绘制的窗口句柄成功返回 NT_ERC_OK*/NT_UINT32(NT_API* VideoCaptureDevicePreviewWindowSizeChanged)(NT_HWND hwnd);/*停止摄像头预览hwnd: 绘制的窗口句柄成功返回 NT_ERC_OK*/NT_UINT32(NT_API* StopVideoCaptureDevicePreview)(NT_HWND hwnd);/***************************//*****获取摄像头RBG32图像接口++//***************************//*调用流程:1. StartGetVideoCaptureDeviceImage 获取句柄,切保存句柄2. GetVideoCaptureDeviceImage 获取图像3. StopGetVideoCaptureDeviceImage 停止, 之后句柄将无效*//*调用此接口前置条件: 必须调用过Init接口, 否则会奔溃或失败pVideoCaptrueImageHandle: 要返回的句柄的指针,请不要和其他句柄搞混device_unique_id_utf8: 设备唯一id成功返回 NT_ERC_OK 并返回VideoCaptrueImageHandle句柄*/NT_UINT32(NT_API* StartGetVideoCaptureDeviceImage)(NT_PHANDLE pVideoCaptrueImageHandle,NT_PCSTR   device_unique_id_utf8);/**上下反转设备图像*is_flip: 1:表示反转, 0:表示不反转*/NT_UINT32(NT_API *FlipVerticalVideoCaptureDeviceImage)(NT_HANDLE videoCaptrueImageHandle, NT_INT32 is_flip);/**水平反转设备图像*is_flip: 1:表示反转, 0:表示不反转*/NT_UINT32(NT_API *FlipHorizontalVideoCaptureDeviceImage)(NT_HANDLE videoCaptrueImageHandle, NT_INT32 is_flip);/**旋转设备图像, 顺时针旋转degress: 设置0, 90, 180, 270度有效,其他值无效注意:除了0度,其他角度播放会耗费更多CPU*/NT_UINT32(NT_API *RotateVideoCaptureDeviceImage)(NT_HANDLE videoCaptrueImageHandle, NT_INT32 degress);/*调用这个接口可以获取摄像头图像videoCaptrueImageHandle: 句柄, 通过StartGetVideoCaptureDeviceImage得到的isDiscardImage: 1:表示取到图像后,就把SDK内部保存的图像删除掉, 0:表示取到图像后, SDK内部的图像不删除,那么下一次再调用这个接口的时候,如果摄像头没有产生新的图像,就会返回上次返回过的图像ppImage: 指向图像指针的指针,如果有图像的话, 会填充 *ppImage返回值:NT_ERC_OK: 表示取到图像, *ppImage必然有值NT_ERC_PB_NO_IMAGE: 表示SDK内部目前没有图像,需要等待摄像头产生图像其他值: 可能是其他错误,比如参数错误等等注意:1. 这个接口返回的图像 宽和高可能会变, 就是说每一次调用返回的图像宽高可能不一样2. 取到的图像是从上到下的*/NT_UINT32(NT_API* GetVideoCaptureDeviceImage)(NT_HANDLE     videoCaptrueImageHandle,NT_INT32      isDiscardImage,NT_PB_Image** ppImage);/*停止获取摄像头图像成功返回 NT_ERC_OK注意:必须在调用UnInit之前调用*/NT_UINT32(NT_API* StopGetVideoCaptureDeviceImage)(NT_HANDLE  videoCaptrueImageHandle);/***************************//*****获取摄像头RBA32图像接口--//***************************//*设置摄像头信息*/NT_UINT32(NT_API *SetVideoCaptureDeviceBaseParameter)(NT_HANDLE handle, NT_PCSTR device_unique_id_utf8, NT_UINT32 width, NT_UINT32 height);/**上下反转摄像头图像*is_flip: 1:表示反转, 0:表示不反转*/NT_UINT32(NT_API *FlipVerticalCamera)(NT_HANDLE handle, NT_INT32 is_flip);/**水平反转摄像头图像*is_flip: 1:表示反转, 0:表示不反转*/NT_UINT32(NT_API *FlipHorizontalCamera)(NT_HANDLE handle, NT_INT32 is_flip);/**旋转摄像头图像, 顺时针旋转degress: 设置0, 90, 180, 270度有效,其他值无效注意:除了0度,其他角度播放会耗费更多CPU*/NT_UINT32(NT_API *RotateCamera)(NT_HANDLE handle, NT_INT32 degress);/*---摄像头相关接口---*//*+++视频合成相关设置+++*//*设置视频合成层, 传入的是一个数组, 请正确填充每一层reserve: 这个参数保留, 当前请传0confs: 层配置数组count: 数组大小flag: 目前传0pReserve: 保留将来用成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetLayersConfig)(NT_HANDLE handle, NT_INT32 reserve, const NT_PB_LayerBaseConfig** confs, NT_INT32 count,NT_UINT32 flag, NT_PVOID pReserve);/*清除所有层配置,注意这个接口只能在推送或者录像之前调用,否则结果未定义这个接口主要是给C#使用,C++请直接使用SetLayersConfigreserve: 这个参数保留, 当前请传0flag: 目前传0pReserve: 保留将来用成功返回 NT_ERC_OK*/NT_UINT32 (NT_API *ClearLayersConfig)(NT_HANDLE handle, NT_INT32 reserve,NT_UINT32 flag, NT_PVOID pReserve);/*增加层配置,注意这个接口只能在推送或者录像之前调用,否则结果未定义这个接口主要是给C#使用,C++请直接使用SetLayersConfigreserve: 这个参数保留, 当前请传0conf: 配置层layer_type: 层类型flag: 目前传0pReserve: 保留将来用成功返回 NT_ERC_OK*/NT_UINT32 (NT_API *AddLayerConfig)(NT_HANDLE handle, NT_INT32 reserve,NT_PVOID conf, NT_INT32 layer_type,NT_UINT32 flag, NT_PVOID pReserve);/*动态禁止或者启用层index: 层索引, 不能是第0层,如果传0的话,会失败reserve: 保留字段,请传0is_enable: 1表示能用,0表示禁止, 其他值直接返回错误成功返回 NT_ERC_OK*/NT_UINT32(NT_API *EnableLayer)(NT_HANDLE handle, NT_INT32 reserve,NT_INT32 index, NT_INT32 is_enable);/*更新层相关配置, 注意不是层的所有字段都可以更新,只是部分可以更新,并且有些层没有字段可以更新,传入的参数,SDK只选择能更新的字段更新,不能更新的字段会被忽略reserve: 保留字段,请传0conf: 配置flag: 请传0pReserve: 保留字段,请传0成功返回 NT_ERC_OK*/NT_UINT32(NT_API * UpdateLayerConfig)(NT_HANDLE handle, NT_INT32 reserve,const NT_PB_LayerBaseConfig* conf, NT_UINT32 flag, NT_PVOID pReserve);/*这个接口是给C#使用的, C++请使用上面的UpdateLayerConfig接口更新层相关配置, 注意不是层的所有字段都可以更新,只是部分可以更新,并且有些层没有字段可以更新,传入的参数,SDK只选择能更新的字段更新,不能更新的字段会被忽略reserve: 保留字段,请传0conf: 配置flag: 请传0pReserve: 保留字段,请传0成功返回 NT_ERC_OK*/NT_UINT32(NT_API * UpdateLayerConfigV2)(NT_HANDLE handle, NT_INT32 reserve,NT_PVOID conf, NT_INT32 layer_type, NT_UINT32 flag, NT_PVOID pReserve);/*修改层区域pReserve: 保留字段,请传0成功返回 NT_ERC_OK*/NT_UINT32(NT_API *UpdateLayerRegion)(NT_HANDLE handle, NT_INT32 reserve,NT_INT32 index, const NT_PB_RectRegion* region);/*给index层投递Image数据,目前主要是用来把rgb和yuv视频数据传给相关层reserve: 保留字段,请传0index: 层索引image: 图像flag: 请传0pReserve: 保留字段,请传0成功返回 NT_ERC_OK*/NT_UINT32(NT_API * PostLayerImage)(NT_HANDLE handle, NT_INT32 reserve,NT_INT32 index, const NT_PB_Image* image, NT_UINT32 flag, NT_PVOID pReserve);/*---视频合成相关设置---*//*+++视频截屏相关接口+++*//*捕获图片file_name_utf8: 文件名称,utf8编码call_back_data: 回调时用户自定义数据call_back: 回调函数,用来通知用户截图已经完成或者失败成功返回 NT_ERC_OK只有在推送或者录像时调用才可能成功,其他情况下调用,返回错误.因为生成PNG文件比较耗时,一般需要几百毫秒,为防止CPU过高,SDK会限制截图请求数量,当超过一定数量时,调用这个接口会返回NT_ERC_PB_TOO_MANY_CAPTURE_IMAGE_REQUESTS. 这种情况下, 请延时一段时间,等SDK处理掉一些请求后,再尝试.*/NT_UINT32(NT_API* CaptureImage)(NT_HANDLE handle, NT_PCSTR file_name_utf8,NT_PVOID call_back_data, NT_PB_SDKCaptureImageCallBack call_back);/*---视频截屏相关接口---*//*+++视频编码相关接口+++*//*获取视频硬编码器信息数count: 返回的数量成功返回 NT_ERC_OK*/NT_UINT32(NT_API *GetHWVideoEncoderInfoCount)(NT_INT32* count);/*获取视频硬编码信息infos: 请先调用GetHWVideoEncoderInfoCount, 然后分配这个数组info_array_size: 分配的数组大小out_count: 实际返回的数量成功返回 NT_ERC_OK*/NT_UINT32(NT_API *GetHWVideoEncoderInfos)(NT_PB_HWVideoEncoderInfo* infos, NT_INT32 info_array_size, NT_INT32* out_count);/*设置软硬编码类型, 编码器, codec_id, 编码器其他参数.type: 0为软编码, 1为硬编码, 默认是软编码.encoder_id: 如果是软编码, 请设置0; 如果是硬编码, 128为NVIDIA video encoder (NVENC), 填其他值接口返回错误.param1: 如果是软编码,请设置0; 如果是硬编码且是NVENC, 这个参数用来设置GPU index, 设置-1的话SDK自动选择GPU.codec_id: 设置h264或h265编码, 默认是h264, 请参考NT_MEDIA_CODEC_ID,  h264填 NT_MEDIA_CODEC_ID_H264, h265填 NT_MEDIA_CODEC_ID_H265.注意: 软编码不支持h265, 硬编码根据实际硬件情况决定是否支持h265.如果调用了这个接口,请不要再调用SetVideoEncoderType接口成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetVideoEncoder)(NT_HANDLE handle, NT_INT32 type, NT_INT32 encoder_id, NT_UINT32 codec_id, NT_INT32 param1);/*这个接口已经废弃, 请使用SetVideoEncoder接口设置编码类型, 当前支持h264和h265(注意:h265只有64位sdk库支持, 在32位库上设置会失败)encoder_type: 1为h264, 2为h265, 默认为h264成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetVideoEncoderType)(NT_HANDLE handle, NT_INT32 encoder_type);/*注意,码率控制两种方式,要么是 SetVideoQuality(或者 SetVideoQualityV2) + SetVideoMaxBitRate要么是 SetVideoMaxBitRate  + SetVideoBitRate*//*设置视频质量, 范围[0-20], 默认是10, 值越小质量越好,但码率会越大建议用SetVideoQualityV2(注意:请看v2具体参数和范围)*/NT_UINT32(NT_API *SetVideoQuality)(NT_HANDLE handle, NT_INT32 quality);/*设置视频质量, 范围[1-50], 值越小视频质量越好,但码率会越大. 请优先考虑默认值,对于H264, 默认值23对于H265, 默认值28*/NT_UINT32(NT_API *SetVideoQualityV2)(NT_HANDLE handle, NT_INT32 quality);/*设置最大视频码率, 单位kbps*/NT_UINT32(NT_API *SetVideoMaxBitRate)(NT_HANDLE handle, NT_INT32 kbit_rate);/*设置视频码率, 单位kbps, 默认是0,不使用平均码率方式*/NT_UINT32(NT_API *SetVideoBitRate)(NT_HANDLE handle, NT_INT32 kbit_rate);/** 在一些特殊场景下, 视频分辨率会改变, 如果设置一个固定码率的的话,当视频分辨率变大的时候会变的模糊,变小的话又会浪费码率* 所以提供可以设置一组码率的接口,满足不同分辨率切换的需求* 规则: 比如设置两组分辨率 640*360, 640*480, 那么当分辨率小于等于640*360时都使用640*360的码率,* 当分辨率大于640*360且小于等于640*480时,就使用640*480的码率,如果分辨率大于640*480 那就使用640*480的分辨率* 为了设置的更准确, 建议多划分几组, 让区间变小* 调用这个接口每次设置一组,设置多组就调用多次**/NT_UINT32(NT_API* AddVideoEncoderBitrateGroupItem)(NT_HANDLE handle, const NT_PB_VideoEncoderBitrateGroupItem* item);/*清除视频码率组*/NT_UINT32(NT_API* ClearVideoEncoderBitrateGroup)(NT_HANDLE handle);/*设置关键帧间隔, 比如1表示所有帧都是关键帧,10表示每10帧里面一个关键帧,25表示每25帧一个关键帧*/NT_UINT32(NT_API *SetVideoKeyFrameInterval)(NT_HANDLE handle, NT_INT32 interval);/*设置H264 profile.profile: 1: H264 baseline(默认值). 2: H264 main. 3. H264 high成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetVideoEncoderProfile)(NT_HANDLE handle, NT_INT32 profile);/*设置视频编码速度speed: 范围是 1 到 6,  值越小,速度越快,质量也越差*/NT_UINT32(NT_API *SetVideoEncoderSpeed)(NT_HANDLE handle, NT_INT32 speed);/*设置是否对图像进行相同比较,相同图像比较一般在采集桌面时有一定好处,可能能降低码率is_compare_image: 1:表示比较, 0:表示不比较, 其他值无效max_frame_interval: */NT_UINT32(NT_API *SetVideoCompareSameImage)(NT_HANDLE handle, NT_INT32 is_compare_image,NT_UINT32 max_frame_interval);/*设置视频最大关键帧间隔, 这个接口一般不使用,这里是用来配合SetVideoCompareSameImage接口的.比如开启图像比较后,SDK发现连续20s图像都是相同的,但播放端需要收到关键帧才能解码播放,所以需要一个限制.interval:单位是毫秒, 请和SetVideoKeyFrameInterval接口区分开,他们的参数设置方式是不同的*/NT_UINT32(NT_API *SetVideoMaxKeyFrameInterval)(NT_HANDLE handle, NT_INT32 interval);/*---视频编码相关接口---*//*+++音频相关接口+++*//*获取系统音频输入设备数*/NT_UINT32(NT_API* GetAuidoInputDeviceNumber)(NT_INT32* pNumer);/*获取音频输入设备名称device_id: 设备ID,需要输入, 从0开始,最大值不能超过设备数device_name_buff: 设备名称,返回的字符串以0结尾device_name_buff_size: 设备名称buffer的大小,建议512*/NT_UINT32(NT_API* GetAuidoInputDeviceName)(NT_UINT32 device_id, NT_PSTR device_name_buff, NT_UINT32 device_name_buff_size);/**设置推送音频编码类型*type: 1:使用AAC编码, 2:使用speex编码, 其他值返回错误*成功返回 NT_ERC_OK*/NT_UINT32(NT_API* SetPublisherAudioCodecType)(NT_HANDLE handle, NT_INT32 type);/**设置推送Speex编码质量*quality: 范围是0-10, 默认是8:大约28kbps, 值越大,质量越好,码率也越大*成功返回 NT_ERC_OK*/NT_UINT32(NT_API* SetPublisherSpeexEncoderQuality)(NT_HANDLE handle, NT_INT32 quality);/*设置推送静音is_mute: 0表示不静音, 1表示静音*/NT_UINT32(NT_API* SetMute)(NT_HANDLE handle, NT_INT32 is_mute);/*设置音频输入设备IDdevice_id: 设备id, 一般从0开始 */NT_UINT32(NT_API* SetAuidoInputDeviceId)(NT_HANDLE handle, NT_UINT32 device_id);/*检查是否能捕获扬声器音频out_flag: 1表示可以捕获扬声器,0:表示不可以捕获扬声器*/NT_UINT32(NT_API* IsCanCaptureSpeaker)(NT_INT32* out_flag);/**设置采集扬声器时是否补偿静音帧 这个只在auido_option是NT_PB_E_AUDIO_OPTION_CAPTURE_SPEAKER有效*is_compensation: 1表示补偿, 0表示补偿, 设置其他值无效*成功返回 NT_ERC_OK*/NT_UINT32(NT_API* SetCaptureSpeakerCompensateMute)(NT_HANDLE handle, NT_INT32 is_compensation);/**设置回音消除*isCancel: 1表示消除回音, 0表示不消除回音*delay: 回音时延,单位是毫秒,目前推荐设置100ms, 如果设置为0的话,将使用100ms*注意这个只对麦克风捕获有作用,扬声器捕获无效*成功返回 NT_ERC_OK*/NT_UINT32(NT_API* SetEchoCancellation)(NT_HANDLE handle, NT_INT32 isCancel, NT_INT32 delay);/**设置音频噪音抑制*isNS: 1表示噪音抑制, 0表示不抑制*注意,这个一般用在采集麦克风上,采集系统播放声音时必须要性不大*成功返回 NT_ERC_OK*/NT_UINT32(NT_API* SetNoiseSuppression)(NT_HANDLE handle, NT_INT32 isNS);/**设置音频自动增益控制*isAGC: 1表示增益控制, 0表示不控制*注意,这个一般用在采集麦克风上,采集系统播放声音时必须要性不大*成功返回 NT_ERC_OK*/NT_UINT32(NT_API* SetAGC)(NT_HANDLE handle, NT_INT32 isAGC);/**设置端点检测(Voice Activity Detection (VAD))*isVAD: 1表示端点检测, 0表示不检测*注意,这个一般用在采集麦克风上,采集系统播放音乐声音时效果不好*成功返回 NT_ERC_OK*/NT_UINT32(NT_API* SetVAD)(NT_HANDLE handle, NT_INT32 isVAD);/**设置输入音量, 这个接口一般不建议调用, 在一些特殊情况下可能会用, 一般不建议放大音量*index: 一般是0和1, 如果没有混音的只用0, 有混音的话, 0,1分别设置音量*volume: 音量,默认是1.0,范围是[0.0, 5.0], 设置成0静音, 1音量不变*成功返回 NT_ERC_OK*/NT_UINT32(NT_API* SetInputAudioVolume)(NT_HANDLE handle, NT_INT32 index, float volume);/*---音频相关接口---*//*+++推送相关接口+++*//*设置推送的URL支持同时推送到多个RTMP服务器上, 最多可以同时支持推到三个服务器上为设置多个URL,请调用多次成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetURL)(NT_HANDLE handle, NT_PCSTR url, NT_PVOID pReserve);/*设置rtmp推送加密选项url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致is_encrypt_video: 1:表示视频加密, 0:表示视频不加密, 默认不加密, 其他值返回错误is_encrypt_audio: 1:表示音频加密, 0:表示音频不加密, 默认不加密, 其他值返回错误成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtmpEncryptionOption)(NT_HANDLE handle, NT_PCSTR url, NT_INT32 is_encrypt_video, NT_INT32 is_encrypt_audio);/*设置rtmp加密算法url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致encryption_algorithm: 加密算法, 当前支持aes和国标sm4. 1为aes, 2为sm4, 默认为aes.*/NT_UINT32(NT_API *SetRtmpEncryptionAlgorithm)(NT_HANDLE handle, NT_PCSTR url, NT_INT32 encryption_algorithm);/*设置rtmp推送加密密钥url: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致key:加密密钥key_size: 如果加密算法是aes, key_size必须是16, 24, 32 这三个值, 其他返回错误; 如果加密算法是sm4, key_size必须是16, 其他值返回错误.成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtmpEncryptionKey)(NT_HANDLE handle, NT_PCSTR url, const NT_BYTE* key, NT_UINT32 key_size);/*设置rtmp推送加密IV(初始化向量), 这个接口不调用的话, 将使用默认IVurl: 考虑到可能推送到多个服务器,可以根据推送url配置不同的加密选项, 请确保url和SetURL一致iv: 初始化向量iv_size: 当前必须是16, 其他值返回错误成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtmpEncryptionIV)(NT_HANDLE handle, NT_PCSTR url, const NT_BYTE* iv, NT_UINT32 iv_size);/**设置视频包时间戳回调url:推送urlmin_call_interval:最小回调时间间隔(单位是毫秒), 如果是0的话,发送每个视频包时都会回调callbackdata:回调时用户自定义数据call_back:回调函数指针*/NT_UINT32(NT_API *SetVideoPacketTimestampCallBack)(NT_HANDLE handle,NT_PCSTR url, NT_UINT32 min_call_interval,NT_PVOID call_back_data, NT_PB_SDKVideoPacketTimestampCallBack call_back);/*设置推送状态回调call_back_data: 回调时用户自定义数据call_back*/NT_UINT32(NT_API *SetPublisherStatusCallBack)(NT_HANDLE handle,NT_PVOID call_back_data, NT_PB_SDKPublisherStatusCallBack call_back);/*启动推送*/NT_UINT32(NT_API *StartPublisher)(NT_HANDLE handle, NT_PVOID pReserve);/*停止推送*/NT_UINT32(NT_API *StopPublisher)(NT_HANDLE handle);/*---推送相关接口---*//*+++发布rtsp流相关接口+++*//** 设置rtsp的流名称* stream_name: 流程名称,不能为空字符串,必须是英文* 这个作用是: 比如rtsp的url是:rtsp://192.168.0.111/test, test就是设置下去的stream_name* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtspStreamName)(NT_HANDLE handle, NT_PCSTR stream_name);/** 给要发布的rtsp流设置rtsp server, 一个流可以发布到多个rtsp server上,rtsp server的创建启动请参考OpenRtspServer和StartRtspServer接口* handle: 推送实例句柄* rtsp_server_handle:rtsp server句柄 * reserve: 保留参数,传0*/NT_UINT32(NT_API *AddRtspStreamServer)(NT_HANDLE handle, NT_HANDLE rtsp_server_handle, NT_INT32 reserve);/** 清除设置的rtsp server*/NT_UINT32(NT_API *ClearRtspStreamServer)(NT_HANDLE handle);/*启动rtsp流reserve: 保留参数,传0*/NT_UINT32(NT_API *StartRtspStream)(NT_HANDLE handle, NT_INT32 reserve);/*停止rtsp流*/NT_UINT32(NT_API *StopRtspStream)(NT_HANDLE handle);/*---发布rtsp流相关接口---*//*+++推送rtsp相关接口+++*//*设置推送rtsp传输方式transport_protocol: 1表示UDP传输rtp包; 2表示TCP传输rtp包. 默认是1, UDP传输. 传其他值SDK报错。成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetPushRtspTransportProtocol)(NT_HANDLE handle, NT_INT32 transport_protocol);/*设置推送RTSP的URL成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetPushRtspURL)(NT_HANDLE handle, NT_PCSTR url);/*启动推送RTSP流reserve: 保留参数,传0*/NT_UINT32(NT_API *StartPushRtsp)(NT_HANDLE handle, NT_INT32 reserve);/*停止推送RTSP流*/NT_UINT32(NT_API *StopPushRtsp)(NT_HANDLE handle);/*---推送rtsp相关接口---*//*+++录像相关接口+++*//*设置本地录像目录, 必须是英文目录,否则会失败*/NT_UINT32(NT_API *SetRecorderDirectory)(NT_HANDLE handle, NT_PCSTR dir, NT_PVOID pReserve);/*设置单个录像文件最大大小, 当超过这个值的时候,将切割成第二个文件size: 单位是KB(1024Byte), 当前范围是 [5MB-1GB], 超出将被设置到范围内*/NT_UINT32(NT_API *SetRecorderFileMaxSize)(NT_HANDLE handle, NT_UINT32 size);/*设置录像文件名生成规则*/NT_UINT32(NT_API *SetRecorderFileNameRuler)(NT_HANDLE handle, NT_PB_RecorderFileNameRuler* ruler);/*启动录像*/NT_UINT32(NT_API *StartRecorder)(NT_HANDLE handle, NT_PVOID pReserve);/*暂停录像is_pause: 1表示暂停, 0表示恢复录像, 输入其他值将调用失败成功返回NT_ERC_OK返回NT_ERC_PB_NEED_RETRY, 请隔一段时间再尝试调用*/NT_UINT32(NT_API *PauseRecorder)(NT_HANDLE hanlde, NT_INT32 is_pause);/*停止录像*/NT_UINT32(NT_API *StopRecorder)(NT_HANDLE handle);/*---录像相关接口---*//*+++预览相关接口+++*//*设置预览图像回调image_format: 请参考NT_PB_E_IMAGE_FORMAT,只能是NT_PB_E_IMAGE_FORMAT_RGB32, NT_PB_E_IMAGE_FORMAT_I420*/NT_UINT32(NT_API *SetVideoPreviewImageCallBack)(NT_HANDLE handle,NT_INT32 image_format,NT_PVOID call_back_data, NT_PB_SDKVideoPreviewImageCallBack call_back);/*启动预览reserve1: 保留参数传0pReserve2: 保留参数传NULL*/NT_UINT32(NT_API *StartPreview)(NT_HANDLE handle, NT_UINT32 reserve1, NT_PVOID pReserve2);/*停止预览*/NT_UINT32(NT_API *StopPreview)(NT_HANDLE handle);/*---预览相关接口---*//** 投递编码过的视频数据给SDK* codec_id:请参考NT_MEDIA_CODEC_ID, 注意不要传递auido codec id,否则结果没有定义* data: 编码数据* size: 编码数据大小* is_key_frame: 1:表示是关键帧, 0:表示不是* timestamp: 时间戳* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *PostVideoEncodedData)(NT_HANDLE handle, NT_UINT32 codec_id, const NT_BYTE* data, NT_UINT32 size,NT_INT32 is_key_frame, NT_UINT64 timestamp);/** 投递编码过的视频数据给SDK V2版 * codec_id:请参考NT_MEDIA_CODEC_ID, 注意不要传递auido codec id,否则结果没有定义* data: 编码数据* size: 编码数据大小* is_key_frame: 1:表示是关键帧, 0:表示不是* timestamp: 解码时间戳* presentation_timestamp: 显示时间戳* 注意:请确保 presentation_timestamp >= timestamp, 否则结果未定义* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *PostVideoEncodedDataV2)(NT_HANDLE handle, NT_UINT32 codec_id,const NT_BYTE* data, NT_UINT32 size,NT_INT32 is_key_frame, NT_UINT64 timestamp, NT_UINT64 presentation_timestamp);/** 投递编码过的音频数据给SDK*codec_id:请参考NT_MEDIA_CODEC_ID, 注意不要传递video codec id,否则结果没有定义* data: 编码数据* size: 编码数据大小* is_key_frame: 1:表示是关键帧, 0:表示不是* timestamp: 时间戳* parameter_info: 当编码是aac的时候,这个是AudioSpecificConfig, 其他编码请传NULL* parameter_info_size: parameter_info 长度* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *PostAudioEncodedData)(NT_HANDLE handle, NT_UINT32 codec_id,const NT_BYTE* data, NT_UINT32 size,NT_INT32 is_key_frame, NT_UINT64 timestamp,const NT_BYTE*  parameter_info,NT_UINT32 parameter_info_size);/** 投递PCM音频数据给SDK, 每10ms音频数据传入一次**  data: pcm数据, 注意每个采样必须是16位的,其他格式不支持, 注意双通道的话数据是交错的*  size: pcm数据大小*  timestamp:时间戳单位是毫秒,必须是递增的*  sample_rate: 采样率*  channels: 通道, 当前通道只支持1和2,也就是单通道和双通道*  per_channel_sample_number: 这个请传入的是 sampleRate/100, 也就是单个通道的10毫秒的采样数*/NT_UINT32(NT_API *PostAudioPCMData)(NT_HANDLE handle,const NT_BYTE* data, NT_UINT32 size, NT_UINT64 timestamp,NT_INT32 sample_rate, NT_INT32 channels, NT_INT32 per_channel_sample_number);/*** 投递用来混音的PCM音频数据给SDK, 每10ms音频数据传入一次* 这个接口只有在auido_option是NT_PB_E_AUDIO_OPTION_MIC_EXTERNAL_PCM_MIXER使用,其他情况下报错* 当前只支持一路外部音频和内置麦克风混音**  data: pcm数据, 注意每个采样必须是16位的,其他格式不支持, 注意双通道的话数据是交错的*  size: pcm数据大小*  timestamp:时间戳单位是毫秒,必须是递增的*  sample_rate: 采样率*  channels: 通道, 当前通道只支持1和2,也就是单通道和双通道*  per_channel_sample_number: 这个请传入的是 sampleRate/100, 也就是单个通道的10毫秒的采样数*/NT_UINT32(NT_API *PostAudioExternalPCMMixerData)(NT_HANDLE handle,const NT_BYTE* data, NT_UINT32 size, NT_UINT64 timestamp,NT_INT32 sample_rate, NT_INT32 channels, NT_INT32 per_channel_sample_number);/*++++发送用户自定义数据相关接口++++*//** 1. 目前使用sei机制发送用户自定数据到播放端* 2. 这种机制有可能会丢失数据, 所以这种方式不保证接收端一定能收到* 3. 优势:能和视频保持同步,虽然有可能丢失,但一般的需求都满足了* 4. 目前提供两种发送方式 第一种发送二进制数据, 第二种发送 utf8字符串*//** 设置发送队列大小,为保证实时性,默认大小为3, 必须设置一个大于0的数* 如果数据超过队列大小,将丢掉队头数据* 这个接口请在 StartPublisher 之前调用*/NT_UINT32(NT_API *SetPostUserDataQueueMaxSize)(NT_HANDLE handle, NT_INT32 max_size, NT_INT32 reserve);/** 清空用户数据队列, 有些情况可能会用到,比如发送队列里面有4条消息再等待发送,又想把最新的消息快速发出去, 可以 * 先清除掉正在排队消息, 再调用PostUserXXX  **/NT_UINT32(NT_API *ClearPostUserDataQueue)(NT_HANDLE handle);/** 发送二进制数据* data: 二进制数据* size:数据大小* 注意: 1.目前数据大小限制在256个字节以内,太大可能会影响视频传输,如果有特殊需求,需要增大限制,请联系我们* 2. 如果积累的数据超过了设置的队列大小,之前的队头数据将被丢弃* 3. 必须再调用StartPublisher之后再发送数据*/NT_UINT32(NT_API *PostUserData)(NT_HANDLE handle, const NT_BYTE* data, NT_UINT32 size, NT_INT32 reserve);/** 发送utf8字符串* utf8_str: utf8字符串* 注意: 1. 字符串长度不能超过256, 太大可能会影响视频传输,如果有特殊需求,需要增大限制,请联系我们* 2. 如果积累的数据超过了设置的队列大小,之前的队头数据将被丢弃* 3. 必须再调用StartPublisher之后再发送数据*/NT_UINT32(NT_API *PostUserUTF8StringData)(NT_HANDLE handle, NT_PCSTR utf8_str, NT_INT32 reserve);/*----发送用户自定义数据相关接口----*//*设置休眠模式mode: 1表示休眠, 0表示不休眠reserve: 保留参数, 当前传0成功返回NT_ERC_OK*/NT_UINT32(NT_API *SetSleepMode)(NT_HANDLE hanlde, NT_INT32 mode, NT_INT32 reserve);/*万能接口, 设置参数, 大多数问题, 这些接口都能解决*/NT_UINT32(NT_API *SetParam)(NT_HANDLE handle, NT_UINT32 id, NT_PVOID pData);/*万能接口, 得到参数, 大多数问题,这些接口都能解决*/NT_UINT32(NT_API *GetParam)(NT_HANDLE handle, NT_UINT32 id, NT_PVOID pData);/*+++屏幕选取工具+++*//*注意这个接口返回的句柄,一定要和上面的推送时用的Open接口返回的句柄区分开,完全是不同的句柄,用错结果未定义*//*mode: 请参考NT_PB_E_SCREEN_REGION_CHOOSE_MODEmode_data: mode == NT_PB_E_SCREEN_REGION_CHOOSE_MODE_CHOOSE, mode_data 是NULL.mode == NT_PB_E_SCREEN_REGION_CHOOSE_MODE_MOVE, mode_data 是NT_PB_RectRegion*callback: 这个必须要有,并且必须处理, 否则资源泄漏callback_data: callback dataflag目前传0,后面扩展用, pReserve传NULL,扩展用,打开一个屏幕选取工具的toolHandle成功返回 NT_ERC_OK*/NT_UINT32(NT_API *OpenScreenRegionChooseTool)(NT_PHANDLE pToolHandle,NT_UINT32 mode, NT_PVOID  mode_data,NT_PB_SDKScreenRegionChooseCallBack callback,NT_PVOID callback_data,NT_UINT32 flag, NT_PVOID pReserve);/*调用这个接口之后toolHandle失效,成功返回 NT_ERC_OK*/NT_UINT32(NT_API *CloseScreenRegionChooseTool)(NT_HANDLE toolHandle);/*---屏幕选取工具---*//*+++rtsp server操作接口+++*//** 创建一个rtsp server * pRtspServerHandle: rtsp server 句柄* reserve:保留参数传0* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *OpenRtspServer)(NT_PHANDLE pRtspServerHandle, NT_INT32 reserve);/** 设置rtsp server 监听端口, 在StartRtspServer之前必须要设置端口* rtsp_server_handle: rtsp server 句柄* port: 端口号,可以设置为554,或者是1024到65535之间,其他值返回失败* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtspServerPort)(NT_HANDLE rtsp_server_handle, NT_INT32 port);/** 设置rtsp server 鉴权用户名和密码, 这个可以不设置,只有需要鉴权的再设置* rtsp_server_handle: rtsp server 句柄* user_name: 用户名,必须是英文* password:密码,必须是英文* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtspServerUserNamePassword)(NT_HANDLE rtsp_server_handle, NT_PCSTR user_name, NT_PCSTR password);/** 设置rtsp server 组播, 如果server设置成组播就不能单播,组播和单播只能选一个, 一般来说单播网络设备支持的好,wifi组播很多路由器不支持* rtsp_server_handle: rtsp server 句柄* is_multicast: 是否组播, 1为组播, 0为单播, 其他值接口返回错误, 默认是单播* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtspServerMulticast)(NT_HANDLE rtsp_server_handle, NT_INT32 is_multicast);/** 设置rtsp server 组播组播地址 * rtsp_server_handle: rtsp server 句柄* multicast_address: 组播地址* 如果设置的不是组播地址, 将返回错误* 组播地址范围说明: [224.0.0.0, 224.0.0.255] 为组播预留地址, 不能设置. 可设置范围为[224.0.1.0, 239.255.255.255], 其中SSM地址范围为[232.0.0.0, 232.255.255.255]* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *SetRtspServerMulticastAddress)(NT_HANDLE rtsp_server_handle, NT_PCSTR multicast_address);/** 获取rtsp server当前的客户会话数, 这个接口必须在StartRtspServer之后再调用* rtsp_server_handle: rtsp server 句柄* session_numbers: 会话数* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *GetRtspServerClientSessionNumbers)(NT_HANDLE rtsp_server_handle, NT_INT32* session_numbers);/** 启动rtsp server* rtsp_server_handle: rtsp server 句柄* reserve: 保留参数传0* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *StartRtspServer)(NT_HANDLE rtsp_server_handle, NT_INT32 reserve);/** 停止rtsp server* rtsp_server_handle: rtsp server 句柄* 成功返回 NT_ERC_OK*/NT_UINT32(NT_API *StopRtspServer)(NT_HANDLE rtsp_server_handle);/** 关闭rtsp server* 调用这个接口之后rtsp_server_handle失效,* 成功返回 NT_ERC_OK*/NT_UINT32 (NT_API *CloseRtspServer)(NT_HANDLE rtsp_server_handle);/*---rtsp server操作接口---*//*+++ NT_PB_Image 操作函数+++*/NT_SmartPublisherImageSDKAPI ImageAPI_;/*--- NT_PB_Image 操作函数---*//*+++绘制操作+++*/NT_SmartPublisherDrawImageSDKAPI drawImageAPI_;/*---绘制操作---*/} NT_SmartPublisherSDKAPI;NT_UINT32 NT_API NT_GetSmartPublisherSDKAPI(NT_SmartPublisherSDKAPI* pAPI);/*reserve1: 请传0NT_PVOID: 请传NULL成功返回: NT_ERC_OK*/NT_UINT32 NT_API NT_PB_SetSDKClientKey(NT_PCSTR cid, NT_PCSTR key, NT_INT32 reserve1, NT_PVOID reserve2);#ifdef __cplusplus
}
#endif#endif

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/553086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android平台Camera2数据如何对接RTMP推流到服务器

1. Camera2架构 在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用的API1(android.hardware.camera)就被标为 Deprecated 了。 Camera API2相较于API1有很大不同, 并且API2是为了配合HAL3进行使用的, API2有很多API…

IE浏览器下如何低延迟播放RTSP或RTMP流

首先,虽然本文是介绍IE浏览器下OCX控件播放RTSP或RTMP,但这种方式并不推荐,毕竟它只能用于IE浏览器环境下,局限太大,而且随着微软IE浏览器的更新,不确定后续支持情况。当然,话说回来&#xff0c…

Windows平台RTMP播放器/RTSP播放器如何在播放窗口添加OSD文字叠加

好多开发者在做Windows平台特别是单屏多画面显示时,希望像监控摄像机一样,可以在播放画面添加OSD台标,以实现字符叠加效果,大多开发者可很轻松的实现以上效果,针对此,本文以大牛直播SDK (Github…

Windows平台Unity3d下如何同时播放多路RTSP或RTMP流

好多开发者在做AR、VR或者教育类产品时,苦于如何在windows平台构建一个稳定且低延迟的RTSP或者RTMP播放器,如果基于Unity3d完全重新开发一个播放器,代价大、而且周期长,不适合快速出产品,我们认为当前最好的方式就是集…

Vscode —— 解决Vscode终端无法使用npm的命令的问题

在cmd中可以正常执行npm -v等指令,但是在vs code终端中,无法执行npm -v,node -v等指令 出现报错 解决办法👇 方法一:【右键单击Vscode】以【管理员身份运行】,【重启Vscode】 方法二:①【用户变量】的【path】添加npm所在路径的…

浏览器播放RTSP视频流几种解决方案

方案一: H5 websocket_rtsp_proxy 实现视频流直播 Streamedian 提供了一种“html5_rtsp_player websock_rtsp_proxy”的技术方案,可以通过html5的video标签直接播放RTSP的视频流。 整个架构如下图所示,分为服务器端和浏览器端两部分: 方案…

如何用轻量级RTSP服务本地生成RTSP测试URL

最近发现好多开发者都在搜索可用的RTSP测试URL,目前公网实际可测试的RTSP URL非常少,即便是可用,分辨率和网络也非常差,不适合长期测试。 针对此,我们的建议是最好直接网上买个海康或大华的摄像头,一般来说…

Windows平台RTSP|RTMP播放端SDK集成说明

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-…

如何实现Android端获取RTSP|RTMP流转推RTMP

技术背景 最近不少开发者找到我们,他们在做智能家居等传统行业时,希望实现在Android板件拉取本地的RTSP或RTMP流,然后对外推送RTMP出去,亦或内部启个轻量级RTSP服务,提供个对外对接的媒介URL,简单来说&…

QT实现低延迟的RTSP、RTMP播放器

好多开发者在QT环境下实现RTMP或RTSP播放时,首先考虑到的是集成VLC,集成后,却发现VLC在延迟、断网重连、稳定性等各个方面不尽人意,无法满足上线环境需求。本文以调用大牛直播SDK(官方)的Windows平台播放端…

Android对接实现内网无纸化会议|智慧教室|实时同屏功能

背景 本文主要讲的是基于Android平台实现RTMP的技术方案设计,基础架构图如下: 组网注意事项 1. 组网:无线组网,需要好的AP模块才能撑得住大的并发流量,推送端到AP,最好是有线网链接; 2. 服务…

Windows平台RTMP推送|轻量级RTSP服务实现本地摄像头|屏幕|叠加数据预览

背景 大家在做Windows平台RTMP推送或轻量级RTSP服务的时候,不管是采集屏幕还是采集摄像头,亦或屏幕摄像头的叠加模式,总会有这样的诉求,采集到的数据,希望能本地看看具体采集的数据或者图像实际效果,也就是…

Windows平台RTMP|RTSP播放器为什么要兼容GDI绘制

为什么要支持GDI 先说结论,Windows平台播放渲染这块,一般来说99%以上的机器都是支持D3D的,实现GDI模式绘制,除了为了好的兼容性外,在远程连接的场景下,D3D创建不成功,需要使用GDI模式。 简单来…

Android平台实现Unity3D下RTMP推送

像Unity3D下的RTMP或RTSP播放器一样,好多开发者苦于在Unity环境下,如何高效率低延迟的把数据采集并编码实时推送到流媒体服务器,实现Unity场景下的低延迟推拉流方案。 关于屏幕采集,有两种方案: 1. 直接封装Android原…

Windows平台实现Unity下窗体|摄像头|屏幕采集推送

技术背景 随着Unity3D的应用范围越来越广,越来越多的行业开始基于Unity3D开发产品,如传统行业中虚拟仿真教育、航空工业、室内设计、城市规划、工业仿真等领域。 基于此,好多开发者苦于在Unity环境下,没有低延迟的推拉流解决方案…

数据推送选择GB28181、RTSP还是RTMP?

GB/T28181 国标GB/T28181协议全称《安全防范视频监控联网系统信息传输、交换、控制技术要求》,是一个定义视频联网传输和设备控制标准的白皮书,由公安部科技信息化局提出,该标准规定了城市监控报警联网系统中信息传输、交换、控制的互联结构…

Android平台基于RTMP或RTSP的一对一音视频互动技术方案探讨

背景 随着智能门禁等物联网产品的普及,越来越多的开发者对音视频互动体验提出了更高的要求。目前市面上大多一对一互动都是基于WebRTC,优点不再赘述,我们这里先说说可能需要面临的问题:WebRTC的服务器部署非常复杂,可…

Android前端音视频数据接入GB28181平台意义

技术背景 在我们研发Android平台GB28181前端音视频接入模块之前,业内听到最多的是,如何用Android或者Windows端,在没有国标IPC设备的前提下,模拟GB28181的信令和媒体流交互流程,实现GB28181整体方案的测试&#xff1f…

std::atomic和std::mutex区别

​std::atomic介绍​ ​模板类std::atomic是C11提供的原子操作类型&#xff0c;头文件 #include<atomic>。​在多线程调用下&#xff0c;利用std::atomic可实现数据结构的无锁设计。​​ ​和互斥量的不同之处在于&#xff0c;std::atomic原子操作&#xff0c;主要是保…

C++ std::remove/std::remove_if/erase用法探讨

​std::remove 不会改变输入vector/string的长度。其过程相当于去除指定的字符&#xff0c;剩余字符往前靠。后面的和原始字符保持一致。​ 需要注意的是&#xff0c;remove函数是通过覆盖移去的&#xff0c;如果容器最后一个值刚好是需要删除的&#xff0c;则它无法覆盖掉容器…