You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS WebRTC自定义MyVideoSourceFilter未触发didCaptureVideoFrame问题

问题分析与解决方案

错误原因

  1. 未遵守协议:MyVideoSourceFilter未声明遵守RTCVideoCapturerDelegate协议,RTCCameraVideoCapturer仅会向实现该协议的代理发送回调消息。
  2. 对象被释放:RTCCameraVideoCapturer的delegate是弱引用属性,你当前代码中的filter是局部变量,代码块执行完毕后会被ARC自动释放,导致代理失效。
  3. 未启动捕获流程:若未获取摄像头权限或未调用startCapture方法启动视频采集,不会产生任何视频帧,自然触发不了didCaptureVideoFrame回调。

补充操作

1. 让自定义类遵守协议

修改MyVideoSourceFilter的头文件,明确声明遵守RTCVideoCapturerDelegate:

#import <WebRTC/WebRTC.h>

@interface MyVideoSourceFilter : NSObject <RTCVideoCapturerDelegate>
@property (nonatomic, strong) RTCVideoSource *videoSource;
- (instancetype)initWithSource:(RTCVideoSource *)source;
@end

2. 强引用自定义Filter对象

在当前类中添加强引用属性保存filter,避免其被释放:

// 在当前类的头文件或类扩展中添加
@property (nonatomic, strong) MyVideoSourceFilter *videoFilter;

// 初始化代码修改为
self.videoFilter = [[MyVideoSourceFilter alloc] initWithSource:videoSource];
self.videoCapturer = [[RTCCameraVideoCapturer alloc] initWithDelegate:self.videoFilter];
// 无需重复设置delegate,initWithDelegate已完成代理绑定

3. 启动摄像头捕获并处理权限

确保已获取摄像头权限,并启动视频采集:

// 检查并请求摄像头权限
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (status == AVAuthorizationStatusAuthorized) {
    [self startVideoCapture];
} else if (status == AVAuthorizationStatusNotDetermined) {
    [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
        if (granted) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self startVideoCapture];
            });
        }
    }];
}

// 启动视频采集的辅助方法
- (void)startVideoCapture {
    AVCaptureDevice *frontCamera = [self getFrontCamera];
    AVCaptureDeviceFormat *preferredFormat = [self getPreferredCaptureFormatForDevice:frontCamera];
    if (frontCamera && preferredFormat) {
        [self.videoCapturer startCaptureWithDevice:frontCamera format:preferredFormat fps:30];
    }
}

// 获取前置摄像头
- (AVCaptureDevice *)getFrontCamera {
    for (AVCaptureDevice *device in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
        if (device.position == AVCaptureDevicePositionFront) {
            return device;
        }
    }
    return nil;
}

// 获取合适的捕获格式(示例为1280x720)
- (AVCaptureDeviceFormat *)getPreferredCaptureFormatForDevice:(AVCaptureDevice *)device {
    for (AVCaptureDeviceFormat *format in device.formats) {
        CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription);
        if (dimensions.width == 1280 && dimensions.height == 720) {
            return format;
        }
    }
    return device.formats.firstObject;
}

4. 验证代理有效性

初始化完成后可打印代理对象,确认其不为空:

NSLog(@"videoCapturer delegate: %@", self.videoCapturer.delegate);

内容的提问来源于stack exchange,提问作者Peter Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 14:37:18