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

iOS中AVCaptureVideoDataOutputSampleBufferDelegate未触发captureOutput求助

问题分析与解决方案

你的摄像头画面正常显示,但captureOutput代理方法不触发,主要有以下几个常见原因及对应的修复方案:

1. AVCaptureVideoDataOutput 未被强引用

你在setupCamera方法中创建的AVCaptureVideoDataOutput是局部变量,虽然已添加到captureSession,但系统对输出对象的引用可能不足以维持其生命周期,导致输出对象被提前释放,代理回调自然无法触发。

修复:在类中添加强引用属性保存视频输出对象:
在.h文件中添加:

@property (nonatomic, strong) AVCaptureVideoDataOutput *videoDataOutput;

然后在setupCamera中修改创建逻辑:

self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
[self.videoDataOutput setSampleBufferDelegate:self queue:self.videoDataOutputQueue];
[self.captureSession addOutput:self.videoDataOutput];

2. 未指定兼容的像素格式

AVCaptureVideoDataOutput默认的像素格式可能不被当前设备支持,导致无法输出采样缓冲区。

修复:添加像素格式设置,使用通用的32位BGRA格式:

self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
// 设置兼容的像素格式
NSDictionary *outputSettings = @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)};
self.videoDataOutput.videoSettings = outputSettings;
[self.videoDataOutput setSampleBufferDelegate:self queue:self.videoDataOutputQueue];
[self.captureSession addOutput:self.videoDataOutput];

3. 检查AVCaptureConnection的启用状态

添加视频输出后,对应的AVCaptureConnection可能处于未启用状态,需要手动确认并启用。

修复:在添加输出后,获取连接并启用:

[self.captureSession addOutput:self.videoDataOutput];
// 获取视频连接并启用
AVCaptureConnection *connection = [self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo];
if (connection.isEnabled == NO) {
    connection.enabled = YES;
}

4. 确保代理对象(Trying实例)的生命周期

如果你的Trying类实例是临时创建的(比如在某个方法中局部声明,方法结束后被释放),那么代理对象不存在,回调也不会触发。要确保Trying实例被其他对象(比如ViewController)强引用持有。


修改后的完整代码示例

.h 文件

#import <AVFoundation/AVFoundation.h>
#import <UIKit/UIKit.h>

@interface Trying : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
@property (nonatomic, strong) dispatch_queue_t videoDataOutputQueue;
@property (nonatomic, strong) UIView *view;
@property (nonatomic, strong) AVCaptureVideoDataOutput *videoDataOutput; // 新增属性
- (void)setupCamera;
@end

.m 文件

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import "Trying.h"

@interface Trying ()

@end

@implementation Trying

- (void)setupCamera {
    self.captureSession = [[AVCaptureSession alloc] init];
    
    AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    NSError *error;
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];
    
    if (deviceInput) {
        [self.captureSession addInput:deviceInput];
        
        AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
        previewLayer.frame = self.view.bounds;
        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        [self.view.layer addSublayer:previewLayer];
        
        self.previewLayer = previewLayer;
        
        // Create a video data output and set the delegate
        self.videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL);
        self.videoDataOutput = [[AVCaptureVideoDataOutput alloc] init];
        // 设置像素格式
        NSDictionary *outputSettings = @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)};
        self.videoDataOutput.videoSettings = outputSettings;
        [self.videoDataOutput setSampleBufferDelegate:self queue:self.videoDataOutputQueue];
        [self.captureSession addOutput:self.videoDataOutput];
        
        // 检查并启用连接
        AVCaptureConnection *connection = [self.videoDataOutput connectionWithMediaType:AVMediaTypeVideo];
        if (!connection.isEnabled) {
            connection.enabled = YES;
        }
        
        // Start the session
        [self.captureSession startRunning];
    } else {
        NSLog(@"Error setting up camera: %@", error.localizedDescription);
    }
}

- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    // Process the live sample buffer here
    NSLog(@"Got a live sample buffer");
    
    // You can use the sampleBuffer for further processing, such as image recognition or analysis
}

- (void)captureOutput:(AVCaptureOutput *)output didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    NSLog(@"Dropped a sample buffer");
    // Handle dropped frames if needed
}
@end

内容的提问来源于stack exchange,提问作者Tanishq Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:00:56