跨平台屏幕/摄像头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_OPTION
		flag目前传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属性窗口,设置成1
		is_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, 否则必须大于等于256
		 device_unique_id_utf8: 设备唯一ID, 传NULL将不返回ID,如果不传NULL的话,device_unique_id_length必须大于等于1024,返回utf8编码的设备ID
		 device_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: 设备唯一id
		capability_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: 设备唯一id
		hwnd: 绘制的窗口句柄
		成功返回 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: 这个参数保留, 当前请传0
		confs: 层配置数组
		count: 数组大小
		flag: 目前传0
		pReserve: 保留将来用
		成功返回 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++请直接使用SetLayersConfig
		reserve: 这个参数保留, 当前请传0
		flag: 目前传0
		pReserve: 保留将来用
		成功返回 NT_ERC_OK
		*/
		NT_UINT32 (NT_API *ClearLayersConfig)(NT_HANDLE handle, NT_INT32 reserve,
			NT_UINT32 flag, NT_PVOID pReserve);


		/*
		增加层配置,注意这个接口只能在推送或者录像之前调用,否则结果未定义
		这个接口主要是给C#使用,C++请直接使用SetLayersConfig
		reserve: 这个参数保留, 当前请传0
		conf: 配置层
		layer_type: 层类型
		flag: 目前传0
		pReserve: 保留将来用
		成功返回 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: 保留字段,请传0
		is_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: 保留字段,请传0
		conf: 配置
		flag: 请传0
		pReserve: 保留字段,请传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: 保留字段,请传0
		conf: 配置
		flag: 请传0
		pReserve: 保留字段,请传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: 保留字段,请传0
		index: 层索引
		image: 图像
		flag: 请传0
		pReserve: 保留字段,请传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);

		/*
		设置音频输入设备ID
		device_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(初始化向量), 这个接口不调用的话, 将使用默认IV
		url: 考虑到可能推送到多个服务器,可以根据推送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:推送url
		min_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: 保留参数传0
		pReserve2: 保留参数传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_MODE
		 mode_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 data
		 flag目前传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: 请传0
	NT_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

 

posted @   音视频牛哥  阅读(0)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示