diff --git a/packages/camera/camera/test/camera_image_stream_test.dart b/packages/camera/camera/test/camera_image_stream_test.dart index 6ac27e513fc..c89e4acaa72 100644 --- a/packages/camera/camera/test/camera_image_stream_test.dart +++ b/packages/camera/camera/test/camera_image_stream_test.dart @@ -215,11 +215,10 @@ class MockStreamingCameraPlatform extends MockCameraPlatform { } @override - Future startVideoRecording(int cameraId, - {Duration? maxVideoDuration}) { + Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) { streamCallLog.add('startVideoRecording'); - return super - .startVideoRecording(cameraId, maxVideoDuration: maxVideoDuration); + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return super.startVideoRecording(cameraId); } @override diff --git a/packages/camera/camera/test/camera_test.dart b/packages/camera/camera/test/camera_test.dart index f10015334d5..0c6a319397e 100644 --- a/packages/camera/camera/test/camera_test.dart +++ b/packages/camera/camera/test/camera_test.dart @@ -1511,14 +1511,17 @@ class MockCameraPlatform extends Mock super.noSuchMethod(Invocation.method(#prepareForVideoRecording, null)); @override - Future startVideoRecording(int cameraId, - {Duration? maxVideoDuration}) => - Future.value(mockVideoRecordingXFile); + Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) { + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); + } + + @override + Future startVideoCapturing(VideoCaptureOptions options) async {} @override - Future startVideoCapturing(VideoCaptureOptions options) { - return startVideoRecording(options.cameraId, - maxVideoDuration: options.maxDuration); + Future stopVideoRecording(int cameraId) { + return Future.value(mockVideoRecordingXFile); } @override diff --git a/packages/camera/camera_android/CHANGELOG.md b/packages/camera/camera_android/CHANGELOG.md index 777f4913eeb..fa7a742c118 100644 --- a/packages/camera/camera_android/CHANGELOG.md +++ b/packages/camera/camera_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.9+8 + +* Removes unused code related to `maxVideoDuration`. + ## 0.10.9+7 * Updates Android Gradle plugin to 8.5.0. diff --git a/packages/camera/camera_android/lib/src/android_camera.dart b/packages/camera/camera_android/lib/src/android_camera.dart index ce0af171562..9cd1df45191 100644 --- a/packages/camera/camera_android/lib/src/android_camera.dart +++ b/packages/camera/camera_android/lib/src/android_camera.dart @@ -267,8 +267,8 @@ class AndroidCamera extends CameraPlatform { @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) async { - return startVideoCapturing( - VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration)); + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); } @override @@ -277,7 +277,6 @@ class AndroidCamera extends CameraPlatform { 'startVideoRecording', { 'cameraId': options.cameraId, - 'maxVideoDuration': options.maxDuration?.inMilliseconds, 'enableStream': options.streamCallback != null, }, ); @@ -626,15 +625,6 @@ class AndroidCamera extends CameraPlatform { cameraEventStreamController.add(CameraClosingEvent( cameraId, )); - case 'video_recorded': - final Map arguments = _getArgumentDictionary(call); - cameraEventStreamController.add(VideoRecordedEvent( - cameraId, - XFile(arguments['path']! as String), - arguments['maxVideoDuration'] != null - ? Duration(milliseconds: arguments['maxVideoDuration']! as int) - : null, - )); case 'error': final Map arguments = _getArgumentDictionary(call); cameraEventStreamController.add(CameraErrorEvent( diff --git a/packages/camera/camera_android/pubspec.yaml b/packages/camera/camera_android/pubspec.yaml index 0dc0371c0e4..1f157f0aefe 100644 --- a/packages/camera/camera_android/pubspec.yaml +++ b/packages/camera/camera_android/pubspec.yaml @@ -3,7 +3,7 @@ description: Android implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.10.9+7 +version: 0.10.9+8 environment: sdk: ^3.4.0 diff --git a/packages/camera/camera_android/test/android_camera_test.dart b/packages/camera/camera_android/test/android_camera_test.dart index 87acd2c0c72..04e2e256837 100644 --- a/packages/camera/camera_android/test/android_camera_test.dart +++ b/packages/camera/camera_android/test/android_camera_test.dart @@ -636,31 +636,6 @@ void main() { expect(channel.log, [ isMethodCall('startVideoRecording', arguments: { 'cameraId': cameraId, - 'maxVideoDuration': null, - 'enableStream': false, - }), - ]); - }); - - test('Should pass maxVideoDuration when starting recording a video', - () async { - // Arrange - final MethodChannelMock channel = MethodChannelMock( - channelName: _channelName, - methods: {'startVideoRecording': null}, - ); - - // Act - await camera.startVideoRecording( - cameraId, - maxVideoDuration: const Duration(seconds: 10), - ); - - // Assert - expect(channel.log, [ - isMethodCall('startVideoRecording', arguments: { - 'cameraId': cameraId, - 'maxVideoDuration': 10000, 'enableStream': false, }), ]); @@ -685,7 +660,6 @@ void main() { expect(channel.log, [ isMethodCall('startVideoRecording', arguments: { 'cameraId': cameraId, - 'maxVideoDuration': null, 'enableStream': true, }), ]); diff --git a/packages/camera/camera_android_camerax/CHANGELOG.md b/packages/camera/camera_android_camerax/CHANGELOG.md index 8db61ac165d..9e8e4fc17c5 100644 --- a/packages/camera/camera_android_camerax/CHANGELOG.md +++ b/packages/camera/camera_android_camerax/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.6.7+1 + +* Updates README to remove references to `maxVideoDuration`, as it was never + visible to app-facing clients, nor was it implemented in `camera_android`. + ## 0.6.7 * Updates AGP version to 8.5.0. diff --git a/packages/camera/camera_android_camerax/README.md b/packages/camera/camera_android_camerax/README.md index b6b1a46a383..bc929109cad 100644 --- a/packages/camera/camera_android_camerax/README.md +++ b/packages/camera/camera_android_camerax/README.md @@ -44,12 +44,12 @@ due to this not currently being supported by CameraX. the plugin will fall back to target 480p (`ResolutionPreset.medium`) if configured with `ResolutionPreset.low`. -### Setting maximum duration and stream options for video capture +### Setting stream options for video capture Calling `startVideoCapturing` with `VideoCaptureOptions` configured with -`maxVideoDuration` and `streamOptions` is currently unsupported do to the -limitations of the CameraX library and the platform interface, respectively, -and thus, those parameters will silently be ignored. +`streamOptions` is currently unsupported do to +limitations of the platform interface, +and thus that parameter will silently be ignored. ## What requires Android permissions diff --git a/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart b/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart index eec9ee8b776..1d068eb24f1 100644 --- a/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart +++ b/packages/camera/camera_android_camerax/lib/src/android_camera_camerax.dart @@ -1013,16 +1013,15 @@ class AndroidCameraCameraX extends CameraPlatform { @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) async { - return startVideoCapturing( - VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration)); + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); } /// Starts a video recording and/or streaming session. /// /// Please see [VideoCaptureOptions] for documentation on the - /// configuration options. Currently, maxVideoDuration and streamOptions - /// are unsupported due to the limitations of CameraX and the platform - /// interface, respectively. + /// configuration options. Currently streamOptions are unsupported due to + /// limitations of the platform interface. @override Future startVideoCapturing(VideoCaptureOptions options) async { if (recording != null) { diff --git a/packages/camera/camera_android_camerax/pubspec.yaml b/packages/camera/camera_android_camerax/pubspec.yaml index f08ec59d47e..da774124a3a 100644 --- a/packages/camera/camera_android_camerax/pubspec.yaml +++ b/packages/camera/camera_android_camerax/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_android_camerax description: Android implementation of the camera plugin using the CameraX library. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_android_camerax issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.6.7 +version: 0.6.7+1 environment: sdk: ^3.4.0 diff --git a/packages/camera/camera_avfoundation/CHANGELOG.md b/packages/camera/camera_avfoundation/CHANGELOG.md index aa067429dd2..cb1d1838942 100644 --- a/packages/camera/camera_avfoundation/CHANGELOG.md +++ b/packages/camera/camera_avfoundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.16+3 + +* Removes unused `maxVideoDuration` code. + ## 0.9.16+2 * Fixes regression taking a picture in torch mode. diff --git a/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart b/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart index 6f947863a3c..d3d5bd8fe4f 100644 --- a/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart +++ b/packages/camera/camera_avfoundation/lib/src/avfoundation_camera.dart @@ -207,8 +207,8 @@ class AVFoundationCamera extends CameraPlatform { @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) async { - return startVideoCapturing( - VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration)); + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); } @override diff --git a/packages/camera/camera_avfoundation/pubspec.yaml b/packages/camera/camera_avfoundation/pubspec.yaml index 4823e0ac52b..897be05383a 100644 --- a/packages/camera/camera_avfoundation/pubspec.yaml +++ b/packages/camera/camera_avfoundation/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_avfoundation description: iOS implementation of the camera plugin. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_avfoundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.9.16+2 +version: 0.9.16+3 environment: sdk: ^3.2.3 diff --git a/packages/camera/camera_web/CHANGELOG.md b/packages/camera/camera_web/CHANGELOG.md index 9788191de35..c9e8e661da4 100644 --- a/packages/camera/camera_web/CHANGELOG.md +++ b/packages/camera/camera_web/CHANGELOG.md @@ -1,5 +1,8 @@ -## NEXT +## 0.3.4 +* Removes `maxVideoDuration`/`maxDuration`, as the feature was never exposed at + the app-facing package level, and is deprecated at the platform interface + level. * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. ## 0.3.3 diff --git a/packages/camera/camera_web/example/integration_test/camera_test.dart b/packages/camera/camera_web/example/integration_test/camera_test.dart index 412ce7148bc..7611e288b84 100644 --- a/packages/camera/camera_web/example/integration_test/camera_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_test.dart @@ -1069,60 +1069,7 @@ void main() { verify(mediaRecorder.start).called(1); }); - testWidgets( - 'starts a video recording ' - 'with maxVideoDuration', (WidgetTester tester) async { - const Duration maxVideoDuration = Duration(hours: 1); - - final Camera camera = Camera( - textureId: 1, - cameraService: cameraService, - ) - ..mediaRecorder = mediaRecorder - ..isVideoTypeSupported = isVideoTypeSupported; - - await camera.initialize(); - await camera.play(); - - await camera.startVideoRecording(maxVideoDuration: maxVideoDuration); - - verify(() => mediaRecorder.start(maxVideoDuration.inMilliseconds)) - .called(1); - }); - group('throws a CameraWebException', () { - testWidgets( - 'with notSupported error ' - 'when maxVideoDuration is 0 milliseconds or less', - (WidgetTester tester) async { - final Camera camera = Camera( - textureId: 1, - cameraService: cameraService, - ) - ..mediaRecorder = mediaRecorder - ..isVideoTypeSupported = isVideoTypeSupported; - - await camera.initialize(); - await camera.play(); - - expect( - () => camera.startVideoRecording(maxVideoDuration: Duration.zero), - throwsA( - isA() - .having( - (CameraWebException e) => e.cameraId, - 'cameraId', - textureId, - ) - .having( - (CameraWebException e) => e.code, - 'code', - CameraErrorCode.notSupported, - ), - ), - ); - }); - testWidgets( 'with notSupported error ' 'when no video types are supported', (WidgetTester tester) async { @@ -1346,46 +1293,6 @@ void main() { }); }); - group('on video data available', () { - late void Function(Event) videoDataAvailableListener; - - setUp(() { - when( - () => mediaRecorder.addEventListener('dataavailable', any()), - ).thenAnswer((Invocation invocation) { - videoDataAvailableListener = - invocation.positionalArguments[1] as void Function(Event); - }); - }); - - testWidgets( - 'stops a video recording ' - 'if maxVideoDuration is given and ' - 'the recording was not stopped manually', - (WidgetTester tester) async { - const Duration maxVideoDuration = Duration(hours: 1); - - final Camera camera = Camera( - textureId: 1, - cameraService: cameraService, - ) - ..mediaRecorder = mediaRecorder - ..isVideoTypeSupported = isVideoTypeSupported; - - await camera.initialize(); - await camera.play(); - await camera.startVideoRecording(maxVideoDuration: maxVideoDuration); - - when(() => mediaRecorder.state).thenReturn('recording'); - - videoDataAvailableListener(FakeBlobEvent(Blob([]))); - - await Future.microtask(() {}); - - verify(mediaRecorder.stop).called(1); - }); - }); - group('on video recording stopped', () { late void Function(Event) videoRecordingStoppedListener; @@ -1543,7 +1450,6 @@ void main() { testWidgets( 'emits a VideoRecordedEvent ' 'when a video recording is created', (WidgetTester tester) async { - const Duration maxVideoDuration = Duration(hours: 1); const String supportedVideoType = 'video/webm'; final MockMediaRecorder mediaRecorder = MockMediaRecorder(); @@ -1580,7 +1486,7 @@ void main() { final StreamQueue streamQueue = StreamQueue(camera.onVideoRecordedEvent); - await camera.startVideoRecording(maxVideoDuration: maxVideoDuration); + await camera.startVideoRecording(); Blob? finalVideo; camera.blobBuilder = (List blobs, String videoType) { @@ -1614,11 +1520,6 @@ void main() { 'name', finalVideo.hashCode.toString(), ), - ) - .having( - (VideoRecordedEvent e) => e.maxVideoDuration, - 'maxVideoDuration', - maxVideoDuration, ), ), ); diff --git a/packages/camera/camera_web/example/integration_test/camera_web_test.dart b/packages/camera/camera_web/example/integration_test/camera_web_test.dart index cfce6c4f5a9..d4c7d582533 100644 --- a/packages/camera/camera_web/example/integration_test/camera_web_test.dart +++ b/packages/camera/camera_web/example/integration_test/camera_web_test.dart @@ -2839,9 +2839,7 @@ void main() { .thenAnswer((Invocation _) => const Stream.empty()); when( - () => camera.startVideoRecording( - maxVideoDuration: any(named: 'maxVideoDuration'), - ), + () => camera.startVideoRecording(), ).thenThrow(exception); final Stream eventStream = diff --git a/packages/camera/camera_web/lib/src/camera.dart b/packages/camera/camera_web/lib/src/camera.dart index acf5ceef888..7512fc62771 100644 --- a/packages/camera/camera_web/lib/src/camera.dart +++ b/packages/camera/camera_web/lib/src/camera.dart @@ -437,18 +437,9 @@ class Camera { /// Starts a new video recording using [html.MediaRecorder]. /// - /// Throws a [CameraWebException] if the provided maximum video duration is invalid - /// or the browser does not support any of the available video mime types - /// from [_videoMimeType]. - Future startVideoRecording({Duration? maxVideoDuration}) async { - if (maxVideoDuration != null && maxVideoDuration.inMilliseconds <= 0) { - throw CameraWebException( - textureId, - CameraErrorCode.notSupported, - 'The maximum video duration must be greater than 0 milliseconds.', - ); - } - + /// Throws a [CameraWebException] if the browser does not support any of the + /// available video mime types from [_videoMimeType]. + Future startVideoRecording() async { mediaRecorder ??= html.MediaRecorder(videoElement.srcObject!, { 'mimeType': _videoMimeType, @@ -461,10 +452,10 @@ class Camera { _videoAvailableCompleter = Completer(); _videoDataAvailableListener = - (html.Event event) => _onVideoDataAvailable(event, maxVideoDuration); + (html.Event event) => _onVideoDataAvailable(event); _videoRecordingStoppedListener = - (html.Event event) => _onVideoRecordingStopped(event, maxVideoDuration); + (html.Event event) => _onVideoRecordingStopped(event); mediaRecorder!.addEventListener( 'dataavailable', @@ -482,36 +473,19 @@ class Camera { videoRecordingErrorController.add(error); }); - if (maxVideoDuration != null) { - mediaRecorder!.start(maxVideoDuration.inMilliseconds); - } else { - // Don't pass the null duration as that will fire a `dataavailable` event directly. - mediaRecorder!.start(); - } + mediaRecorder!.start(); } - void _onVideoDataAvailable( - html.Event event, [ - Duration? maxVideoDuration, - ]) { + void _onVideoDataAvailable(html.Event event) { final html.Blob? blob = (event as html.BlobEvent).data; // Append the recorded part of the video to the list of all video data files. if (blob != null) { _videoData.add(blob); } - - // Stop the recorder if the video has a maxVideoDuration - // and the recording was not stopped manually. - if (maxVideoDuration != null && mediaRecorder!.state == 'recording') { - mediaRecorder!.stop(); - } } - Future _onVideoRecordingStopped( - html.Event event, [ - Duration? maxVideoDuration, - ]) async { + Future _onVideoRecordingStopped(html.Event event) async { if (_videoData.isNotEmpty) { // Concatenate all video data files into a single blob. final String videoType = _videoData.first.type; @@ -526,7 +500,7 @@ class Camera { // Emit an event containing the recorded video file. videoRecorderController.add( - VideoRecordedEvent(textureId, file, maxVideoDuration), + VideoRecordedEvent(textureId, file, null), ); _videoAvailableCompleter?.complete(file); diff --git a/packages/camera/camera_web/lib/src/camera_web.dart b/packages/camera/camera_web/lib/src/camera_web.dart index 900d1c706fe..799d742533a 100644 --- a/packages/camera/camera_web/lib/src/camera_web.dart +++ b/packages/camera/camera_web/lib/src/camera_web.dart @@ -463,8 +463,8 @@ class CameraPlugin extends CameraPlatform { @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) { - return startVideoCapturing( - VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration)); + // Ignore maxVideoDuration, as it is deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); } @override @@ -489,7 +489,7 @@ class CameraPlugin extends CameraPlatform { ); }); - return camera.startVideoRecording(maxVideoDuration: options.maxDuration); + return camera.startVideoRecording(); } on html.DomException catch (e) { throw PlatformException(code: e.name, message: e.message); } on CameraWebException catch (e) { diff --git a/packages/camera/camera_web/pubspec.yaml b/packages/camera/camera_web/pubspec.yaml index 8e47d50a09a..e33a2e0fd28 100644 --- a/packages/camera/camera_web/pubspec.yaml +++ b/packages/camera/camera_web/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_web description: A Flutter plugin for getting information about and controlling the camera on Web. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.3.3 +version: 0.3.4 environment: sdk: ^3.2.0 diff --git a/packages/camera/camera_windows/CHANGELOG.md b/packages/camera/camera_windows/CHANGELOG.md index 6073e0c3ad8..4b164343ecd 100644 --- a/packages/camera/camera_windows/CHANGELOG.md +++ b/packages/camera/camera_windows/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.4 + +* Removes `maxVideoDuration`/`maxDuration`, as the feature was never exposed at + the app-facing package level, and is deprecated at the platform interface + level. + ## 0.2.3 * Converts native platform calls to Pigeon. diff --git a/packages/camera/camera_windows/lib/camera_windows.dart b/packages/camera/camera_windows/lib/camera_windows.dart index b54bc68a19f..51424164871 100644 --- a/packages/camera/camera_windows/lib/camera_windows.dart +++ b/packages/camera/camera_windows/lib/camera_windows.dart @@ -208,8 +208,8 @@ class CameraWindows extends CameraPlatform { @override Future startVideoRecording(int cameraId, {Duration? maxVideoDuration}) async { - return startVideoCapturing( - VideoCaptureOptions(cameraId, maxDuration: maxVideoDuration)); + // Ignore maxVideoDuration, as it is unimplemented and deprecated. + return startVideoCapturing(VideoCaptureOptions(cameraId)); } @override @@ -219,8 +219,8 @@ class CameraWindows extends CameraPlatform { 'Streaming is not currently supported on Windows'); } - await _hostApi.startVideoRecording( - options.cameraId, _pigeonVideoCaptureOptions(options)); + // Currently none of `options` is supported on Windows, so it's not passed. + await _hostApi.startVideoRecording(options.cameraId); } @override @@ -353,18 +353,6 @@ class CameraWindows extends CameraPlatform { cameraId, ), ); - case 'video_recorded': - final Map arguments = - (call.arguments as Map).cast(); - final int? maxDuration = arguments['maxVideoDuration'] as int?; - // This is called if maxVideoDuration was given on record start. - cameraEventStreamController.add( - VideoRecordedEvent( - cameraId, - XFile(arguments['path']! as String), - maxDuration != null ? Duration(milliseconds: maxDuration) : null, - ), - ); case 'error': final Map arguments = (call.arguments as Map).cast(); @@ -420,11 +408,4 @@ class CameraWindows extends CameraPlatform { // ignore: dead_code return PlatformResolutionPreset.max; } - - /// Returns a [VideoCamptureOptions]'s Pigeon representation. - PlatformVideoCaptureOptions _pigeonVideoCaptureOptions( - VideoCaptureOptions options) { - return PlatformVideoCaptureOptions( - maxDurationMilliseconds: options.maxDuration?.inMilliseconds); - } } diff --git a/packages/camera/camera_windows/lib/src/messages.g.dart b/packages/camera/camera_windows/lib/src/messages.g.dart index 2640b62037f..a522461b584 100644 --- a/packages/camera/camera_windows/lib/src/messages.g.dart +++ b/packages/camera/camera_windows/lib/src/messages.g.dart @@ -97,28 +97,6 @@ class PlatformSize { } } -/// Pigeon version of the relevant subset of VideoCaptureOptions. -class PlatformVideoCaptureOptions { - PlatformVideoCaptureOptions({ - this.maxDurationMilliseconds, - }); - - int? maxDurationMilliseconds; - - Object encode() { - return [ - maxDurationMilliseconds, - ]; - } - - static PlatformVideoCaptureOptions decode(Object result) { - result as List; - return PlatformVideoCaptureOptions( - maxDurationMilliseconds: result[0] as int?, - ); - } -} - class _PigeonCodec extends StandardMessageCodec { const _PigeonCodec(); @override @@ -129,11 +107,8 @@ class _PigeonCodec extends StandardMessageCodec { } else if (value is PlatformSize) { buffer.putUint8(130); writeValue(buffer, value.encode()); - } else if (value is PlatformVideoCaptureOptions) { - buffer.putUint8(131); - writeValue(buffer, value.encode()); } else if (value is PlatformResolutionPreset) { - buffer.putUint8(132); + buffer.putUint8(131); writeValue(buffer, value.index); } else { super.writeValue(buffer, value); @@ -148,8 +123,6 @@ class _PigeonCodec extends StandardMessageCodec { case 130: return PlatformSize.decode(readValue(buffer)!); case 131: - return PlatformVideoCaptureOptions.decode(readValue(buffer)!); - case 132: final int? value = readValue(buffer) as int?; return value == null ? null : PlatformResolutionPreset.values[value]; default: @@ -320,8 +293,7 @@ class CameraApi { } /// Starts recording video with the given camera. - Future startVideoRecording( - int cameraId, PlatformVideoCaptureOptions options) async { + Future startVideoRecording(int cameraId) async { final String __pigeon_channelName = 'dev.flutter.pigeon.camera_windows.CameraApi.startVideoRecording$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = @@ -330,8 +302,8 @@ class CameraApi { pigeonChannelCodec, binaryMessenger: __pigeon_binaryMessenger, ); - final List? __pigeon_replyList = await __pigeon_channel - .send([cameraId, options]) as List?; + final List? __pigeon_replyList = + await __pigeon_channel.send([cameraId]) as List?; if (__pigeon_replyList == null) { throw _createConnectionError(__pigeon_channelName); } else if (__pigeon_replyList.length > 1) { diff --git a/packages/camera/camera_windows/pigeons/messages.dart b/packages/camera/camera_windows/pigeons/messages.dart index fe5a86af058..52fb4a196fd 100644 --- a/packages/camera/camera_windows/pigeons/messages.dart +++ b/packages/camera/camera_windows/pigeons/messages.dart @@ -40,13 +40,6 @@ class PlatformSize { final double height; } -/// Pigeon version of the relevant subset of VideoCaptureOptions. -class PlatformVideoCaptureOptions { - PlatformVideoCaptureOptions({required this.maxDurationMilliseconds}); - - final int? maxDurationMilliseconds; -} - @HostApi() abstract class CameraApi { /// Returns the names of all of the available capture devices. @@ -70,7 +63,7 @@ abstract class CameraApi { /// Starts recording video with the given camera. @async - void startVideoRecording(int cameraId, PlatformVideoCaptureOptions options); + void startVideoRecording(int cameraId); /// Finishes recording video with the given camera, and returns the path to /// the resulting file. diff --git a/packages/camera/camera_windows/pubspec.yaml b/packages/camera/camera_windows/pubspec.yaml index 492adffbb12..7e3f7381b4b 100644 --- a/packages/camera/camera_windows/pubspec.yaml +++ b/packages/camera/camera_windows/pubspec.yaml @@ -2,7 +2,7 @@ name: camera_windows description: A Flutter plugin for getting information about and controlling the camera on Windows. repository: https://github.com/flutter/packages/tree/main/packages/camera/camera_windows issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22 -version: 0.2.3 +version: 0.2.4 environment: sdk: ^3.2.0 diff --git a/packages/camera/camera_windows/test/camera_windows_test.dart b/packages/camera/camera_windows/test/camera_windows_test.dart index 887f2eb6768..ca7e7eb9944 100644 --- a/packages/camera/camera_windows/test/camera_windows_test.dart +++ b/packages/camera/camera_windows/test/camera_windows_test.dart @@ -360,23 +360,7 @@ void main() { await plugin.startVideoRecording(cameraId); // Assert - verify(mockApi.startVideoRecording(any, any)); - }); - - test('Should pass maxVideoDuration when starting recording a video', - () async { - // Act - await plugin.startVideoRecording( - cameraId, - maxVideoDuration: const Duration(seconds: 10), - ); - - // Assert - final VerificationResult verification = - verify(mockApi.startVideoRecording(any, captureAny)); - final PlatformVideoCaptureOptions? options = - verification.captured[0] as PlatformVideoCaptureOptions?; - expect(options?.maxDurationMilliseconds, 10000); + verify(mockApi.startVideoRecording(any)); }); test('capturing fails if trying to stream', () async { diff --git a/packages/camera/camera_windows/test/camera_windows_test.mocks.dart b/packages/camera/camera_windows/test/camera_windows_test.mocks.dart index fe72c8165aa..d55db4a6bd5 100644 --- a/packages/camera/camera_windows/test/camera_windows_test.mocks.dart +++ b/packages/camera/camera_windows/test/camera_windows_test.mocks.dart @@ -120,17 +120,10 @@ class MockCameraApi extends _i1.Mock implements _i2.CameraApi { ) as _i3.Future); @override - _i3.Future startVideoRecording( - int? cameraId, - _i2.PlatformVideoCaptureOptions? options, - ) => - (super.noSuchMethod( + _i3.Future startVideoRecording(int? cameraId) => (super.noSuchMethod( Invocation.method( #startVideoRecording, - [ - cameraId, - options, - ], + [cameraId], ), returnValue: _i3.Future.value(), returnValueForMissingStub: _i3.Future.value(), diff --git a/packages/camera/camera_windows/windows/camera.cpp b/packages/camera/camera_windows/windows/camera.cpp index 023d1377b56..7cfc5708ef4 100644 --- a/packages/camera/camera_windows/windows/camera.cpp +++ b/packages/camera/camera_windows/windows/camera.cpp @@ -12,7 +12,6 @@ using flutter::EncodableValue; // Camera channel events. constexpr char kCameraMethodChannelBaseName[] = "plugins.flutter.io/camera_windows/camera"; -constexpr char kVideoRecordedEvent[] = "video_recorded"; constexpr char kCameraClosingEvent[] = "camera_closing"; constexpr char kErrorEvent[] = "error"; @@ -325,24 +324,6 @@ void CameraImpl::OnTakePictureFailed(CameraResult result, } }; -void CameraImpl::OnVideoRecordSucceeded(const std::string& file_path, - int64_t video_duration_ms) { - if (messenger_ && camera_id_ >= 0) { - auto channel = GetMethodChannel(); - - std::unique_ptr message_data = - std::make_unique( - EncodableMap({{EncodableValue("path"), EncodableValue(file_path)}, - {EncodableValue("maxVideoDuration"), - EncodableValue(video_duration_ms)}})); - - channel->InvokeMethod(kVideoRecordedEvent, std::move(message_data)); - } -} - -void CameraImpl::OnVideoRecordFailed(CameraResult result, - const std::string& error){}; - void CameraImpl::OnCaptureError(CameraResult result, const std::string& error) { if (messenger_ && camera_id_ >= 0) { auto channel = GetMethodChannel(); diff --git a/packages/camera/camera_windows/windows/camera.h b/packages/camera/camera_windows/windows/camera.h index 14084f5e484..b72789f2876 100644 --- a/packages/camera/camera_windows/windows/camera.h +++ b/packages/camera/camera_windows/windows/camera.h @@ -130,10 +130,6 @@ class CameraImpl : public Camera { void OnTakePictureSucceeded(const std::string& file_path) override; void OnTakePictureFailed(CameraResult result, const std::string& error) override; - void OnVideoRecordSucceeded(const std::string& file_path, - int64_t video_duration) override; - void OnVideoRecordFailed(CameraResult result, - const std::string& error) override; void OnCaptureError(CameraResult result, const std::string& error) override; // Camera diff --git a/packages/camera/camera_windows/windows/camera_plugin.cpp b/packages/camera/camera_windows/windows/camera_plugin.cpp index 5bbc951956a..089aa28c722 100644 --- a/packages/camera/camera_windows/windows/camera_plugin.cpp +++ b/packages/camera/camera_windows/windows/camera_plugin.cpp @@ -295,7 +295,7 @@ void CameraPlugin::ResumePreview( } void CameraPlugin::StartVideoRecording( - int64_t camera_id, const PlatformVideoCaptureOptions& options, + int64_t camera_id, std::function reply)> result) { auto camera = GetCameraByCameraId(camera_id); if (!camera) { @@ -307,21 +307,13 @@ void CameraPlugin::StartVideoRecording( FlutterError("camera_error", "Pending start recording request exists")); } - int64_t max_video_duration_ms = -1; - const int64_t* requested_max_video_duration_ms = - options.max_duration_milliseconds(); - - if (requested_max_video_duration_ms != nullptr) { - max_video_duration_ms = *requested_max_video_duration_ms; - } - std::optional path = GetFilePathForVideo(); if (path) { if (camera->AddPendingVoidResult(PendingResultType::kStartRecord, std::move(result))) { auto cc = camera->GetCaptureController(); assert(cc); - cc->StartRecord(*path, max_video_duration_ms); + cc->StartRecord(*path); } } else { return result( diff --git a/packages/camera/camera_windows/windows/camera_plugin.h b/packages/camera/camera_windows/windows/camera_plugin.h index 43f0e3a4619..422f5c92b36 100644 --- a/packages/camera/camera_windows/windows/camera_plugin.h +++ b/packages/camera/camera_windows/windows/camera_plugin.h @@ -63,7 +63,7 @@ class CameraPlugin : public flutter::Plugin, int64_t camera_id, std::function reply)> result) override; void StartVideoRecording( - int64_t camera_id, const PlatformVideoCaptureOptions& options, + int64_t camera_id, std::function reply)> result) override; void StopVideoRecording( int64_t camera_id, diff --git a/packages/camera/camera_windows/windows/capture_controller.cpp b/packages/camera/camera_windows/windows/capture_controller.cpp index 9c61d81ab0f..de1aa55f4a1 100644 --- a/packages/camera/camera_windows/windows/capture_controller.cpp +++ b/packages/camera/camera_windows/windows/capture_controller.cpp @@ -259,11 +259,7 @@ HRESULT CaptureControllerImpl::CreateCaptureEngine() { void CaptureControllerImpl::ResetCaptureController() { if (record_handler_ && record_handler_->CanStop()) { - if (record_handler_->IsContinuousRecording()) { - StopRecord(); - } else if (record_handler_->IsTimedRecording()) { - StopTimedRecord(); - } + StopRecord(); } if (preview_handler_) { @@ -491,8 +487,7 @@ HRESULT CaptureControllerImpl::FindBaseMediaTypes() { return S_OK; } -void CaptureControllerImpl::StartRecord(const std::string& file_path, - int64_t max_video_duration_ms) { +void CaptureControllerImpl::StartRecord(const std::string& file_path) { assert(capture_engine_); if (!IsInitialized()) { @@ -523,8 +518,7 @@ void CaptureControllerImpl::StartRecord(const std::string& file_path, // Check MF_CAPTURE_ENGINE_RECORD_STARTED event handling for response // process. - hr = record_handler_->StartRecord(file_path, max_video_duration_ms, - capture_engine_.Get(), + hr = record_handler_->StartRecord(file_path, capture_engine_.Get(), base_capture_media_type_.Get()); if (FAILED(hr)) { // Destroy record handler on error cases to make sure state is resetted. @@ -557,23 +551,6 @@ void CaptureControllerImpl::StopRecord() { } } -// Stops timed recording. Called internally when requested time is passed. -// Check MF_CAPTURE_ENGINE_RECORD_STOPPED event handling for response process. -void CaptureControllerImpl::StopTimedRecord() { - assert(capture_controller_listener_); - if (!record_handler_ || !record_handler_->IsTimedRecording()) { - return; - } - - HRESULT hr = record_handler_->StopRecord(capture_engine_.Get()); - if (FAILED(hr)) { - // Destroy record handler on error cases to make sure state is resetted. - record_handler_ = nullptr; - return capture_controller_listener_->OnVideoRecordFailed( - GetCameraResult(hr), "Failed to record video"); - } -} - // Starts capturing preview frames using preview handler // After first frame is captured, OnPreviewStarted is called void CaptureControllerImpl::StartPreview() { @@ -845,15 +822,8 @@ void CaptureControllerImpl::OnRecordStopped(CameraResult result, if (result == CameraResult::kSuccess) { std::string path = record_handler_->GetRecordPath(); capture_controller_listener_->OnStopRecordSucceeded(path); - if (record_handler_->IsTimedRecording()) { - capture_controller_listener_->OnVideoRecordSucceeded( - path, (record_handler_->GetRecordedDuration() / 1000)); - } } else { capture_controller_listener_->OnStopRecordFailed(result, error); - if (record_handler_->IsTimedRecording()) { - capture_controller_listener_->OnVideoRecordFailed(result, error); - } } } @@ -877,7 +847,6 @@ bool CaptureControllerImpl::UpdateBuffer(uint8_t* buffer, } // Handles capture time update from each processed frame. -// Stops timed recordings if requested recording duration has passed. // Called via IMFCaptureEngineOnSampleCallback implementation. // Implements CaptureEngineObserver::UpdateCaptureTime. void CaptureControllerImpl::UpdateCaptureTime(uint64_t capture_time_us) { @@ -890,14 +859,6 @@ void CaptureControllerImpl::UpdateCaptureTime(uint64_t capture_time_us) { // started. OnPreviewStarted(CameraResult::kSuccess, ""); } - - // Checks if max_video_duration_ms is passed. - if (record_handler_) { - record_handler_->UpdateRecordingTime(capture_time_us); - if (record_handler_->ShouldStopTimedRecording()) { - StopTimedRecord(); - } - } } } // namespace camera_windows diff --git a/packages/camera/camera_windows/windows/capture_controller.h b/packages/camera/camera_windows/windows/capture_controller.h index f2288b5e913..8dd541421f7 100644 --- a/packages/camera/camera_windows/windows/capture_controller.h +++ b/packages/camera/camera_windows/windows/capture_controller.h @@ -87,8 +87,7 @@ class CaptureController { virtual void ResumePreview() = 0; // Starts recording video. - virtual void StartRecord(const std::string& file_path, - int64_t max_video_duration_ms) = 0; + virtual void StartRecord(const std::string& file_path) = 0; // Stops the current video recording. virtual void StopRecord() = 0; @@ -124,8 +123,7 @@ class CaptureControllerImpl : public CaptureController, void StartPreview() override; void PausePreview() override; void ResumePreview() override; - void StartRecord(const std::string& file_path, - int64_t max_video_duration_ms) override; + void StartRecord(const std::string& file_path) override; void StopRecord() override; void TakePicture(const std::string& file_path) override; @@ -183,10 +181,6 @@ class CaptureControllerImpl : public CaptureController, // for preview and video capture. HRESULT FindBaseMediaTypes(); - // Stops timed video record. Called internally when record handler when max - // recording time is exceeded. - void StopTimedRecord(); - // Stops preview. Called internally on camera reset and dispose. HRESULT StopPreview(); diff --git a/packages/camera/camera_windows/windows/capture_controller_listener.h b/packages/camera/camera_windows/windows/capture_controller_listener.h index bc7a173925a..4567f52edc7 100644 --- a/packages/camera/camera_windows/windows/capture_controller_listener.h +++ b/packages/camera/camera_windows/windows/capture_controller_listener.h @@ -106,20 +106,6 @@ class CaptureControllerListener { virtual void OnTakePictureFailed(CameraResult result, const std::string& error) = 0; - // Called by CaptureController when timed recording is successfully recorded. - // - // file_path: Filesystem path of the captured image. - // video_duration: Duration of recorded video in milliseconds. - virtual void OnVideoRecordSucceeded(const std::string& file_path, - int64_t video_duration_ms) = 0; - - // Called by CaptureController if timed recording fails. - // - // result: The kind of result. - // error: A string describing the error. - virtual void OnVideoRecordFailed(CameraResult result, - const std::string& error) = 0; - // Called by CaptureController if capture engine returns error. // For example when camera is disconnected while on use. // diff --git a/packages/camera/camera_windows/windows/messages.g.cpp b/packages/camera/camera_windows/windows/messages.g.cpp index 426dc22c010..bf8020b8386 100644 --- a/packages/camera/camera_windows/windows/messages.g.cpp +++ b/packages/camera/camera_windows/windows/messages.g.cpp @@ -166,52 +166,6 @@ PlatformSize PlatformSize::FromEncodableList(const EncodableList& list) { return decoded; } -// PlatformVideoCaptureOptions - -PlatformVideoCaptureOptions::PlatformVideoCaptureOptions() {} - -PlatformVideoCaptureOptions::PlatformVideoCaptureOptions( - const int64_t* max_duration_milliseconds) - : max_duration_milliseconds_( - max_duration_milliseconds - ? std::optional(*max_duration_milliseconds) - : std::nullopt) {} - -const int64_t* PlatformVideoCaptureOptions::max_duration_milliseconds() const { - return max_duration_milliseconds_ ? &(*max_duration_milliseconds_) : nullptr; -} - -void PlatformVideoCaptureOptions::set_max_duration_milliseconds( - const int64_t* value_arg) { - max_duration_milliseconds_ = - value_arg ? std::optional(*value_arg) : std::nullopt; -} - -void PlatformVideoCaptureOptions::set_max_duration_milliseconds( - int64_t value_arg) { - max_duration_milliseconds_ = value_arg; -} - -EncodableList PlatformVideoCaptureOptions::ToEncodableList() const { - EncodableList list; - list.reserve(1); - list.push_back(max_duration_milliseconds_ - ? EncodableValue(*max_duration_milliseconds_) - : EncodableValue()); - return list; -} - -PlatformVideoCaptureOptions PlatformVideoCaptureOptions::FromEncodableList( - const EncodableList& list) { - PlatformVideoCaptureOptions decoded; - auto& encodable_max_duration_milliseconds = list[0]; - if (!encodable_max_duration_milliseconds.IsNull()) { - decoded.set_max_duration_milliseconds( - encodable_max_duration_milliseconds.LongValue()); - } - return decoded; -} - PigeonCodecSerializer::PigeonCodecSerializer() {} EncodableValue PigeonCodecSerializer::ReadValueOfType( @@ -223,11 +177,7 @@ EncodableValue PigeonCodecSerializer::ReadValueOfType( case 130: return CustomEncodableValue(PlatformSize::FromEncodableList( std::get(ReadValue(stream)))); - case 131: - return CustomEncodableValue( - PlatformVideoCaptureOptions::FromEncodableList( - std::get(ReadValue(stream)))); - case 132: { + case 131: { const auto& encodable_enum_arg = ReadValue(stream); const int64_t enum_arg_value = encodable_enum_arg.IsNull() ? 0 : encodable_enum_arg.LongValue(); @@ -261,16 +211,8 @@ void PigeonCodecSerializer::WriteValue( stream); return; } - if (custom_value->type() == typeid(PlatformVideoCaptureOptions)) { - stream->WriteByte(131); - WriteValue(EncodableValue( - std::any_cast(*custom_value) - .ToEncodableList()), - stream); - return; - } if (custom_value->type() == typeid(PlatformResolutionPreset)) { - stream->WriteByte(132); + stream->WriteByte(131); WriteValue(EncodableValue(static_cast( std::any_cast(*custom_value))), stream); @@ -498,17 +440,8 @@ void CameraApi::SetUp(flutter::BinaryMessenger* binary_messenger, return; } const int64_t camera_id_arg = encodable_camera_id_arg.LongValue(); - const auto& encodable_options_arg = args.at(1); - if (encodable_options_arg.IsNull()) { - reply(WrapError("options_arg unexpectedly null.")); - return; - } - const auto& options_arg = - std::any_cast( - std::get(encodable_options_arg)); api->StartVideoRecording( - camera_id_arg, options_arg, - [reply](std::optional&& output) { + camera_id_arg, [reply](std::optional&& output) { if (output.has_value()) { reply(WrapError(output.value())); return; diff --git a/packages/camera/camera_windows/windows/messages.g.h b/packages/camera/camera_windows/windows/messages.g.h index e2ee53253ff..c20b1bd91af 100644 --- a/packages/camera/camera_windows/windows/messages.g.h +++ b/packages/camera/camera_windows/windows/messages.g.h @@ -137,31 +137,6 @@ class PlatformSize { double height_; }; -// Pigeon version of the relevant subset of VideoCaptureOptions. -// -// Generated class from Pigeon that represents data sent in messages. -class PlatformVideoCaptureOptions { - public: - // Constructs an object setting all non-nullable fields. - PlatformVideoCaptureOptions(); - - // Constructs an object setting all fields. - explicit PlatformVideoCaptureOptions( - const int64_t* max_duration_milliseconds); - - const int64_t* max_duration_milliseconds() const; - void set_max_duration_milliseconds(const int64_t* value_arg); - void set_max_duration_milliseconds(int64_t value_arg); - - private: - static PlatformVideoCaptureOptions FromEncodableList( - const flutter::EncodableList& list); - flutter::EncodableList ToEncodableList() const; - friend class CameraApi; - friend class PigeonCodecSerializer; - std::optional max_duration_milliseconds_; -}; - class PigeonCodecSerializer : public flutter::StandardCodecSerializer { public: PigeonCodecSerializer(); @@ -204,7 +179,7 @@ class CameraApi { std::function reply)> result) = 0; // Starts recording video with the given camera. virtual void StartVideoRecording( - int64_t camera_id, const PlatformVideoCaptureOptions& options, + int64_t camera_id, std::function reply)> result) = 0; // Finishes recording video with the given camera, and returns the path to // the resulting file. diff --git a/packages/camera/camera_windows/windows/record_handler.cpp b/packages/camera/camera_windows/windows/record_handler.cpp index 4a4ae0c7d33..f857c146efc 100644 --- a/packages/camera/camera_windows/windows/record_handler.cpp +++ b/packages/camera/camera_windows/windows/record_handler.cpp @@ -227,15 +227,12 @@ HRESULT RecordHandler::InitRecordSink(IMFCaptureEngine* capture_engine, } HRESULT RecordHandler::StartRecord(const std::string& file_path, - int64_t max_duration, IMFCaptureEngine* capture_engine, IMFMediaType* base_media_type) { assert(!file_path.empty()); assert(capture_engine); assert(base_media_type); - type_ = max_duration < 0 ? RecordingType::kContinuous : RecordingType::kTimed; - max_video_duration_ms_ = max_duration; file_path_ = file_path; recording_start_timestamp_us_ = -1; recording_duration_us_ = 0; @@ -268,9 +265,7 @@ void RecordHandler::OnRecordStopped() { file_path_ = ""; recording_start_timestamp_us_ = -1; recording_duration_us_ = 0; - max_video_duration_ms_ = -1; recording_state_ = RecordState::kNotStarted; - type_ = RecordingType::kNone; } } @@ -282,12 +277,4 @@ void RecordHandler::UpdateRecordingTime(uint64_t timestamp) { recording_duration_us_ = (timestamp - recording_start_timestamp_us_); } -bool RecordHandler::ShouldStopTimedRecording() const { - return type_ == RecordingType::kTimed && - recording_state_ == RecordState::kRunning && - max_video_duration_ms_ > 0 && - recording_duration_us_ >= - (static_cast(max_video_duration_ms_) * 1000); -} - } // namespace camera_windows diff --git a/packages/camera/camera_windows/windows/record_handler.h b/packages/camera/camera_windows/windows/record_handler.h index a8866e75b71..faed3e8ef9c 100644 --- a/packages/camera/camera_windows/windows/record_handler.h +++ b/packages/camera/camera_windows/windows/record_handler.h @@ -19,15 +19,6 @@ namespace camera_windows { using Microsoft::WRL::ComPtr; -enum class RecordingType { - // Camera is not recording. - kNone, - // Recording continues until it is stopped with a separate stop command. - kContinuous, - // Recording stops automatically after requested record time is passed. - kTimed -}; - // States that the record handler can be in. // // When created, the handler starts in |kNotStarted| state and transtions in @@ -53,14 +44,11 @@ class RecordHandler { // Sets record state to: starting. // // file_path: A string that hold file path for video capture. - // max_duration: A int64 value of maximun recording duration. - // If value is -1 video recording is considered as - // a continuous recording. // capture_engine: A pointer to capture engine instance. Used to start // the actual recording. // base_media_type: A pointer to base media type used as a base // for the actual video capture media type. - HRESULT StartRecord(const std::string& file_path, int64_t max_duration, + HRESULT StartRecord(const std::string& file_path, IMFCaptureEngine* capture_engine, IMFMediaType* base_media_type); @@ -77,14 +65,6 @@ class RecordHandler { // sets recording state to: not started. void OnRecordStopped(); - // Returns true if recording type is continuous recording. - bool IsContinuousRecording() const { - return type_ == RecordingType::kContinuous; - } - - // Returns true if recording type is timed recording. - bool IsTimedRecording() const { return type_ == RecordingType::kTimed; } - // Returns true if new recording can be started. bool CanStart() const { return recording_state_ == RecordState::kNotStarted; } @@ -100,22 +80,16 @@ class RecordHandler { // Calculates new recording time from capture timestamp. void UpdateRecordingTime(uint64_t timestamp); - // Returns true if recording time has exceeded the maximum duration for timed - // recordings. - bool ShouldStopTimedRecording() const; - private: // Initializes record sink for video file capture. HRESULT InitRecordSink(IMFCaptureEngine* capture_engine, IMFMediaType* base_media_type); const PlatformMediaSettings media_settings_; - int64_t max_video_duration_ms_ = -1; int64_t recording_start_timestamp_us_ = -1; uint64_t recording_duration_us_ = 0; std::string file_path_; RecordState recording_state_ = RecordState::kNotStarted; - RecordingType type_ = RecordingType::kNone; ComPtr record_sink_; }; diff --git a/packages/camera/camera_windows/windows/test/camera_plugin_test.cpp b/packages/camera/camera_windows/windows/test/camera_plugin_test.cpp index 5329a03e09e..412c46bf8c2 100644 --- a/packages/camera/camera_windows/windows/test/camera_plugin_test.cpp +++ b/packages/camera/camera_windows/windows/test/camera_plugin_test.cpp @@ -541,82 +541,9 @@ TEST(CameraPlugin, StartVideoRecordingHandlerCallsStartRecordWithPath) { return cam->capture_controller_.get(); }); - EXPECT_CALL(*capture_controller, StartRecord(EndsWith(".mp4"), -1)) + EXPECT_CALL(*capture_controller, StartRecord(EndsWith(".mp4"))) .Times(1) - .WillOnce([cam = camera.get()](const std::string& file_path, - int64_t max_video_duration_ms) { - assert(cam->pending_void_result_); - return cam->pending_void_result_(std::nullopt); - }); - - camera->camera_id_ = mock_camera_id; - camera->capture_controller_ = std::move(capture_controller); - - MockCameraPlugin plugin(std::make_unique().get(), - std::make_unique().get(), - std::make_unique()); - - // Add mocked camera to plugins camera list. - plugin.AddCamera(std::move(camera)); - - bool result_called = false; - std::function)> start_video_result = - [&result_called](std::optional reply) { - EXPECT_FALSE(result_called); // Ensure only one reply call. - result_called = true; - EXPECT_FALSE(reply); - }; - - plugin.StartVideoRecording(mock_camera_id, PlatformVideoCaptureOptions(), - std::move(start_video_result)); - - EXPECT_TRUE(result_called); -} - -TEST(CameraPlugin, - StartVideoRecordingHandlerCallsStartRecordWithPathAndCaptureDuration) { - int64_t mock_camera_id = 1234; - int64_t mock_video_duration = 100000; - - std::unique_ptr camera = - std::make_unique(MOCK_DEVICE_ID); - - std::unique_ptr capture_controller = - std::make_unique(); - - EXPECT_CALL(*camera, HasCameraId(Eq(mock_camera_id))) - .Times(1) - .WillOnce([cam = camera.get()](int64_t camera_id) { - return cam->camera_id_ == camera_id; - }); - - EXPECT_CALL(*camera, - HasPendingResultByType(Eq(PendingResultType::kStartRecord))) - .Times(1) - .WillOnce(Return(false)); - - EXPECT_CALL(*camera, - AddPendingVoidResult(Eq(PendingResultType::kStartRecord), _)) - .Times(1) - .WillOnce([cam = camera.get()]( - PendingResultType type, - std::function)> result) { - cam->pending_void_result_ = std::move(result); - return true; - }); - - EXPECT_CALL(*camera, GetCaptureController) - .Times(1) - .WillOnce([cam = camera.get()]() { - assert(cam->pending_void_result_); - return cam->capture_controller_.get(); - }); - - EXPECT_CALL(*capture_controller, - StartRecord(EndsWith(".mp4"), Eq(mock_video_duration))) - .Times(1) - .WillOnce([cam = camera.get()](const std::string& file_path, - int64_t max_video_duration_ms) { + .WillOnce([cam = camera.get()](const std::string& file_path) { assert(cam->pending_void_result_); return cam->pending_void_result_(std::nullopt); }); @@ -639,9 +566,7 @@ TEST(CameraPlugin, EXPECT_FALSE(reply); }; - plugin.StartVideoRecording(mock_camera_id, - PlatformVideoCaptureOptions(&mock_video_duration), - std::move(start_video_result)); + plugin.StartVideoRecording(mock_camera_id, std::move(start_video_result)); EXPECT_TRUE(result_called); } @@ -665,7 +590,7 @@ TEST(CameraPlugin, StartVideoRecordingHandlerErrorOnInvalidCameraId) { EXPECT_CALL(*camera, HasPendingResultByType).Times(0); EXPECT_CALL(*camera, AddPendingVoidResult).Times(0); EXPECT_CALL(*camera, GetCaptureController).Times(0); - EXPECT_CALL(*capture_controller, StartRecord(_, -1)).Times(0); + EXPECT_CALL(*capture_controller, StartRecord(_)).Times(0); camera->camera_id_ = mock_camera_id; @@ -684,8 +609,7 @@ TEST(CameraPlugin, StartVideoRecordingHandlerErrorOnInvalidCameraId) { EXPECT_TRUE(reply); }; - plugin.StartVideoRecording(missing_camera_id, PlatformVideoCaptureOptions(), - std::move(start_video_result)); + plugin.StartVideoRecording(missing_camera_id, std::move(start_video_result)); EXPECT_TRUE(result_called); } diff --git a/packages/camera/camera_windows/windows/test/camera_test.cpp b/packages/camera/camera_windows/windows/test/camera_test.cpp index 986cb72b43a..c5b5a5c97fd 100644 --- a/packages/camera/camera_windows/windows/test/camera_test.cpp +++ b/packages/camera/camera_windows/windows/test/camera_test.cpp @@ -615,47 +615,5 @@ TEST(Camera, TakePictureReportsAccessDenied) { EXPECT_TRUE(result_called); } -TEST(Camera, OnVideoRecordSucceededInvokesCameraChannelEvent) { - std::unique_ptr camera = - std::make_unique(MOCK_DEVICE_ID); - std::unique_ptr capture_controller_factory = - std::make_unique(); - - std::unique_ptr binary_messenger = - std::make_unique(); - - const std::string file_path = "C:\\temp\\filename.mp4"; - const int64_t camera_id = 12345; - std::string camera_channel = - std::string("plugins.flutter.io/camera_windows/camera") + - std::to_string(camera_id); - const int64_t video_duration = 1000000; - - EXPECT_CALL(*capture_controller_factory, CreateCaptureController) - .Times(1) - .WillOnce( - []() { return std::make_unique>(); }); - - // TODO: test binary content. - // First time is video record success message, - // and second is camera closing message. - EXPECT_CALL(*binary_messenger, Send(Eq(camera_channel), _, _, _)).Times(2); - - PlatformMediaSettings media_settings(PlatformResolutionPreset::max, false); - - // Init camera with mock capture controller factory - camera->InitCamera(std::move(capture_controller_factory), - std::make_unique().get(), - binary_messenger.get(), media_settings); - - // Pass camera id for camera - camera->OnCreateCaptureEngineSucceeded(camera_id); - - camera->OnVideoRecordSucceeded(file_path, video_duration); - - // Dispose camera before message channel. - camera = nullptr; -} - } // namespace test } // namespace camera_windows diff --git a/packages/camera/camera_windows/windows/test/capture_controller_test.cpp b/packages/camera/camera_windows/windows/test/capture_controller_test.cpp index adee8addd9c..3d0087b0403 100644 --- a/packages/camera/camera_windows/windows/test/capture_controller_test.cpp +++ b/packages/camera/camera_windows/windows/test/capture_controller_test.cpp @@ -213,7 +213,7 @@ void MockRecordStart(CaptureControllerImpl* capture_controller, EXPECT_CALL(*record_sink, AddStream).Times(2).WillRepeatedly(Return(S_OK)); EXPECT_CALL(*record_sink, SetOutputFileName).Times(1).WillOnce(Return(S_OK)); - capture_controller->StartRecord(mock_path_to_video, -1); + capture_controller->StartRecord(mock_path_to_video); EXPECT_CALL(*camera, OnStartRecordSucceeded()).Times(1); engine->CreateFakeEvent(S_OK, MF_CAPTURE_ENGINE_RECORD_STARTED); @@ -789,7 +789,7 @@ TEST(CaptureController, StartRecordWithSettingsSuccess) { .Times(1) .WillOnce(Return(S_OK)); - capture_controller->StartRecord(mock_path_to_video, -1); + capture_controller->StartRecord(mock_path_to_video); EXPECT_CALL(*camera, OnStartRecordSucceeded()).Times(1); engine->CreateFakeEvent(S_OK, MF_CAPTURE_ENGINE_RECORD_STARTED); @@ -839,7 +839,7 @@ TEST(CaptureController, ReportsStartRecordError) { Eq("Failed to start video recording"))) .Times(1); - capture_controller->StartRecord("mock_path", -1); + capture_controller->StartRecord("mock_path"); capture_controller = nullptr; texture_registrar = nullptr; @@ -880,7 +880,7 @@ TEST(CaptureController, ReportsStartRecordAccessDenied) { Eq("Failed to start video recording"))) .Times(1); - capture_controller->StartRecord("mock_path", -1); + capture_controller->StartRecord("mock_path"); capture_controller = nullptr; texture_registrar = nullptr; @@ -933,7 +933,7 @@ TEST(CaptureController, ReportsStartRecordErrorEvent) { .Times(1) .WillOnce(Return(S_OK)); - capture_controller->StartRecord(mock_path_to_video, -1); + capture_controller->StartRecord(mock_path_to_video); // Send a start record failed event EXPECT_CALL(*camera, OnStartRecordSucceeded).Times(0); @@ -999,7 +999,7 @@ TEST(CaptureController, ReportsStartRecordAccessDeniedEvent) { .WillOnce(Return(S_OK)); // Send a start record failed event - capture_controller->StartRecord(mock_path_to_video, -1); + capture_controller->StartRecord(mock_path_to_video); EXPECT_CALL(*camera, OnStartRecordSucceeded).Times(0); EXPECT_CALL(*camera, OnStartRecordFailed(Eq(CameraResult::kAccessDenied), diff --git a/packages/camera/camera_windows/windows/test/mocks.h b/packages/camera/camera_windows/windows/test/mocks.h index 5d52797b0dd..07718a017f7 100644 --- a/packages/camera/camera_windows/windows/test/mocks.h +++ b/packages/camera/camera_windows/windows/test/mocks.h @@ -172,11 +172,6 @@ class MockCamera : public Camera { MOCK_METHOD(void, OnTakePictureFailed, (CameraResult result, const std::string& error), (override)); - MOCK_METHOD(void, OnVideoRecordSucceeded, - (const std::string& file_path, int64_t video_duration), - (override)); - MOCK_METHOD(void, OnVideoRecordFailed, - (CameraResult result, const std::string& error), (override)); MOCK_METHOD(void, OnCaptureError, (CameraResult result, const std::string& error), (override)); @@ -251,9 +246,7 @@ class MockCaptureController : public CaptureController { MOCK_METHOD(void, StartPreview, (), (override)); MOCK_METHOD(void, ResumePreview, (), (override)); MOCK_METHOD(void, PausePreview, (), (override)); - MOCK_METHOD(void, StartRecord, - (const std::string& file_path, int64_t max_video_duration_ms), - (override)); + MOCK_METHOD(void, StartRecord, (const std::string& file_path), (override)); MOCK_METHOD(void, StopRecord, (), (override)); MOCK_METHOD(void, TakePicture, (const std::string& file_path), (override)); };