-
Notifications
You must be signed in to change notification settings - Fork 3.4k
[camera_avfoundation] fix stopVideoRecording waiting indefinitely and video lag at start #7065
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
ba64f20
e2161c3
f2d83af
165afc7
05d19ce
0bfce88
1591697
172b3bf
fb3d713
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,6 +69,7 @@ @interface FLTCam () <AVCaptureVideoDataOutputSampleBufferDelegate, | |
@property(strong, nonatomic) AVCaptureVideoDataOutput *videoOutput; | ||
@property(strong, nonatomic) AVCaptureAudioDataOutput *audioOutput; | ||
@property(strong, nonatomic) NSString *videoRecordingPath; | ||
@property(assign, nonatomic) BOOL isFirstSample; | ||
@property(assign, nonatomic) BOOL isRecording; | ||
@property(assign, nonatomic) BOOL isRecordingPaused; | ||
@property(assign, nonatomic) BOOL videoIsDisconnected; | ||
|
@@ -663,19 +664,19 @@ - (void)captureOutput:(AVCaptureOutput *)output | |
|
||
// ignore audio samples until the first video sample arrives to avoid black frames | ||
// https://github.com/flutter/flutter/issues/57831 | ||
if (_videoWriter.status != AVAssetWriterStatusWriting && output != _captureVideoOutput) { | ||
if (_isFirstSample && output != _captureVideoOutput) { | ||
return; | ||
} | ||
|
||
CMTime currentSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); | ||
|
||
if (_videoWriter.status != AVAssetWriterStatusWriting) { | ||
[_videoWriter startWriting]; | ||
if (_isFirstSample) { | ||
[_videoWriter startSessionAtSourceTime:currentSampleTime]; | ||
// fix sample times not being numeric when pause/resume happens before first sample buffer | ||
// arrives https://github.com/flutter/flutter/issues/132014 | ||
_lastVideoSampleTime = currentSampleTime; | ||
_lastAudioSampleTime = currentSampleTime; | ||
_isFirstSample = NO; | ||
} | ||
|
||
if (output == _captureVideoOutput) { | ||
|
@@ -830,6 +831,13 @@ - (void)startVideoRecordingWithCompletion:(void (^)(FlutterError *_Nullable))com | |
details:nil]); | ||
return; | ||
} | ||
// do not call startWriting in didOutputSampleBuffer to prevent state in which | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: "do not move startWriting call to didOutputSampleBuffer... " Because there should only be 1 place to call |
||
// stopVideoRecordingWithCompletion does not send completion when _isRecording is | ||
// YES but _videoWriter.status is AVAssetWriterStatusUnknown and video lag at start | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you also explain that this happens when stop video is called immediately after start, before the first video sample is arrived (if i understand correctly) |
||
// https://github.com/flutter/flutter/issues/132016 | ||
// https://github.com/flutter/flutter/issues/151319 | ||
[_videoWriter startWriting]; | ||
_isFirstSample = YES; | ||
_isRecording = YES; | ||
_isRecordingPaused = NO; | ||
_videoTimeOffset = CMTimeMake(0, 1); | ||
|
@@ -849,19 +857,17 @@ - (void)stopVideoRecordingWithCompletion:(void (^)(NSString *_Nullable, | |
if (_isRecording) { | ||
_isRecording = NO; | ||
|
||
if (_videoWriter.status != AVAssetWriterStatusUnknown) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you add a comment explaining that it's not necessary to check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, but such a comment loses context here because in sources it is not visible that there was such a check, only in this diff |
||
[_videoWriter finishWritingWithCompletionHandler:^{ | ||
if (self->_videoWriter.status == AVAssetWriterStatusCompleted) { | ||
[self updateOrientation]; | ||
completion(self->_videoRecordingPath, nil); | ||
self->_videoRecordingPath = nil; | ||
} else { | ||
completion(nil, [FlutterError errorWithCode:@"IOError" | ||
message:@"AVAssetWriter could not finish writing!" | ||
details:nil]); | ||
} | ||
}]; | ||
} | ||
[_videoWriter finishWritingWithCompletionHandler:^{ | ||
if (self->_videoWriter.status == AVAssetWriterStatusCompleted) { | ||
[self updateOrientation]; | ||
completion(self->_videoRecordingPath, nil); | ||
self->_videoRecordingPath = nil; | ||
} else { | ||
completion(nil, [FlutterError errorWithCode:@"IOError" | ||
message:@"AVAssetWriter could not finish writing!" | ||
details:nil]); | ||
} | ||
}]; | ||
} else { | ||
NSError *error = | ||
[NSError errorWithDomain:NSCocoaErrorDomain | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be
isFirstVideoSample
?