Avoiding blurriness at start & end of video (even after using setPreferredVideoStabilizationMode:AVCaptureVideoStabilizationModeAuto)?

旧城冷巷雨未停 提交于 2019-11-26 08:37:17

问题


We capture video on iOS while using setPreferredVideoStabilizationMode:AVCaptureVideoStabilizationModeAuto, but the video still sometimes comes out blurry at the start and at the end (fine in the middle, though), which is very problematic because we grab the first frame as a still image (in order to enable video & photo capabilities without switching camera modes).

Placing the device flat on a desk removes all blurriness, so the whole video is sharp throughout. This suggests it has something to do with video stabilization, but is there another property to set?

Does locking the focus mode matter?

Any other troubleshooting tips?

Here is the video capture function from PBJVision, which we use:

- (void)startVideoCapture
{
    if (![self _canSessionCaptureWithOutput:_currentOutput] || _cameraMode != PBJCameraModeVideo) {
        [self _failVideoCaptureWithErrorCode:PBJVisionErrorSessionFailed];
        DLog(@\"session is not setup properly for capture\");
        return;
    }

    DLog(@\"starting video capture\");

    [self _enqueueBlockOnCaptureVideoQueue:^{

        if (_flags.recording || _flags.paused)
            return;

        NSString *guid = [[NSUUID new] UUIDString];
        NSString *outputFile = [NSString stringWithFormat:@\"video_%@.mp4\", guid];

        if ([_delegate respondsToSelector:@selector(vision:willStartVideoCaptureToFile:)]) {
            outputFile = [_delegate vision:self willStartVideoCaptureToFile:outputFile];

            if (!outputFile) {
                [self _failVideoCaptureWithErrorCode:PBJVisionErrorBadOutputFile];
                return;
            }
        }

        NSString *outputDirectory = (_captureDirectory == nil ? NSTemporaryDirectory() : _captureDirectory);
        NSString *outputPath = [outputDirectory stringByAppendingPathComponent:outputFile];
        NSURL *outputURL = [NSURL fileURLWithPath:outputPath];
        if ([[NSFileManager defaultManager] fileExistsAtPath:outputPath]) {
            NSError *error = nil;
            if (![[NSFileManager defaultManager] removeItemAtPath:outputPath error:&error]) {
                [self _failVideoCaptureWithErrorCode:PBJVisionErrorOutputFileExists];

                DLog(@\"could not setup an output file (file exists)\");
                return;
            }
        }

        if (!outputPath || [outputPath length] == 0) {
            [self _failVideoCaptureWithErrorCode:PBJVisionErrorBadOutputFile];

            DLog(@\"could not setup an output file\");
            return;
        }

        if (_mediaWriter) {
            _mediaWriter.delegate = nil;
            _mediaWriter = nil;
        }
        _mediaWriter = [[PBJMediaWriter alloc] initWithOutputURL:outputURL];
        _mediaWriter.delegate = self;

        AVCaptureConnection *videoConnection = [_captureOutputVideo connectionWithMediaType:AVMediaTypeVideo];
        [self _setOrientationForConnection:videoConnection];

        _startTimestamp = CMClockGetTime(CMClockGetHostTimeClock());
        _timeOffset = kCMTimeInvalid;

        _flags.recording = YES;
        _flags.paused = NO;
        _flags.interrupted = NO;
        _flags.videoWritten = NO;

        _captureThumbnailTimes = [NSMutableSet set];
        _captureThumbnailFrames = [NSMutableSet set];

        if (_flags.thumbnailEnabled && _flags.defaultVideoThumbnails) {
            [self captureVideoThumbnailAtFrame:0];
        }

        [self _enqueueBlockOnMainQueue:^{                
            if ([_delegate respondsToSelector:@selector(visionDidStartVideoCapture:)])
                [_delegate visionDidStartVideoCapture:self];
        }];
    }];
}

This code configures PBJVision and starts video capture:

private func initPBJVision() {
    // Configure PBJVision
    pbj.delegate = self
    pbj.cameraMode = .Video
    pbj.cameraOrientation = .Portrait
    pbj.focusMode = .AutoFocus
    pbj.outputFormat = .Preset
    pbj.cameraDevice = .Back
    pbj.thumbnailEnabled = false

    // Log status
    print(\"Configured PBJVision\")

    pbj.startVideoCapture()
}

Once PBJ is ready with its preview, we make the camera focus on the midpoint of the screen.

// Called when PBJVision preview begins
func visionSessionDidStartPreview(vision: PBJVision) {
    // Focus screen at midpoint
    let focus_x = CGFloat(0.5)
    let focus_y = CGFloat(0.5)
}

回答1:


Video is blurry by its nature. 24 or 30 frames per second video will always have some blur in the shot because that's the way our eyes are tricked into believing the pictures are actually moving. The longer shutter speed allows the camera to give the impression of motion.

Photos use a much shorter shutter speed (1/60th of a second or less) to give a clear, still picture.

There's some info here on how to take a picture while recording video:

How to Programmatically Take Photos While Recording Video




回答2:


I do not know about the PBJVision framework, but you could check the adjustingFocus of the AVCaptureDevice before extracting the picture you need.


Apparently, you can check the focusing status of the device by using PBJVision isAdjustingFocus method.



来源:https://stackoverflow.com/questions/34912050/avoiding-blurriness-at-start-end-of-video-even-after-using-setpreferredvideos

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!