Repository: flutter
Issue: [camera_avfoundation] Separate time offsets for video and audio can cause shifted audio
Labels: platform-ios,p: camera,package,has reproducible steps,P2,team-ios,triaged-ios,found in release: 3.22

### Steps to reproduce

1. run code sample
2. when ready press Start
3. wait until it counts to 200 and there is Stop button
4. record something where will be clear if audio is shifted and press Stop
5. recorded video will be playing in loop, there will be also that potentially lengthly initial segment recorded while counting

When encountering a crash due to other bugs repeat from step 1.

### Expected results

No shifted audio.

### Actual results

Shifted audio. There is no sense for these offsets to be separate `_videoTimeOffset` and `_audioTimeOffset`. What they actually mean is how much time the camera controller spent in a paused state and there should be just a single such value, otherwise audio can be desynchronised.

### Code sample

<details open><summary>Code sample</summary>

```dart
import "dart:io";
import "package:flutter/material.dart";
import "package:camera/camera.dart";
import "package:video_player/video_player.dart";

void main()
{
	runApp(Builder(builder: (context) => const MaterialApp(home: MyHomePage())));
}

class MyHomePage extends StatefulWidget
{
	const MyHomePage({super.key});
	@override State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
{
	bool loading = false;
	bool ready = false;
	int counter = 0;
	CameraController? camera_cont;
	VideoPlayerController? cont;

	@override void dispose()
	{
		camera_cont?.dispose();
		super.dispose();
	}

	init_camera() async
	{
		setState(() => loading = true);
		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();
		await camera_cont!.startVideoRecording();
		for(int i = 0; i < 200; i++)
		{
			setState(() => counter = i);
			await Future.delayed(const Duration(milliseconds: 100));
			await camera_cont!.pauseVideoRecording();
			await camera_cont!.resumeVideoRecording();
		}
		setState(() => ready = true);
	}

	void stop() async
	{
		final file = await camera_cont!.stopVideoRecording();
		setState(() => cont = VideoPlayerController.file(File(file.path))..initialize()..setLooping(true)..play());
	}

	@override Widget build(BuildContext context)
	{
		if(camera_cont == null && !loading)return Center(child: FilledButton(onPressed: init_camera, child: const Text("Start")));
		if(cont != null)return VideoPlayer(cont!);
		if(loading)return const Center(child: CircularProgressIndicator());
		return Stack(
			alignment: Alignment.center,
			children: [
				CameraPreview(camera_cont!),
				if(!ready)Text("$counter"),
				if(!ready)const CircularProgressIndicator(),
				if(ready)FilledButton(onPressed: stop, child: const Text("Stop")),
			],
		);
	}
}
```

</details>


### Screenshots or Video

<details open>
<summary>Screenshots / Video demonstration</summary>


https://github.com/flutter/flutter/assets/30872003/d9616147-7f13-4e4a-b26c-296ce54d818d


</details>

Original video: https://www.youtube.com/watch?v=R6DiFlAXrS0

### Logs

<details open><summary>Logs</summary>

```console
[Paste your logs here]
```

</details>


### Flutter Doctor output

<details open><summary>Doctor output</summary>

```console
[✓] Flutter (Channel stable, 3.22.2, on macOS 14.5 23F79 darwin-x64)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
```

</details>