多目摄像机

更新时间:2024-06-17 07:54:00下载pdf

IPC SDK 支持多个摄像头一起显示,目前采用的是视频分割协议进行多目视频分割渲染,需要设备支持。

  • 必须确保设备数据模型获取成功。
  • 首先初始化 ThingSmartCameraType 对象,然后再调用视频分割相关的 API。
  • SDK 接入阶段,建议打开 debug 模式。

是否支持视频分割协议

接口说明

获取设备是否支持 IPC 视频流分割高级能力,返回布尔类型。

@property (nonatomic, assign, readonly) BOOL isSupportedVideoSplitting;

示例代码

id<ThingSmartCameraType> camera = [ThingSmartCameraFactory cameraWithP2PType:p2pType config:config delegate:self];
if (camera.advancedConfig) {
    return camera.advancedConfig.isSupportedVideoSplitting;
}
return NO;

获取视频分割协议

接口说明

获取视频分割协议,以 JSON 格式返回。

@property (nonatomic, copy, readonly) NSString *cameraSplitVideoInfoJson;

示例代码

id<ThingSmartCameraType> camera = [ThingSmartCameraFactory cameraWithP2PType:p2pType config:config delegate:self];
if (camera.advancedConfig) {
    return camera.advancedConfig.cameraSplitVideoInfoJson;
}
return nil;

更多信息,参考:

渲染视图绑定镜头 ID

接口说明

每个渲染视图可绑定一个镜头 ID,该接口支持批量绑定。

创建 camera 对象成功后,调用绑定方法。

ThingSmartVideoViewIndexPair 协议中的 videoIndex 信息,建议从分割协议中解析对应的 index 进行赋值。

- (BOOL)registerVideoViewIndexPairs:(NSArray<id<ThingSmartVideoViewIndexPair>> *)viewIndexPairs;

入参说明

参数 子参数 说明
viewIndexPairs videoIndex 镜头 ID,对应协议下面的 split_info.index,例如 1,2,3 等
videoView 渲染视频流 view 对象

渲染视图解绑镜头 ID

接口说明

解绑渲染视图,单次调用支持解绑多个镜头 ID。

创建 camera 对象成功后,调用解绑方法。

ThingSmartVideoViewIndexPair 协议中的 videoIndex 信息,建议从分割协议中解析对应的 index 进行赋值。

- (BOOL)uninstallVideoViewIndexPairs:(NSArray<id<ThingSmartVideoViewIndexPair>> *)viewIndexPairs;

入参说明

参数 子参数 说明
viewIndexPairs videoIndex 镜头 ID,对应协议下面的 split_info.index,例如 1,2,3 等
videoView 渲染视频流 view 对象

渲染视图切换镜头

调用后可以切换两个播放器所渲染的镜头视频流。

调用 swapVideoIndex:forVideoIndex: 之前,务必保证已经调用 registerVideoViewIndexPairs:

- (BOOL)swapVideoIndex:(ThingSmartVideoIndex)videoIndex forVideoIndex:(ThingSmartVideoIndex)forVideoIndex;

入参说明

参数 说明
videoIndex 需要切换的第一个镜头 ID, 需提前在 registerVideoViewIndexPairs 接口中绑定
forVideoIndex 需要切换的第二个镜头 ID, 需提前在 registerVideoViewIndexPairs 接口中绑定

示例代码

[camera swapVideoIndex:1 forVideoIndex:2];

完整示例代码

/// 绑定信息类
@interface CameraDivisionRegisterConfig : NSObject<ThingSmartVideoViewIndexPair>

@end

@implementation CameraDivisionRegisterConfig

@synthesize videoIndex;
@synthesize videoView;

@end
//创建摄像头
- (void)createCamera {
    if (self.camera) {
        return;
    }

   id p2pType = [self.deviceModel.skills objectForKey:@"p2pType"];
   dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    self.camera = [ThingSmartCameraFactory cameraWithP2PType:p2pType deviceId:devId delegate:self];
  //绑定 view
    [self bindRenderView];
    [self.camera connect];
});
}

