Repository: flutter
Issue: Error while Recording Video using Camera pugin ^0.8.1
Labels: c: crash,p: camera,package,team-ecosystem,P2,triaged-ecosystem

In an application which I am currently working, we are supposed to record a video for an hour. We are capturing the video in 2 min window chunks in order to perform certain operations on the video chunks after recording them.

The consecutive startVideoRecording() and stopVideoRecording() works perfectly in most of the cases but in some devices it throws a Camera Exception

## Steps to Reproduce

**Min Reproducible Code:**


<details>
<summary>code sample</summary>

```dart
import 'dart:async';

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';

List<CameraDescription> cameras;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  cameras = await availableCameras();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CameraApp(title: 'Camera Test'),
    );
  }
}

class CameraApp extends StatefulWidget {
  CameraApp({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _CameraAppState createState() => _CameraAppState();
}

class _CameraAppState extends State<CameraApp> {
  CameraController _cameraController;
  Timer _timer;
  int _captureWindow = 120;
  bool _isTestInProgress = false;

  @override
  void initState() {
    super.initState();
    CameraDescription _cameraDescription = cameras.firstWhere(
      (CameraDescription camera) =>
          camera.lensDirection == CameraLensDirection.front,
    );
    _cameraController = CameraController(
      _cameraDescription,
      ResolutionPreset.low,
      enableAudio: true,
    );

    _cameraController.initialize().then((value) {
      if (!mounted) {
        return;
      }

      setState(() {});
    });
  }

  @override
  void dispose() {
    _cameraController.dispose();
    super.dispose();
  }

  void _startTest() async {
    setState(() {
      _isTestInProgress = true;
    });
    await _cameraController.startVideoRecording();
    print('Started Video Recording');
    _timer = new Timer.periodic(new Duration(seconds: 1), (timer) async {
      int duration = timer.tick;
      print('Duration:$duration');
      if (duration != 0 && duration % _captureWindow == 0) {
        try {
          XFile file = await _cameraController.stopVideoRecording();
          print('Video Captured Successfully at path: ${file.path}');
        } catch (error) {
          // Camera Exception is thrown
          print('Error Encountered while stopping the camera:$error');
        }
        try {
          await _cameraController.startVideoRecording();
        } catch (error) {
          // Camera Exception is not thrown here
          print('Error Encountered while starting the camera:$error');
        }
        print('Started Video Recording');
      }
    });
  }

  void _stopTest() async {
    setState(() {
      _isTestInProgress = false;
    });
    _timer.cancel();
    try {
      XFile file = await _cameraController.stopVideoRecording();
      print('Test Concluded');
      print('Video Captured Successfully at path: ${file.path}');
    } catch (error) {
      print('Error Encountered while stopping the camera:$error');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _cameraController.value.isInitialized
                ? CameraPreview(_cameraController)
                : Container(),
            _isTestInProgress
                ? TextButton(
                    onPressed: _stopTest,
                    child: Container(child: Text('STOP TEST')))
                : TextButton(
                    onPressed: _startTest,
                    child: Container(
                      child: Text('START TEST'),
                    ))
          ],
        ),
      ),
    );
  }
}
```
</details>



**Expected results:** 
- The App should capture the consecutive video chunks with out any error.

**Actual results:**
- The application throws an error on stop video recording  
- In case the error occurs on stop video recording in the actual production app we are disposing and reinitializing the camera controller and then it functions as it is expected but we are losing a 2 min video chunk there.
- There is also a chance of this exact pattern repeating again after recording some video chunks successfully

<details>
  <summary>Logs</summary>

**Error logs displayed on startVideoRecording(). No CameraException is thrown at this point**

