Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[camera]Fix CameraPreview freezes during startVideoRecording on iOS #1023

Merged
merged 8 commits into from
Mar 13, 2019

Conversation

cvolzke4
Copy link
Contributor

@cvolzke4 cvolzke4 commented Jan 2, 2019

See flutter/flutter#25961 for more information.

@@ -288,9 +288,7 @@ - (void)startVideoRecordingAtPath:(NSString *)path result:(FlutterResult)result
_eventSink(@{@"event" : @"error", @"errorDescription" : @"Setup Writer Failed"});
return;
}
[_captureSession stopRunning];
Copy link
Contributor Author

@cvolzke4 cvolzke4 Jan 2, 2019

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?

Copy link
Contributor

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?

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

@sigurdm sigurdm left a 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
Copy link
Contributor

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.

Copy link
Contributor Author

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.
Copy link
Contributor

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

Copy link
Contributor Author

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 {
Copy link
Contributor

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.

Copy link
Contributor Author

@cvolzke4 cvolzke4 Jan 8, 2019

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:

  1. Start preview, capture still image (takePicture()).
  2. Start preview, capture video+audio recording (startVideoRecording()).
  3. 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.

Copy link
Contributor Author

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?

Copy link
Contributor

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).

Copy link
Contributor Author

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];
Copy link
Contributor

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?

Copy link
Contributor

@bparrishMines bparrishMines left a 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];
Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Contributor Author

@cvolzke4 cvolzke4 Jan 8, 2019

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.

@cyanglaz cyanglaz changed the title Fix CameraPreview freezes during startVideoRecording on iOS [camera]Fix CameraPreview freezes during startVideoRecording on iOS Feb 23, 2019
@cvolzke4 cvolzke4 requested a review from mklim as a code owner March 13, 2019 00:48
@bparrishMines bparrishMines merged commit 236885b into flutter:master Mar 13, 2019
Akachu pushed a commit to Akachu/flutter_camera that referenced this pull request Apr 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants