-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[camera]Fix CameraPreview freezes during startVideoRecording on iOS #1023
Conversation
@@ -288,9 +288,7 @@ - (void)startVideoRecordingAtPath:(NSString *)path result:(FlutterResult)result | |||
_eventSink(@{@"event" : @"error", @"errorDescription" : @"Setup Writer Failed"}); | |||
return; | |||
} | |||
[_captureSession stopRunning]; |
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.
This stopRunning() / startRunning() pair interferes with the CameraPreview view, causing it to freeze momentarily. Are they needed?
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.
I think you are right that they are not needed.
I no longer have an iOS setup to test it. Does recording work without them?
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.
I checked out their branch and it everything still works when it's removed on my iphone 6.
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.
Thanks Maurice for checking that. It also seems to work on my iPhone 7.
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.
Thanks for looking into this!
I have a few comments, but generally this looks good.
I'm no longer on the flutter team, so would wait for @bparrishMines to approve and land this.
@@ -515,4 +516,4 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result | |||
} | |||
} | |||
|
|||
@end | |||
@end |
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.
nit: this lost a newline.
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.
Re-added.
@@ -222,6 +222,16 @@ class CameraController extends ValueNotifier<CameraValue> { | |||
return _creatingCompleter.future; | |||
} | |||
|
|||
/// Prepare the capture session for video recording. | |||
/// Preparing audio can cause a minor delay in the CameraPreview view on iOS. |
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.
Nit: leave an empty line after the first line in dart-doc comments
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.
Fixed.
/// that would otherwise be experienced when video recording is started. | ||
/// | ||
/// Throws a [CameraException] if the prepare fails. | ||
Future<void> prepareForVideoRecording() async { |
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.
Is there some way we can avoid exposing this on the dart side?
Could we always call this as part of the initialization of the camera itself or is that too costly if the camera is only started much later?
It seems annoying for the user to have several initialization steps to do - and it also exposes platform specifics, so it would be nice to avoid if possible.
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.
There are three use cases to consider:
- Start preview, capture still image (takePicture()).
- Start preview, capture video+audio recording (startVideoRecording()).
- Start preview,
Capture still image,
Switch to 'video preview' (call prepareForVideoRecording() here),
Start video+audio recording (expect no delay).
Today in flutter, use cases #2 and #3 cause a delay in the preview when startVideoRecording() is started.
Use case #3 without this delay would look like this (iPhone native camera app):
https://drive.google.com/open?id=17OAkOADgcSMgyNtg6TkN6Gj3fYkXAiye0Q
This demo doesn't show a delay when starting video capture, presumably because audio capture is initialized by the native app when the user taps the 'Video' button while fuzzing the preview view. This isn't possible in flutter without a prepareForVideoRecording(), or initializing audio early.
Initializing audio early is an option, but isn't ideal:
- Use case Add url-launcher plugin #1 would require audio permissions.
- Use case #3 would have undue delay on preview init, if the user only intends to capture a still image.
prepareForVideoRecording() is an optional optimization, giving the developer the option of choosing when to take on the delay in the preview view.
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.
Any more thoughts on this?
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.
Why not have both?
Can we manage some initialization state (presumably on iOS side?) so that if the user has not called prepareForVideoRecording(), it still works? My guess is that majority of our users won't care about that delay so forcing them to call an additional API is harsh. For the remaining users, having this fine tuned control is great.
We should also document this behavior (that this is an optional call).
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.
prepareForVideoRecording() is intended to be an optional call, it would only be required for users that care about performance in the above way.
I've added a comment to make this more clear.
@@ -288,9 +288,7 @@ - (void)startVideoRecordingAtPath:(NSString *)path result:(FlutterResult)result | |||
_eventSink(@{@"event" : @"error", @"errorDescription" : @"Setup Writer Failed"}); | |||
return; | |||
} | |||
[_captureSession stopRunning]; |
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.
I think you are right that they are not needed.
I no longer have an iOS setup to test it. Does recording work without them?
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.
PR looks good. I tested it on my iphone 6 and the freeze is now significantly shorter with this addition.
@@ -288,9 +288,7 @@ - (void)startVideoRecordingAtPath:(NSString *)path result:(FlutterResult)result | |||
_eventSink(@{@"event" : @"error", @"errorDescription" : @"Setup Writer Failed"}); | |||
return; | |||
} | |||
[_captureSession stopRunning]; |
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.
I checked out their branch and it everything still works when it's removed on my iphone 6.
@@ -202,6 +202,12 @@ public void onMethodCall(MethodCall call, final Result result) { | |||
camera.takePicture((String) call.argument("path"), result); | |||
break; | |||
} | |||
case "prepareForVideoRecording": | |||
{ | |||
// not yet implemented for Android |
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.
Would this need to be implemented on Android? If it does, this would require a // Todo: ...
If not, I would include that this method does nothing on Android in the documentation on the dart side.
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.
I haven't tried the camera on Android, but if it would only be required there if it suffers from the same freezing issue.
I've updated the comment re Android no-op.
… address review comment" This reverts commit 8f28873.
See flutter/flutter#25961 for more information.