更新时间:2024-06-04 10:29:32下载pdf
除了实时视频直播,存储卡录像播放以外,IPC SDK 还提供了一些额外的音视频能力。
无论是视频直播,还是录像回放,当视频成功开始播放以后,用户都可以将当前正在播放的视频录制到手机中。
接口说明
录制视频并保存到手机系统相册。
- (void)startRecord;
接口说明
录制视频保存到指定路径。
- (void)startRecordWithFilePath:(NSString *)filePath;
参数说明
参数 | 说明 |
---|---|
filePath | 保存视频的文件路径,视频保存为 MP4 文件,文件路径需要有 .mp4 后缀 |
接口说明
停止录制,并保存文件。
- (void)stopRecord;
接口说明
视频开始录制的代理回调。
- (void)cameraDidStartRecord:(id<ThingSmartCameraType>)camera;
接口说明
视频停止录制并成功保存视频文件的代理回调。
- (void)cameraDidStopRecord:(id<ThingSmartCameraType>)camera;
调用开始录制和停止录制均有可能会失败,失败后将通过代理方法 -(void)camera:didOccurredErrorAtStep: specificErrorCode:;
返回错误信息。
示例代码
Objective-C:
- (void)startRecord {
if (self.isRecording) {
return;
}
// 在视频播放中才能开启录制
if (self.previewing || self.playbacking) {
[self.camera startRecord];
self.recording = YES;
}
}
- (void)stopRecord {
if (self.isRecording) {
[self.camera stopRecord];
self.recording = NO;
}
}
- (void)cameraDidStartRecord:(id<ThingSmartCameraType>)camera {
// 已成功开启视频录制,更新 UI
}
- (void)cameraDidStopRecord:(id<ThingSmartCameraType>)camera {
// 视频录制已停止,并且录制的视频成功保存
}
- (void)camera:(id<ThingSmartCameraType>)camera didOccurredErrorAtStep:(TYCameraErrorCode)errStepCode specificErrorCode:(NSInteger)errorCode {
// 开启或者停止视频录制失败
if (errStepCode == Thing_ERROR_RECORD_FAILED) {
self.recording = NO;
}
}
Swift:
func startRecord() {
if self.isRecording {
return
}
guard self.isPreviewing || self.isPlaybacking else {
return;
}
self.camera.startRecord()
self.isRecording = true
}
func stopRecord() {
guard self.isRecording else {
return
}
self.camera.stopRecord()
}
func cameraDidStartRecord(_ camera: ThingSmartCameraType!) {
// 已成功开启视频录制,更新 UI
}
func cameraDidStopRecord(_ camera: ThingSmartCameraType!) {
// 视频录制已停止,并且录制的视频成功保存
}
func camera(_ camera: ThingSmartCameraType!, didOccurredErrorAtStep errStepCode: ThingCameraErrorCode, specificErrorCode errorCode: Int) {
// 开启或者停止视频录制失败
if errStepCode == Thing_ERROR_RECORD_FAILED {
self.isRecording = false
}
}
同样的,无论是视频直播,还是录像回放,当视频成功开始播放以后,用户可以对当前显示的视频图像截图。IPC SDK 提供三种截图的方式,下面两种方式是 ThingSmartCameraType
对象提供的方法:
接口说明
视频截图,图片保存在手机系统相册。
- (UIImage *)snapShoot;
返回值
类型 | 说明 |
---|---|
UIImage | 视频截图的 UIImage 对象,返回 nil 表示图片保存失败 |
接口说明
视频截图,图片保存在指定文件路径。P2P 1.0 设备不支持此接口。
- (UIImage *)snapShootSavedAtPath:(NSString *)filePath thumbnilPath:(NSString *)thumbnilPath;
参数说明
参数 | 说明 |
---|---|
filePath | 保存图片的文件路径 |
thumbnilPath | 保存缩略图的文件路径,如果不需要,可以传入 nil |
返回值
类型 | 说明 |
---|---|
UIImage | 视频截图的 UIImage 对象,返回 nil 表示图片保存失败 |
接口说明
还有一种方式,是使用视频渲染视图 ThingSmartVideoType
的截图接口,此方法只返回一个 UIImage
对象,并不会自动保存图片。
- (UIImage *)screenshot;
返回值
类型 | 说明 |
---|---|
UIImage | 视频截图的 UIImage 对象,返回 nil 表示图片保存失败 |
示例代码
Objective-C:
- (void)snapShoot {
// 在播放视频时才可以截图
if (self.previewing || self.playbacking) {
if ([self.camera snapShoot]) {
// 截图已成功保存到手机相册
}
}
}
Swift:
func snapShoot() {
guard self.isPreviewing || self.isPlaybacking else {
return;
}
if let _ = self.camera.snapShoot() {
// 截图已成功保存到手机相册
}
}
在使用上面的录制或者截图方法时,请确保 App 已获得手机相册的访问权限,否则会导致 App 崩溃。
无论是视频直播,还是录像回放,当视频成功开始播放以后,用户都可以开启视频声音,默认声音是关闭状态。
接口说明
视频声音开关。
- (void)enableMute:(BOOL)mute forPlayMode:(ThingSmartCameraPlayMode)playMode;
参数说明
参数 | 说明 |
---|---|
mute | 是否静音:
|
playMode | 当前的播放模式 |
接口说明
视频声音开关结果代理回调。
- (void)camera:(id<ThingSmartCameraType>)camera didReceiveMuteState:(BOOL)isMute playMode:(ThingSmartCameraPlayMode)playMode;
参数说明
参数 | 说明 |
---|---|
camera | 开关声音的 Camera 对象 |
isMute | 当前的静音状态 |
playMode | 当前的播放模式 |
接口说明
扬声器和听筒模式的切换,返回值不为 0
表示切换失败。P2P 1.0 设备不支持此接口。
- (int)enableSpeaker:(BOOL)enabled;
参数说明
参数 | 说明 |
---|---|
enabled |
|
接口说明
获取当前声音播放模式,返回 YES
表示扬声器播放,NO
为听筒播放,P2P 1.0 设备不支持此接口。
- (BOOL)speakerEnabled;
播放模式在视频直播和录像回放之间切换后,IPC SDK 内部不会保留前一个播放模式的静音状态。即如果:
所以切换播放模式后,您需要同步一下期望的声音开关状态。
视频出流成功后,可以获取实时的视频码率。
接口说明
获取实时的视频码率。
- (double)getVideoBitRateKBPS;
在 P2P 连接成功后,可以开启与设备的实时通话功能,在开始对讲前,需要确保 App 已获得手机麦克风的访问权限。
设备支持扬声器,代表支持单向对讲。设备同时支持扬声器和拾音器,代表视频有声音,即支持双向对讲。您可通过查询 设备能力,确认设备是否支持扬声器和拾音器。
在实时视频直播时,打开视频声音,播放的声音即为摄像机实时采集的人声与环境声音。此时,打开 App 到摄像机的声音通道,即可实现双向对讲功能。
部分摄像机可能没有扬声器或拾音器,此类摄像机无法实现双向对讲。
单向对讲功能需要开发者来实现控制。在开启对讲的时候,关闭视频声音,关闭对讲后,再打开视频声音即可。
接口说明
开启 App 到摄像机的声音通道。
- (void)startTalk;
接口说明
关闭 App 到摄像机的声音通道。
- (void)stopTalk;
接口说明
App 到摄像机的声音通道成功开启代理回调。
- (void)cameraDidBeginTalk:(id<ThingSmartCameraType>)camera;
接口说明
App 到摄像机的声音通道成功关闭的代理回调。
- (void)cameraDidStopTalk:(id<ThingSmartCameraType>)camera;
示例代码
下文以单向对讲为例,展示声音开关与实时对讲接口的用法。
Objective-C:
- (void)startTalk {
[self.camera startTalk];
// 如果不是静音状态,关闭声音
if (!self.isMuted) {
[self.camera enableMute:YES forPlayMode:ThingSmartCameraPlayModePreview];
}
}
- (void)stopTalk {
[self.camera stopTalk];
}
- (void)cameraDidBeginTalk:(id<ThingSmartCameraType>)camera {
// 对讲已成功开启
}
- (void)cameraDidStopTalk:(id<ThingSmartCameraType>)camera {
// 对讲已停止
// 如果是静音状态,打开声音
if (self.isMuted) {
[self.camera enableMute:NO forPlayMode:ThingSmartCameraPlayModePreview];
}
}
- (void)camera:(id<ThingSmartCameraType>)camera didReceiveMuteState:(BOOL)isMute playMode:(ThingSmartCameraPlayMode)playMode {
// 收到静音状态的变化,更新 UI
self.isMuted = isMute;
}
- (void)camera:(id<ThingSmartCameraType>)camera didOccurredErrorAtStep:(ThingCameraErrorCode)errStepCode specificErrorCode:(NSInteger)errorCode {
if (errStepCode == Thing_ERROR_START_TALK_FAILED) {
// 开启对讲失败,重新打开声音
if (self.isMuted) {
[self.camera enableMute:NO forPlayMode:ThingSmartCameraPlayModePreview];
}
}
else if (errStepCode == Thing_ERROR_ENABLE_MUTE_FAILED) {
// 设置静音状态失败
}
}
Swift:
// 当前在实时视频播放状态
func startTalk() {
self.camera.startTalk()
guard self.isMuted else {
self.camera.enableMute(true, for: .preview)
return
}
}
func stopTalk() {
self.camera.stopTalk()
}
func cameraDidBeginTalk(_ camera: ThingSmartCameraType!) {
// 对讲已成功开启
}
func cameraDidStopTalk(_ camera: ThingSmartCameraType!) {
// 对讲已停止
if self.isMuted {
self.camera.enableMute(false, for: .preview)
}
}
func camera(_ camera: ThingSmartCameraType!, didReceiveMuteState isMute: Bool, playMode: ThingSmartCameraPlayMode) {
self.isMuted = isMute
// 收到静音状态的变化,更新 UI
}
func camera(_ camera: ThingSmartCameraType!, didOccurredErrorAtStep errStepCode: ThingCameraErrorCode, specificErrorCode errorCode: Int) {
if errStepCode == Thing_ERROR_START_TALK_FAILED {
// 开启对讲失败,重新打开声音
self.camera.enableMute(false, for: .preview)
}else if errStepCode == Thing_ERROR_ENABLE_MUTE_FAILED {
// 设置静音状态失败
}
}
在实时视频直播时,可以切换清晰度。目前只有高清和标清两种清晰度,且只有实时视频直播时才支持。少数摄像机只支持一种清晰度。存储卡视频录像在录制时,只保存了一种清晰度的视频流。
接口说明
获取当前视频图像的清晰度,结果通过代理方法返回。
- (void)getHD;
接口说明
切换视频清晰度,YES
是高清,NO
是标清。
- (void)enableHD:(BOOL)hd;
参数说明
参数 | 说明 |
---|---|
hd | 是否高清:
|
接口说明
视频清晰度状态变化代理回调。
- (void)camera:(id<ThingSmartCameraType>)camera didReceiveDefinitionState:(BOOL)isHd;
参数说明
参数 | 说明 |
---|---|
camera | 清晰度变化的 Camera 对象 |
isHd | 当前的清晰度状态:
|
以上三个接口在 3.20.0 版本 SDK 中已废弃,但 P2P 1.0 设备可以继续使用。您可以使用以下三个接口替代,但注意 P2P 1.0 设备不支持这些接口。
接口说明
获取视频清晰度。
- (void)getDefinition;
接口说明
设置视频清晰度。
- (void)setDefinition:(ThingSmartCameraDefinition)definition;
接口说明
视频清晰度状态变化代理回调。
- (void)camera:(id<ThingSmartCameraType>)camera definitionChanged:(ThingSmartCameraDefinition)definition;
ThingSmartCameraDefinition 枚举
值 | 描述 |
---|---|
ThingSmartCameraDefinitionProflow | 省流量 |
ThingSmartCameraDefinitionStandard | 标清 |
ThingSmartCameraDefinitionHigh | 高清 |
ThingSmartCameraDefinitionSuper | 超清 |
ThingSmartCameraDefinitionSSuper | 超超清 |
不同的清晰度,需要设备端支持,目前普遍设备只支持标清和高清两种清晰度。
示例代码
Objective-C:
- (void)changeHD {
ThingSmartCameraDefinition definition = self.HD ? ThingSmartCameraDefinitionStandard : ThingSmartCameraDefinitionHigh;
[self.camera setDefinition:definition];
}
// 视频分辨率改变的代理方法,实时视频直播或者录像回放刚开始时也会调用
- (void)camera:(id<ThingSmartCameraType>)camera resolutionDidChangeWidth:(NSInteger)width height:(NSInteger)height {
// 获取当前的清晰度
[self.camera getDefinition];
}
// 清晰度状态代理方法
- (void)camera:(id<ThingSmartCameraType>)camera definitionChanged:(ThingSmartCameraDefinition)definition {
self.HD = definition >= ThingSmartCameraDefinitionHigh;
}
- (void)camera:(id<ThingSmartCameraType>)camera didOccurredErrorAtStep:(TYCameraErrorCode)errStepCode specificErrorCode:(NSInteger)errorCode {
if (errStepCode == Thing_ERROR_ENABLE_HD_FAILED) {
// 切换视频清晰度失败
}
}
Swift:
func changeHD() {
let definition = self.isHD ? ThingSmartCameraDefinition.standard : ThingSmartCameraDefinition.high
self.camera.setDefinition(definition)
}
// 视频分辨率改变的代理方法,实时视频直播或者录像回放刚开始时也会调用
func camera(_ camera: ThingSmartCameraType!, resolutionDidChangeWidth width: Int, height: Int) {
// 获取当前的清晰度
self.camera.getDefinition()
}
func camera(_ camera: ThingSmartCameraType!, definitionChanged definition: ThingSmartCameraDefinition) {
self.isHD = definition.rawValue >= ThingSmartCameraDefinition.high.rawValue
}
func camera(_ camera: ThingSmartCameraType!, didOccurredErrorAtStep errStepCode: ThingCameraErrorCode, specificErrorCode errorCode: Int) {
if errStepCode == Thing_ERROR_ENABLE_HD_FAILED {
// 切换视频清晰度失败
}
}
IPC SDK 提供访问视频裸流数据的代理回调方法,此方法返回视频帧的 YUV 数据,颜色编码格式为 YUV 420sp。iOS 中,对应于 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
格式。
接口说明
视频帧裸流数据代理回调。
- (void)camera:(id<ThingSmartCameraType>)camera thing_didReceiveVideoFrame:(CMSampleBufferRef)sampleBuffer frameInfo:(ThingSmartVideoFrameInfo)frameInfo;
参数说明
参数 | 说明 |
---|---|
camera | 接收到视频数据的 Camera 对象 |
sampleBuffer | 视频帧 YUV 数据 |
frameInfo | 视频帧信息 |
ThingSmartVideoFrameInfo 结构体
字段 | 类型 | 描述 |
---|---|---|
nWidth | int | 视频图像宽度 |
nHeight | int | 视频图像高度 |
nFrameRate | int | 视频帧率 |
nTimeStamp | unsigned long long | 视频帧时间戳 |
nDuration | unsigned long long | 播放报警消息中视频附件时,视频的总长度,单位是 毫秒 |
nProgress | unsigned long long | 播放报警消息中视频附件时,视频帧的时间点,单位是 毫秒 |
如果您想要自行渲染视频图像,或者需要对视频图像做特殊处理,可以将 ThingSmartCameraType
对象的 autoRender
属性设置为 NO
,然后实现此代理方法。此时,IPC SDK 将不会自动渲染视频图像。
您可以将 sampleBuffer
强行转换为 CVPixelBufferRef
,如果您想要异步处理视频帧数据,请记得先 retain
。否则,此代理方法执行完成后,视频帧数据将会被释放,异步处理时会发生野指针异常。
示例代码
Objective-C:
- (void)camera:(id<ThingSmartCameraType>)camera thing_didReceiveVideoFrame:(CMSampleBufferRef)sampleBuffer frameInfo:(ThingSmartVideoFrameInfo)frameInfo {
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)sampleBuffer;
// retain pixelbuffer,防止提前释放
CVPixelBufferRetain(pixelBuffer);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 处理并渲染 pixelBuffer
// ...
// 最后,请务必释放
CVPixelBufferRelease(pixelBuffer);
});
}
Swift:
func camera(_ camera: ThingSmartCameraType!, thing_didReceiveVideoFrame sampleBuffer: CMSampleBuffer!, frameInfo: ThingSmartVideoFrameInfo) {
// 处理并渲染视频数据
}
在视频直播的过程中,如果设备检查到移动物体,智能画框 会在对应的物体上标记一个白色的矩形框。
首先,您需要开启设备的智能画框功能。开启后,设备会随着视频帧发送移动物体的坐标,通过 DP 198
(ipc_object_outline
)来开启设备端的智能画框功能。设备控制接口功能,请参考 设备控制。
在设备端智能画框功能开启的前提下,直播视频播放时,您需要打开 IPC SDK 的智能画框功能。SDK 会根据设备发送的移动物体坐标,在视频图像上绘制矩形框。
此处智能画框功能相关 DP 不做详细介绍,您按照设备端约束即可。
接口说明
智能画框功能开关,通常在开始预览 startPreview
或设置清晰度 setDefinition:
后调用。
- (void)setOutLineEnable:(BOOL)enable;
参数说明
参数 | 说明 |
---|---|
enable | 是否开启智能画框 |
通过设置智能画框的属性来控制框的样式,例如框的颜色,画笔宽度,闪烁频率等。
接口说明
智能画框属性设置,结合设备上报的 SEI(Supplemental Enhancement Information)信息,通过传入指定格式的 JSON 字符串来实现。
- (int)setSmartRectFeatures:(NSString *)features;
参数说明
参数 features
为 JSON 格式字符串,格式约定:
{
"SmartRectFeature":[
{
"type":0,
"index":0,
"brushWidth":1,
"flashFps":{
"drawKeepFrames":2,
"stopKeepFrames":2
},
"rgb":0xFF0000,
"shape":0
},
{
"type":0,
"index":1,
"brushWidth":2,
"flashFps":{
"drawKeepFrames":3,
"stopKeepFrames":2
},
"rgb":0x00FF00,
"shape":1
}
]
}
参数 | 类型 | 说明 |
---|---|---|
SmartRectFeature | Array | 固定标识,支持数组格式(表示多个框的设置),必传 |
type | Int | 画框类型
|
index | Int | 框的索引,对应 SEI 信息里面的 od 的每个 ID 值 |
shape | Int | 矩形框形状
|
rgb | Int | 矩形框颜色,由 RGB 格式转化,默认为 0xFC4747 ,取值范围 0x000000 ~0xFFFFFF |
brushWidth | Int | 矩形框画笔粗细
|
flashFps | String | 矩形框闪烁频率
|
SEI 协议定义
与设备侧约定协议,IPC SDK 解析 SEI 上报的信息,在对应的位置结合相应的属性进行画框。
{
"AGTX":{
"time":6885,
"chn":0,
"key":1,
"iva":{
"od":[
{
"obj":{
"id":0,
"type":1,
"twinkle":1,
"rect":[
0,0,
25,25,
50,50,
80, 80,
100,100
],
"vel":[0,10],
"cat":"PEDESTRIAN"
}
},
{
"obj":{
"id":1,
"type":1,
"twinkle":1,
"rect":[
0,0,
100,100
],
"vel":[0,10],
"cat":"PEDESTRIAN"
}
}
]
}
}
}
设备上报解析 iva
下相关参数说明:
参数 | 说明 |
---|---|
id | 多个画框数据的索引序号 |
type | 画框类型:
|
twinkle | 闪动设置:
|
rect | 每两个数字表示一个点的坐标,所有点按顺时针顺序排列,SDK 会将这些点画成一个封闭的多边形,2 个点即可表示一个矩形框 |
SEI 协议中的 rect
坐标点通常是 App 通过 设备控制 DP 设置传递给设备的,坐标锚点数据约定协议:
偶数位是横(x)坐标上的百分比分子。
奇数位是纵(y)坐标上的百分比分子。
数值最大为 100,奇偶成对出现。
视频解码后,可通过设置对画面渲染再处理,支持拉伸或缩放,左右或上下镜像,90、180、270 度旋转等。
接口说明
- (int)setDeviceFeatures:(NSDictionary *)features;
参数说明
参数 features
为字典类型,格式约定:
{
"DecPostProcess":{
"video":[
{
"restype":"4",
"oldres":"944*1080",
"newres":"1920*1080"
},
{
"restype":"2",
"oldres":"944*1080",
"newres":"1920*1080"
}
],
"mirror":0,
"rotation":2
}
}
参数 | 说明 |
---|---|
DecPostProcess | 固定标识,必传 |
video | 视频分辨率,数组,支持多组分辨率设置:
|
mirror | 镜像设置
|
rotation | 旋转角度
|
ThingSmartCameraAbility
类,可以解析设备的配置信息,从而获取设备的一些基础能力。
属性 | 说明 |
---|---|
defaultDefinition | 实时视频播放的默认清晰度 |
videoNum | 设备支持的码流数,
|
isSupportSpeaker | 设备是否支持扬声器,如果设备支持扬声器,则可以开启讲话 |
isSupportPickup | 设备是否支持拾音器,如果设备支持拾音器,则 App 端查看视频流时可以开启声音 |
rowData | P2P config 原始数据 |
接口说明
根据设备数据模型创建设备能力类对象,需要在连接 P2P 之后调用。第一次 P2P 连接后,本地沙盒中会缓存此数据。
+ (instancetype)cameraAbilityWithDeviceModel:(ThingSmartDeviceModel *)deviceModel;
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