- (void)bindRenderView {
   //one split video player config
    self.oneSplitVideoPlayerConfig = [[CameraDivisionRegisterConfig alloc] init];
    ThingSmartEAGLView *oneSplitVideoPlayer = [[ThingSmartEAGLView alloc] init];
    self.oneSplitVideoPlayerConfig.videoView = oneSplitVideoPlayer;
    self.oneSplitVideoPlayerConfig.videoIndex = 1;
    
    //two split video player config
    self.twoSplitVideoPlayerConfig = [[CameraDivisionRegisterConfig alloc] init];
    ThingSmartEAGLView *twoSplitVideoPlayer = [[ThingSmartEAGLView alloc] init];
    self.twoSplitVideoPlayerConfig.videoView = twoSplitVideoPlayer;
    self.twoSplitVideoPlayerConfig.videoIndex = 2;
    
  // 获取摄像头分割协议
  NSString *splitVideoInfoJson = self.camera.advancedConfig.cameraSplitVideoInfoJson;
  
  //注册渲染 view
   [self.camera registerVideoViewIndexPairs:@[self.oneSplitVideoPlayerConfig,self.twoSplitVideoPlayerConfig]];
  
  
  // 添加视图及布局
    oneSplitVideoPlayer.frame = CGRectMake(0, 90, ScreenWidth(), ScreenWidth()*9/16);
    twoSplitVideoPlayer.frame = CGRectMake(0, CGRectGetMaxY(oneSplitVideoPlayer.frame),  ScreenWidth(), ScreenWidth()*9/16);
  
  [self.view addSubview:oneSplitVideoPlayer];
  [self.view addSubview:twoSplitVideoPlayer];

}

//解绑 view
- (void)unRegister {
    [self.camera uninstallVideoViewIndexPairs:@[self.boolConfig,self.blotConfig]];
}

#pragma mark - ThingSmartCameraDelegate
- (void)cameraDidConnected:(id<ThingSmartCameraType>)camera {
    self.connected = YES;
    // 需要 P2P 连接成功后再开始预览
       [camera startPreview];
}

更多信息,参考 Demo

说明

分割参数说明

参数 说明
total_split_num 视频分割路数
split_info 视频分割信息数组
split_info.index 镜头 ID
split_info.type 根据 type 值,选择绘制对应的视频流
  • -1:单路流
  • 0:全部
  • 1:球机
  • 2:枪机
split_info.res_pos 视频分割坐标信息
align_info 视频窗口组合及定位器位置信息,按需解析
align_info.align_type 视频窗口排列组合标识,约定值:
  • 20:双目两视频窗口上下垂直排列
  • 21:双目两视频窗口左右并列
  • 30:三目三个视频窗口上下垂直排列(暂时无此形态设备,不支持)
  • 31:三目上面一个,下面两个左右并列
  • 32:三目上面两个左右并列,下面一个
align_info.align_group 组合顺序,数组内的数字与 split_info.index 对应,数组内非数组独享一行(同行),嵌套的数组并列共享一行(同列)
align_info.localizer_group 包含具体定位器的位置 split_info.index,不支持跨列配置

协议示例

{
  "total_split_num":3,
  "split_info":[
    {
      "index":1,
      "type":1,
      "res_pos":[[0,0,640,720],[0,0,960,1080]]
    },
    {
      "index":2,
      "type":2,
      "res_pos":[[0,720,640,720],[0,1080,960,1080]]
    },
    {
      "index":3,
      "type":2,
      "res_pos":[[0,720,1280,720],[0,1080,1920,1080]]
    }
  ],
  "align_info":{
    "align_type":32,
    "align_group":[[1, 3],[2]],
    "localizer_group":[1,3]
  }
}