4

こんにちは、画面をキャプチャしてビデオとして作成しています。シミュレーターでうまく動作します。デバイスで実行している間。アプリがクラッシュします。以下にコードとエラーを入れます

 - (void)stopRecording
    {

    [self.displayLink invalidate];
    startTimestamp = 0.0;
    dispatch_async(queue, ^
                   {

                       //if (deferImageprocess) {
                           if (self.writer.status != AVAssetWriterStatusCompleted && self.writer.status != AVAssetWriterStatusUnknown) {
                               [self.writerInput markAsFinished];

                           }

                           if ([self.writer respondsToSelector:@selector(finishWritingWithCompletionHandler:)]) {
                               [self.writer finishWritingWithCompletionHandler:^
                                {

                                    ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
                                    [library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:self.pathStr]
                                                                completionBlock:^(NSURL *assetURL, NSError *error){
                                                                    if (!error)
                                                                    {
                                                                        NSLog(@"Saved Successfully");
                                                                        [self finishBackgroundTask];
                                                                        [self.delegate recordingFinished:[NSString stringWithFormat:@"%@", self.pathStr]];
                                                                    }
                                                                }];
                                }];

                           }
                           else {
                               [self.writer finishWriting];
                               ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init];
                               [library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:self.pathStr]
                                                           completionBlock:^(NSURL *assetURL, NSError *error){
                                                           }];
                               [self finishBackgroundTask];
                               [self restartRecordingIfNeeded];

                           }
                        });

}


**This above to Wirte the video file in Document as well as gallery**

- (void)captureFrame:(CADisplayLink *)displayLink
    {
        dispatch_async(queue, ^
                       {
                           if (self.writerInput.readyForMoreMediaData) {
                               CVReturn status = kCVReturnSuccess;
                               CVPixelBufferRef buffer = NULL;
                               CFTypeRef backingData;

    #if APPSTORE_SAFE || TARGET_IPHONE_SIMULATOR  || TARGET_OS_IPHONE


                               __block UIImage *screenshot = nil;
                               dispatch_sync(dispatch_get_main_queue(), ^{
                                   screenshot = [self screenshot];
                               });
                               CGImageRef image = [[self screenshot] CGImage];
                               CGDataProviderRef dataProvider = CGImageGetDataProvider(image);
                               CFDataRef data = CGDataProviderCopyData(dataProvider);
                               backingData = CFDataCreateMutableCopy(kCFAllocatorDefault, CFDataGetLength(data), data);
                               CFRelease(data);

                               const UInt8 *bytePtr = CFDataGetBytePtr(backingData);

                               status = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,
                                                                     CGImageGetWidth(image),
                                                                     CGImageGetHeight(image),
                                                                     kCVPixelFormatType_32BGRA,
                                                                     (void *)bytePtr,
                                                                     CGImageGetBytesPerRow(image),
                                                                     NULL,
                                                                     NULL,
                                                                     NULL,
                                                                     &buffer);
                               NSLog(@"%d", status);
                               NSParameterAssert(status == kCVReturnSuccess && buffer);
    #else
                               CFTypeRef surface = [UIWindow createScreenIOSurface];
                               backingData = surface;

                               NSDictionary *pixelBufferAttributes = @{(NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA)};
                               status = CVPixelBufferCreateWithIOSurface(NULL, surface, (__bridge CFDictionaryRef)(pixelBufferAttributes), &buffer);
                               NSLog(@"%d", status);
                               NSParameterAssert(status == kCVReturnSuccess && buffer);

    #endif
                               if (buffer) {
                                   CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
                                   CFTimeInterval elapsedTime = currentTime - firstFrameTime;

                                   CMTime presentTime =  CMTimeMake(elapsedTime * TIME_SCALE, TIME_SCALE);

                                   if(![self.writerInputPixelBufferAdaptor appendPixelBuffer:buffer withPresentationTime:presentTime]) {
                                       [self stopRecording];
                                       NSLog(@"Failed");
                                   }

                                   CVPixelBufferRelease(buffer);
                               }

                               CFRelease(backingData);
                           }
                       });

        if (startTimestamp == 0.0) {
            startTimestamp = displayLink.timestamp;
        }

        NSTimeInterval dalta = displayLink.timestamp - startTimestamp;

        if (self.autosaveDuration > 0 && dalta > self.autosaveDuration) {
            startTimestamp = 0.0;
            [self rotateFile];
        }
    }

上記でフレームをキャプチャします。

今、停止中にこのエラーが発生しました。

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '*** -[AVAssetWriterInput markAsFinished] Cannot call method when status is 2'.

ここで何が問題なのかわかりません。何かいい案があれば教えてください

4

1 に答える 1

2

このエラーの原因は

  1. 状況が 2 の場合、ライターを終了としてマークします。

  2. AVAssetWriter インスタンスを再利用しようとしています。記録を開始する必要がある場合は、常に新しいインスタンスを作成することを忘れないでください。

  3. スレッド化の問題です。代わりに、sdk によって提供されるデフォルトのキューが並行しているため、キューを作成してください。それらは並行して動作し、シリアルではありません。

于 2013-11-06T10:46:47.633 に答える