0

我正在玩 AVFoundation,灵感来自这个 Technical Q&A 代码示例- 通过 Lion 上的 AVFoundation 截屏。

示例代码运行良好,但如果我将AVCaptureSessionPresetMedium更改为AVCaptureSessionPresetHigh并出现以下错误,则始终失败:

由于错误,即将完成录制 Error Domain=AVFoundationErrorDomain Code=-11812 "Recording Stopped" UserInfo=0x1001ccb60 {AVErrorRecordingSuccessfullyFinishedKey=false, NSLocalizedRecoverySuggestion=停止使用录制设备的任何其他操作并重试。, NSLocalizedDescription=Recording Stopped}

当会话停止时会发生这种情况。错误代码是AVErrorMediaDiscontinuity。使用 [mSession stopRunning] 优雅地停止录制。

我已经仔细阅读了所有文档,但找不到任何解释为什么会在切换会话预设时发生这种情况。对我来说,它似乎是一个错误。[mSession canSetSessionPreset:AVCaptureSessionPresetHigh] 甚至返回 true。简单的源代码:

@implementation ScreenRecorder

-(void)screenRecording:(NSURL *)destPath
{
    // Create a capture session
    mSession = [[AVCaptureSession alloc] init];

    if ([mSession canSetSessionPreset:AVCaptureSessionPresetHigh])
        NSLog(@"Can set high preset");
    else
        NSLog(@"CANNOT set high preset");

    [mSession setSessionPreset: AVCaptureSessionPresetHigh];// Fails, but AVCaptureSessionPresetMedium works splendidly


    input = [[AVCaptureScreenInput alloc] initWithDisplayID: kCGDirectMainDisplay];
    if (!input) {
        mSession = nil;
        NSLog(@"Input not valid!");
        return;
    }
    if ([mSession canAddInput:input]){
        [mSession addInput:input];
    }
    else
        NSLog(@"Could not add input!!");


    mMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
    if ([mSession canAddOutput:mMovieFileOutput])
        [mSession addOutput:mMovieFileOutput];
    else
        NSLog(@"Could not add movie file output!!");

    [mSession startRunning];

    // Delete any existing movie file first
    if ([[NSFileManager defaultManager] fileExistsAtPath:[destPath path]])
    {
        NSError *err;
        if (![[NSFileManager defaultManager] removeItemAtPath:[destPath path] error:&err])
        {
            NSLog(@"Error deleting existing movie %@",[err localizedDescription]);
        }
    }

    NSLog(@"Starting recording..");
    [mMovieFileOutput startRecordingToOutputFileURL:destPath recordingDelegate:self];
}

-(void)stopRecording
{
    NSLog(@"Stopping recording..");
    [mMovieFileOutput stopRecording];
}

//
// AVCaptureFileOutputRecordingDelegate methods
//
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections
{
    NSLog(@"Started recording to %@", [fileURL description]);
}

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput willFinishRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
    NSLog(@"About to finish recording due to error %@", [error description]);
}

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
    NSLog(@"Did finish recording to %@ due to error %@", [outputFileURL description], [error description]);

    [mSession stopRunning];
    mSession = nil;
}

@end

记录输出:

2013-05-28 19:51:45.058 ScreenEmailer[1330:303] Can set high preset 
2013-05-28 19:51:45.584 ScreenEmailer[1330:303] Starting recording.. 
2013-05-28 19:53:39.757 ScreenEmailer[1330:303] Stopping recording.. 
2013-05-28 19:53:44.758 ScreenEmailer[1330:303] About to finish recording due to error Error Domain=AVFoundationErrorDomain Code=-11812 "Recording Stopped" UserInfo=0x1001ccb60 {AVErrorRecordingSuccessfullyFinishedKey=false, NSLocalizedRecoverySuggestion=Stop any other actions using the recording device and try again., NSLocalizedDescription=Recording Stopped}

为什么会这样?以及如何配置更高的录制质量?

谢谢

4

1 回答 1

1

原来 AVCaptureSessionPresetHigh 需要您定义录制区域:

mSession = [[AVCaptureSession alloc] init];
[mSession setSessionPreset: AVCaptureSessionPresetHigh];
input = [[AVCaptureScreenInput alloc] initWithDisplayID: kCGDirectMainDisplay];
input.cropRect = CGRectMake(0.0, 0.0, 700.0, 700.0); // is required for AVCaptureSessionPresetHigh

以后的录音工作很精彩。

感谢 Gordon Apple <3

于 2013-05-28T20:53:21.033 回答