IOS adding UIProgressView to AVFoundation AVCaptur

2019-04-16 00:19发布

问题:

I am using AVCaptureMovieFileOutput to record videos and I want to add a UIProgressView to represent how much time there is left before the video stops recording.

I set a max duration of 15 seconds:

CMTime maxDuration = CMTimeMakeWithSeconds(15, 50);
[[self movieFileOutput] setMaxRecordedDuration:maxDuration];

I can't seem to find if AVCaptureMovieFileOutput has a callback for when the video is recording or for when recording begins. My question is, how can I get updates on the progress of the recording? Or if this isn't something that is available, how can I tell when recording begins in order to start a timer?

回答1:

Here is how I was able to add a UIProgressView

recording is a property of AVCaptureFileOutput which is extended by AVCaptureMovieFileOutput

I have a variable movieFileOutput of type AVCaptureMovieFileOutput that I am using to capture data to a QuickTime movie.

@property (nonatomic) AVCaptureMovieFileOutput *movieFileOutput;

I added an observer to the recording property to detect a change in recording.

[self addObserver:self
           forKeyPath:@"movieFileOutput.recording"
              options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew)
              context:RecordingContext];

Then in the callback method:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

I created a while loop to be executed in the background, then I made sure to dispatch updates to the view on the main thread like this:

    dispatch_async([self sessionQueue], ^{ // Background task started
        // While the movie is recording, update the progress bar
        while ([[self movieFileOutput] isRecording]) {
            double duration = CMTimeGetSeconds([[self movieFileOutput] recordedDuration]);
            double time = CMTimeGetSeconds([[self movieFileOutput] maxRecordedDuration]);
            CGFloat progress = (CGFloat) (duration / time);
            dispatch_async(dispatch_get_main_queue(), ^{ // Here I dispatch to main queue and update the progress view.
                [self.progressView setProgress:progress animated:YES];
            });
        }
    });