flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
163.18k stars 26.86k forks source link

When is recording interrupted by alarm or phone call video is improperly shifted #151253

Open misos1 opened 5 days ago

misos1 commented 5 days ago

Steps to reproduce

  1. run code sample
  2. start recording
  3. make some alarm or phone call happen during recording
  4. stop alarm or phone call
  5. stop video recording and check the result

After you try to stop the alarm or phone call it may often crash due to #132073, you can either try to reproduce it again (and it may need some considerable amount of tries) or use patch from https://github.com/flutter/packages/pull/6901.

Expected results

Video and audio synchronized. Recording should be probably paused during such an event as an alarm or phone call.

Actual results

In the attached video is recording of counting. What is actually recorded here is the screen of the device after step 5. At number 11 in the video the alarm started and at 24 stopped. It can be heard that audio is seemingly properly handled but video just shows a static frame between 11 and 24 and only after those 13 seconds for which alarm sounded continues from 24 and up.

Code sample

Code sample ```dart import "dart:io"; import "package:flutter/material.dart"; import "package:camera/camera.dart"; import "package:video_player/video_player.dart"; void main() { runApp(const MaterialApp(home: MyHomePage())); } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { bool loading = true; bool recording = false; late CameraController camera_cont; String? file; @override void initState() { super.initState(); init_camera(); } init_camera() async { final cameras = await availableCameras(); camera_cont = CameraController(cameras.firstWhere((camera) => camera.lensDirection == CameraLensDirection.back), ResolutionPreset.ultraHigh); await camera_cont.initialize(); setState(() => loading = false); await camera_cont.prepareForVideoRecording(); } void record() async { await camera_cont.startVideoRecording(); setState(() => recording = true); } void stop() async { final f = await camera_cont.stopVideoRecording(); setState(() => file = f.path); } @override Widget build(BuildContext context) { if(loading)return const Center(child: CircularProgressIndicator()); if(file != null)return VideoPlayer(VideoPlayerController.file(File(file!))..initialize()..setLooping(true)..play()); return Stack( alignment: Alignment.bottomCenter, children: [ CameraPreview(camera_cont), if(recording)FilledButton(onPressed: stop, child: const Text("Stop")) else FilledButton(onPressed: record, child: const Text("Record")), ], ); } } ```

Screenshots or Video

Screenshots / Video demonstration https://github.com/flutter/flutter/assets/30872003/c424aa9e-3691-433f-8342-df8216ad42f3

Logs

Logs ```console [Paste your logs here] ```

Flutter Doctor output

Doctor output ```console [✓] Flutter (Channel stable, 3.22.2, on macOS 14.5 23F79 darwin-x64) ```
darshankawar commented 5 days ago

Thanks for the report @misos1 Please check https://github.com/flutter/flutter/issues/131127 and https://github.com/flutter/flutter/issues/132560#issuecomment-1678949111 to see if it helps in your case or not.

misos1 commented 5 days ago

No, those 2 are about phone calls during playing in the video player, this one is about camera recording as should be clear from title and description. Video player is used only to make it easy to see corrupted video.

darshankawar commented 4 days ago

Thanks for the update. The video seems to be paused during the time phone call or alarm goes off. Can you check if VideoPlayerController still reports "isPlaying" as true during this time ?

misos1 commented 3 days ago

@darshankawar No, a phone call or alarm goes off during recording and not during playback, of course isPlaying is true all the time.

darshankawar commented 1 day ago

@misos1 I checked with native iOS camera and set a timer which went off during camera recording and the recording does pause. Can you check at your end as well ? You may also confirm on native Android as well.

misos1 commented 1 day ago

@darshankawar If you mean the pre-installed camera app from apple it behaves differently for me, but what does that have to do with this issue? Does yours also produce video where audio is shifted?

darshankawar commented 12 hours ago

but what does that have to do with this issue?

By referring to native behavior, I was trying to indicate that the behavior also occurs in native app, so it may not be specific to Flutter only. Are you experiencing this on iOS or Android ?

Does yours also produce video where audio is shifted?

The recording goes blur when alarm goes off in native.

misos1 commented 2 hours ago

So let's compare them (this can be also triggered by just placing an app in the background during recording).

Camera app from apple ("native"):

  1. run it
  2. start recording
  3. make alarm happen (that means it needs to be setup prior recording in a way it triggers during recording)
  4. alarm will show as that notification-like bubble at top and camera preview blurs, finishes video and stores it in videos
  5. dismiss alarm by swiping up on that bubble, then check video and notice that audio is aligned properly to image data

Flutter code sample provided above using camera plugin (wait at least 5 seconds before each step so it is actually visible and also do not put app in background during these steps except you test this instead of alarm or phone call):

  1. run code sample
  2. start recording
  3. make alarm happen (that means it needs to be setup prior recording in a way it triggers during recording)
  4. alarm will show as that notification-like bubble at top and camera preview stops receiving new data like with native
  5. dismiss alarm by swiping up on that bubble, video preview now continues to receive new data from camera
  6. stop video recording, now the resulting video does not look right, there is that first segment which was recorded before alarm happened where is audio aligned to image properly, then second segment where first plays audio and there is shown just still image and after that plays some more video frames, audio is noticeably shifted against image data

I would say there is a big difference between native which produces usable video and flutter which will produce garbage in such case and you have to dump it. It would be ok if it just stopped or paused and continued normally without that audio shifting after the alarm is dismissed.