【问题标题】:crashing on video capture with AVFoundation使用 AVFoundation 捕获视频时崩溃
【发布时间】:2012-06-26 18:49:27
【问题描述】:

我正在尝试使用 AVFoundation 在我的应用中实现视频捕获。我在 viewDidLoad 下有以下代码:

session = [[AVCaptureSession alloc] init];
movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
videoInputDevice = [[AVCaptureDeviceInput alloc] init];
AVCaptureDevice *videoDevice = [self frontFacingCameraIfAvailable];

if (videoDevice)
{
    NSError *error;

    videoInputDevice = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];

    if (!error)
    {
        if ([session canAddInput:videoInputDevice])
            [session addInput:videoInputDevice];
        else 
            NSLog (@"Couldn't add input.");
    }

}


AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
NSError *audioError = nil;
AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&audioError];

if (audioInput)
{
    [session addInput:audioInput];
}

movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];

Float64 TotalSeconds = 35;          //Total seconds
int32_t preferredTimeScale = 30;    //Frames per second
CMTime maxDuration = CMTimeMakeWithSeconds(TotalSeconds, preferredTimeScale);   
movieFileOutput.maxRecordedDuration = maxDuration;

movieFileOutput.minFreeDiskSpaceLimit = 1024 * 1024;                        

if ([session canAddOutput:movieFileOutput])
    [session addOutput:movieFileOutput];

[session setSessionPreset:AVCaptureSessionPresetMedium];
if ([session canSetSessionPreset:AVCaptureSessionPreset640x480])        //Check size based configs are supported before setting them
    [session setSessionPreset:AVCaptureSessionPreset640x480];

[self cameraSetOutputProperties];


[session startRunning];

此代码在用于启动捕获的按钮的实现中,除其他外:

NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"output.mov"];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:outputPath])
{
    NSError *error;
    if ([fileManager removeItemAtPath:outputPath error:&error] == NO)
    {
        //Error - handle if requried
    }
}
[outputPath release];
//Start recording
[movieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];
[outputURL release];

当我尝试在设备上运行它时,当我尝试加载所有这些都应该发生的视图时它会崩溃。 Xcode 给了我一个“线程 1: EXC_BAD_ACCESS (code=1, address=0x4) at:

AVFoundation`-[AVCaptureDeviceInput _setDevice:]:
(stuff)
0x3793f608:  ldr    r0, [r1, r0]

错误在最后一行给出。我认为这与某处的 AVCaptureDeviceInput 有关,但我对它可能是什么一无所知。有谁知道我在这里缺少什么?谢谢。

编辑:摆弄断点后,我发现崩溃发生在这一行:

AVCaptureDevice *videoDevice = [self frontFacingCameraIfAvailable];

那么与该方法有关吗?这是我的实现文件,可能有问题。

NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *captureDevice = nil;
for (AVCaptureDevice *device in videoDevices)
{
    if (device.position == AVCaptureDevicePositionFront)
    {
        captureDevice = device;
        break;
    }
}

//  couldn't find one on the front, so just get the default video device.
if ( ! captureDevice)
{
    captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
}

return captureDevice;

编辑2:可能是我正在使用

AVCaptureDevice *videoDevice = [self frontFacingCameraIfAvailable];

而“自我”以某种方式将扳手扔进去?我知道在创建 CALayer 时可以这样做

CALayer *aLayer = [CALayer layer];

但我不知道与此等效的 AVCaptureDevice(如果有的话)。我不确定它还能是什么,从各方面来看,我的代码看起来都很好,我已经尝试清理项目、重新启动 Xcode、重新启动计算机等。

【问题讨论】:

  • 当你说最后一行时,你具体指的是哪一行?您帖子中的最后一行代码是release
  • 抱歉,我指的是最后一个代码块的最后一行,即 0x3793f608。这是我得到任何错误的唯一地方。

标签: objective-c ios xcode avfoundation


【解决方案1】:

我很确定问题在于您正在模拟器上运行程序。模拟器无法使用这些资源。

【讨论】:

  • 不,我在设备上运行它。
  • 是的,当我设置断点时,应用程序在“AVCaptureDevice *videoDevice = [self frontFacingCameraIfAvailable];”上特别崩溃线。我猜与那个方法有关吗?我将编辑原始帖子以包含它。
  • 检查这个方法:musicalgeometry.com/?p=1554。也许你需要使用 position 属性。
  • 尝试将我的方法更改为那个方法,但它仍然在同一个地方崩溃。
  • 你在哪个 iOS 版本上运行它?
【解决方案2】:

设法解决了这个问题(也许)。

添加

@property (nonatomic, retain) AVCaptureDeviceInput *videoInputDevice; 

到接口,在实现中合成,用这些方法得到前置摄像头:

- (AVCaptureDevice *) cameraWithPosition:(AVCaptureDevicePosition) position
{
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in devices) {
    if ([device position] == position) {
        return device;
    }
}
return nil;
}

-(AVCaptureDevice *)frontFacingCamera
{
return [self cameraWithPosition:AVCaptureDevicePositionFront];

然后分配给它

videoInputDevice = [AVCaptureDeviceInput deviceInputWithDevice:[self frontFacingCamera] error:&error];

不能 100% 确定它是否有效,因为现在它无法保存,但它不再崩溃了。当我确定它是否有效时,我会回来更新它。

【讨论】:

    猜你喜欢
    • 2017-06-01
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    相关资源
    最近更新 更多