使用AVFoundation录制多个屏幕时出错

geo*_*lly 5 macos objective-c avfoundation avcapturesession avcapturemoviefileoutput

我正在尝试使用下面的代码将主监视器屏幕和辅助监视器屏幕记录到两个单独的文件中。

const uint32_t MAX_DISPLAY = 2;
CGDirectDisplayID displays[MAX_DISPLAY] = {0};
CGGetActiveDisplayList(MAX_DISPLAY, displays, &m_nDisplays);

NSString* dest_file[2] = {0};
NSURL* dest_path[2] = {0};

AVCaptureConnection *CaptureConnection[2] = {0};

NSDictionary *videoCleanApertureSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                            @2048, AVVideoCleanApertureWidthKey,
                                            @1152, AVVideoCleanApertureHeightKey,
                                            @0, AVVideoCleanApertureHorizontalOffsetKey,
                                            @0, AVVideoCleanApertureVerticalOffsetKey,
                                            nil];

NSDictionary *videoAspectRatioSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                          @3,AVVideoPixelAspectRatioHorizontalSpacingKey,
                                          @3,AVVideoPixelAspectRatioVerticalSpacingKey,
                                          nil];

 NSNumber* bitsPerSecond = [NSNumber numberWithDouble:1024*1000];

NSDictionary *codecSettings =  [NSDictionary dictionaryWithObjectsAndKeys:
                               bitsPerSecond, AVVideoAverageBitRateKey,
                               videoCleanApertureSettings, AVVideoCleanApertureKey,
                               videoAspectRatioSettings, AVVideoPixelAspectRatioKey,
                               nil];

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               AVVideoCodecH264, AVVideoCodecKey,
                               codecSettings,AVVideoCompressionPropertiesKey,
                               AVVideoScalingModeResize,AVVideoScalingModeKey,
                               @2048, AVVideoWidthKey,
                               @1152, AVVideoHeightKey,
                               nil];

for( int nIdx = 0; nIdx < m_nDisplays; ++nIdx )
{
    m_session[nIdx] = [[AVCaptureSession alloc] init];
    dest_file[nIdx] = [NSString stringWithFormat:@"%@_%d.MOV",destination_path,nIdx];
    dest_path[nIdx] = [NSURL fileURLWithPath: dest_file[nIdx] ];


    // Create a ScreenInput with the display and add it to the session
    m_movie_file_input[nIdx] = [[[AVCaptureScreenInput alloc] initWithDisplayID:displays[nIdx]] autorelease];    
    [m_movie_file_input[nIdx] removesDuplicateFrames ];

    if ([m_session[nIdx] canAddInput:m_movie_file_input[nIdx]])
    {
        [m_session[nIdx] addInput:m_movie_file_input[nIdx]];
    }

    // Create a MovieFileOutput and add it to the session
    m_movie_file_output[nIdx] = [[[AVCaptureMovieFileOutput alloc] init] autorelease];
    if ([m_session[nIdx] canAddOutput:m_movie_file_output[nIdx]])
    {
        [m_session[nIdx] addOutput:m_movie_file_output[nIdx]];
    }

    CaptureConnection[nIdx] = [m_movie_file_output[nIdx] connectionWithMediaType:AVMediaTypeVideo];

    [m_movie_file_output[nIdx] setOutputSettings : videoSettings forConnection : CaptureConnection[nIdx]];

    // Start running the session
    [m_session[nIdx] startRunning];

    [m_movie_file_output[nIdx] startRecordingToOutputFileURL:dest_path[nIdx]    recordingDelegate:self];

}
Run Code Online (Sandbox Code Playgroud)

我将两个屏幕都保存到两个单独的文件中。但是,在为辅助监视器(即循环的第二遍)调用startRecordingToOutputFileURL API时,出现如下错误:

VTCompressionSessionCreate在/SourceCache/CoreMedia_frameworks/CoreMedia-1562.19/Sources/VideoToolbox/VTCompressionSession.c线897处指示err = -8973(err)(VTVideoEncoderStartSession失败)

此外,对于辅助监视器,压缩参数(比特率)未正确设置,它采用了一些我在程序中指定的值以外的其他值。

有人可以帮我吗?另外,请告诉我这是执行此操作的正确方法。

提前致谢

乔治