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 时,将 writer 标记为已完成。

  2. 试图重用您的 AVAssetWriter 实例。当您需要开始录制时,请记住始终创建一个新实例。

  3. 线程问题,请创建队列,因为 sdk 提供的默认队列是并发的,它们以并发方式工作而不是串行工作。

于 2013-11-06T10:46:47.633 回答