多目视频直播

更新时间:2024-12-27 08:53:42下载pdf

多目视频直播需要先创建 ThingSmartCameraType 对象,通过 isSupportedVideoSplitting 判断视频流是否支持分割。如果支持,SDK 会根据配置协议进行视频流分割再进行视频渲染,否则和普通直播相同。

流程说明

多目视频直播

核心接口

演示录屏 接口 描述 备注
ThingSmartCameraFactory +(id)cameraWithP2PType:deviceId:delegate: 创建 ThingSmartCameraType 对象 一个设备 ID 对应一个 ThingSmartCameraType 对象
ThingSmartCameraType advancedConfig.isSupportedVideoSplitting 视频流是否支持分割 如果不支持,请配置对应协议
-(BOOL)registerVideoViewIndexPairs: 渲染视图绑定镜头 ID -
-(void)connectWithMode: 连接 -3 或 -105 建议重连
- (void)startPreviewWithDefinition: 指定清晰度开始直播 根据设备能力上报获取清晰度,开始直播成功后通过 ThingSmartCameraDelegate 中的 - (void)cameraDidBeginPreview: 方法回调
-(BOOL)swapVideoIndex:forVideoIndex: 渲染视图切换镜头 调用前,请确保播放器已绑定
- (int)stopPreview 停止直播 停止直播成功后,通过 ThingSmartCameraDelegate 中的 - (void)cameraDidStopPreview: 方法回调
-(BOOL)uninstallVideoViewIndexPairs: 渲染视图解绑镜头 ID -
-(int)disConnect 断开连接 -
ThingSmartCameraDelegate -(void)cameraInitFailed: 创建 ThingSmartCameraType 对象失败 P2P 类型不支持
-(void)cameraDidConnected: 连接成功 -
- (void)cameraDidBeginPreview: 开始直播成功 -
- (void)cameraDidStopPreview: 停止直播成功 -
-(void)camera:didOccurredErrorAtStep:specificErrorCode: 返回直播相关操作失败的步骤和错误码 连接,开始直播,停止直播等操作

重点关注

  • 如果视频流未进行分割或分割异常,请确认分割协议配置是否正确。
  • 在使用多线程时,注意 ThingSmartCameraType 对象管理,避免跨线程频繁调用 ThingSmartCameraType 中的实例方法,否则会出现死锁等异常情况。

核心代码

创建 ThingSmartCameraType 对象

+ (id<ThingSmartCameraType>)cameraWithP2PType:(id)type deviceId:(NSString *)devId delegate:(id<ThingSmartCameraDelegate>)delegate;

- (void)cameraInitFailed:(ThingSmartCameraErrorCode)errorCode;

视频流是否支持分割

@property (nonatomic, strong, readonly) id <ThingSmartCameraAdvancedConfig> advancedConfig;

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

渲染视图绑定镜头 ID

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

连接

- (void)connectWithMode:(ThingSmartCameraConnectMode)mode;

- (void)cameraDidConnected:(id<ThingSmartCameraType>)camera;

开始直播

//开始直播
- (void)startPreviewWithDefinition:(ThingSmartCameraDefinition)definition;
//开始直播成功
- (void)cameraDidBeginPreview:(id<ThingSmartCameraType>)camera;

渲染视图切换镜头

//渲染视图切换镜头
- (BOOL)swapVideoIndex:(ThingSmartVideoIndex)videoIndex forVideoIndex:(ThingSmartVideoIndex)forVideoIndex;

停止直播

SDK sample 中包含完整流程,可点击查看。

//停止直播
- (void)stopPreview;
//停止直播成功
- (void)cameraDidStopPreview:(id<ThingSmartCameraType>)camera;

渲染视图解绑镜头 ID

//渲染视图解绑镜头 ID
- (BOOL)uninstallVideoViewIndexPairs:(NSArray<id<ThingSmartVideoViewIndexPair>> *)viewIndexPairs;

断连

//主动断开连接
- (void)disConnect;
//被动断开连接
- (void)cameraDisconnected:(id<ThingSmartCameraType>)camera specificErrorCode:(NSInteger)errorCode;

示例代码

SDK sample 中包含完整流程,可点击查看。


//1.创建 ThingSmartCameraType 对象
- (void)cameraInit {
    //初始化设备
    self.device = [ThingSmartDevice deviceWithDeviceId:devId];

    // delegate: ThingSmartCameraDelegate 用于监听 P2P 通道连接状态
    self.camera = [ThingSmartCameraFactory     cameraWithP2PType:@(self.device.deviceModel.p2pType)     deviceId:self.device.deviceModel.devId delegate:self];


    //初始化视频预览页面
        BOOL isSupportedVideoSplitting = self.camera.advancedConfig.isSupportedVideoSplitting;
    if (isSupportedVideoSplitting) {
        [self.camera registerVideoViewIndexPairs:viewIndexPairs]
    } else {
        self.videoView = self.camera.videoView;

    //将视频渲染视图添加到屏幕上
       [self.view addSubview:self.videoView];
    }
}

//2.连接
- (void)cameraConnect {
    [self.camera connectWithMode:ThingSmartCameraConnectAuto];
}
//连接成功
- (void)cameraDidConnected:(id<ThingSmartCameraType>)camera {
    self.connected = YES;
    [self startPreview];
}
//连接失败
- (void)cameraDisconnected:(id<ThingSmartCameraType>)camera specificErrorCode:(NSInteger)errorCode {
    // P2P 连接被动断开,一般为网络波动导致
    self.connected = NO;
}

//3.开始直播
- (void)startPreview {
    [self.camera startPreviewWithDefinition:];
}
//开始直播成功回调
- (void)cameraDidBeginPreview:(id<ThingSmartCameraType>)camera {
   self.previewing = YES;
}

//4.停止直播
- (void)stopPreview {
    [self.camera stopPreview];
}
//停止直播成功回调
- (void)cameraDidStopPreview:(id<ThingSmartCameraType>)camera {
    self.previewing = NO;
}

//5.解绑播放器
- (void)unbindVideoViews {
    [self.camera uninstallVideoViewIndexPairs:viewIndexPairs]
}

//6.断开连接
- (void)disconnect {
    [self.camera disConnect];
}

#pragma mark - ThingSmartCameraDelegate

- (void)camera:(id<ThingSmartCameraType>)camera thing_didReceiveVideoFrame:(CMSampleBufferRef)sampleBuffer frameInfo:(ThingSmartVideoFrameInfo)frameInfo {

}

// 错误回调
- (void)camera:(id<ThingSmartCameraType>)camera didOccurredErrorAtStep:(ThingCameraErrorCode)errStepCode specificErrorCode:(NSInteger)errorCode extErrorCodeInfo:(id<ThingSmartCameraExtErrorCodeInfo>)extErrorCodeInfo {
    if (errStepCode == Thing_ERROR_CONNECT_FAILED) {
         // P2P 连接失败
        self.connected = NO;
    }
    else if (errStepCode == Thing_ERROR_START_PREVIEW_FAILED) {
        // 开始直播失败
        self.previewing = NO;
    }
}