```
I/flutter (29268): Started Video Recording
W/art     (29268): Long monitor contention with owner main (29268) at void android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSessionInternal(android.hardware.camera2.params.InputConfiguration, java.util.List, android.hardware.camera2.CameraCaptureSession$StateCallback, android.os.Handler, boolean)(CameraDeviceImpl.java:586) waiters=0 in void android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks.onDeviceError(int, android.hardware.camera2.impl.CaptureResultExtras) for 130ms
E/CameraCaptureSession(29268): Session 9: Exception while stopping repeating:
E/CameraCaptureSession(29268): android.hardware.camera2.CameraAccessException: CAMERA_ERROR (3): The camera device has encountered a serious error
E/CameraCaptureSession(29268): 	at android.hardware.camera2.impl.CameraDeviceImpl.checkIfCameraClosedOrInError(CameraDeviceImpl.java:2023)
E/CameraCaptureSession(29268): 	at android.hardware.camera2.impl.CameraDeviceImpl.stopRepeating(CameraDeviceImpl.java:952)
E/CameraCaptureSession(29268): 	at android.hardware.camera2.impl.CameraCaptureSessionImpl.close(CameraCaptureSessionImpl.java:395)
E/CameraCaptureSession(29268): 	at io.flutter.plugins.camera.Camera.closeCaptureSession(Camera.java:1171)
E/CameraCaptureSession(29268): 	at io.flutter.plugins.camera.Camera.close(Camera.java:1177)
E/CameraCaptureSession(29268): 	at io.flutter.plugins.camera.Camera$1.onError(Camera.java:252)
E/CameraCaptureSession(29268): 	at android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$1.run(CameraDeviceImpl.java:1684)
E/CameraCaptureSession(29268): 	at android.os.Handler.handleCallback(Handler.java:754)
E/CameraCaptureSession(29268): 	at android.os.Handler.dispatchMessage(Handler.java:95)
E/CameraCaptureSession(29268): 	at android.os.Looper.loop(Looper.java:163)
E/CameraCaptureSession(29268): 	at android.app.ActivityThread.main(ActivityThread.java:6238)
E/CameraCaptureSession(29268): 	at java.lang.reflect.Method.invoke(Native Method)
E/CameraCaptureSession(29268): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:933)
E/CameraCaptureSession(29268): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

```

**Error logs displayed on stopVideoRecording().CameraException is thrown at this point**

```
E/MethodChannel#plugins.flutter.io/camera(29268): Failed to handle method call
E/MethodChannel#plugins.flutter.io/camera(29268): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.camera2.CameraCaptureSession.abortCaptures()' on a null object reference
E/MethodChannel#plugins.flutter.io/camera(29268): 	at io.flutter.plugins.camera.Camera.stopVideoRecording(Camera.java:654)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at io.flutter.plugins.camera.MethodCallHandlerImpl.onMethodCall(MethodCallHandlerImpl.java:120)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:233)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:818)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at android.os.MessageQueue.next(MessageQueue.java:323)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at android.os.Looper.loop(Looper.java:142)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at android.app.ActivityThread.main(ActivityThread.java:6238)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:933)
E/MethodChannel#plugins.flutter.io/camera(29268): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
I/flutter (29268): Error Encountered while stopping the camera:CameraException(error, Attempt to invoke virtual method 'void android.hardware.camera2.CameraCaptureSession.abortCaptures()' on a null object reference)
I/flutter (29268): Error Encountered while starting the camera:CameraException(A video recording is already started., startVideoRecording was called when a recording is already started.)

```

</details>

**Flutter Doctor**

```
[√] Flutter (Channel stable, 2.0.2, on Microsoft Windows [Version 10.0.19041.867], locale en-US)
    • Flutter version 2.0.2 at C:\Users\taran\App_dev\Flutter\flutter
    • Framework revision 8962f6dc68 (3 weeks ago), 2021-03-11 13:22:20 -0800
    • Engine revision 5d8bf811b3
    • Dart version 2.12.1

[√] Android toolchain - develop for Android devices (Android SDK version 30.0.1) 
    • Android SDK at C:\Users\taran\AppData\Local\Android\sdk
    • Platform android-30, build-tools 30.0.1
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java       
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[√] Android Studio (version 4.0)
    • Android Studio at C:\Program Files\Android\Android Studio      
    • Flutter plugin version 47.1.2
    • Dart plugin version 193.7361
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)  

[√] VS Code (version 1.54.3)
    • VS Code at C:\Users\taran\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.20.0

[√] Connected device (3 available)
    • Redmi 4 (mobile) • cfb476ed7d84 • android-arm64  • Android 7.1.2 (API 25)    
    • Chrome (web)     • chrome       • web-javascript • Google Chrome 89.0.4389.90
    • Edge (web)       • edge         • web-javascript • Microsoft Edge 89.0.774.63

• No issues found!
```