android – Camera video recording freezes on starting the video for the first time in Flutter


Following are my specs:

Computer: Macbook M1;
Phone: iPhone 13 Pro, iOS 17.1.2;
Flutter: 3.16.4

Package: camera: ^0.10.5+9

I am trying to record a video, but with the fresh install the first time the video hangs/freezes between 1 to 10 seconds, before streaming properly. But, going back to the previous screen and coming back again does not create a problem. Same is the case with going to the next screen and coming back to the camera screen.

Following are the steps that I am taking to reach the video screen

  1. Fresh launch the app
  2. Go to Splash Screen
  3. Go to Intermediary Screen
  4. Go to Open Camera Screen
  5. Page opens and asks for camera and microphone permissions
  6. Tap the Start Video Recording button
  7. Screen freezes for some time

Following is my code:

import 'dart:async';
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';


@RoutePage()
class CameraPage extends StatefulWidget {
  
  const CameraPage(
      {Key? key})
      : super(key: key);

  @override
  State<CameraPage> createState() => _CameraPageState();
}

class _CameraPageState extends State<CameraPage> {
  bool isRecording = false;
  bool isCameraLoaded = false;
  List<CameraDescription>? cameras;
  late CameraController _cameraController;

  String timeString = "00:00";
  Stopwatch stopwatch = Stopwatch();
  Timer? timer;

  void startTimer() {
    stopwatch.start();
    timer = Timer.periodic(Duration(seconds: 1), update);
  }

  void update(Timer t) {
    if (stopwatch.isRunning) {
      setState(
        () {
          timeString = (stopwatch.elapsed.inMinutes % 60)
                  .toString()
                  .padLeft(timerTextPadding, "0") +
              ":" +
              (stopwatch.elapsed.inSeconds % 60)
                  .toString()
                  .padLeft(timerTextPadding, "0");
        },
      );
    }
  }

  void resetTimer() {
    timer!.cancel();
    stopwatch.reset();
    setState(() {
      timeString = "00:00";
    });
    stopwatch.stop();
  }

  void stopTimer() {
    setState(() {
      timer?.cancel();
      stopwatch.stop();
    });
  }

  @override
  void initState() {
    super.initState();
    loadCamera();
  }

  @override
  void dispose() {
    _cameraController.pauseVideoRecording();
    _cameraController.dispose();
    timer!.cancel();
    super.dispose();
  }

  void loadCamera() async {
    final cameras = await availableCameras();
    var camera = cameras.first;
    _cameraController =
        CameraController(camera, ResolutionPreset.medium, enableAudio: false);

    await _cameraController.initialize().then(
          (_) => {
            if (mounted)
              {
                setState(
                  () {
                    _prepareForVideoRecording();
                  },
                )
              },
          },
        );
    setState(() {
      isCameraLoaded = true;
    });
  }

  _prepareForVideoRecording() async {
    await _cameraController.prepareForVideoRecording();
  }

  _stopVideoRecording() async {
    if (isRecording) {
      setState(() => isRecording = false);
      final videoFile = await _cameraController.stopVideoRecording();
      resetTimer();
      stopTimer();
    }
  }

  _recordVideo() {
    _cameraController.startVideoRecording();
    setState(() => isRecording = true);
    startTimer();
  }

  
  @override
  Widget build(BuildContext context) {
    final cameraPreviewKey = GlobalKey();
    return Scaffold(
      appBar: AppBar(/*AppBar code*/),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 0),
            child: (!isCameraLoaded)
                ? Container(
                    width: MediaQuery.of(context).size.width,
                    height: MediaQuery.of(context).size.width / 3 * 4,
                    child: Center(
                      child: const CircularProgressIndicator(),
                    ),
                  )
                : Row(
                    children: [
                      Expanded(
                        child: Container(
                          width: MediaQuery.of(context).size.width,
                          height: MediaQuery.of(context).size.width / 3 * 4,
                          child: CameraPreview(
                            _cameraController,
                            key: cameraPreviewKey,
                            child: Container(
                              child: Padding(
                                padding: EdgeInsets.all(Sizes.x8),
                                child: Container(
                                  width: MediaQuery.of(context).size.width,
                                  height:
                                      MediaQuery.of(context).size.width / 3 * 4,
                                  decoration: BoxDecoration(
                                    border: Border.all(
                                      width: borderWidth,
                                    ),
                                  ),
                                ),
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
          ),
          
          const Spacer(),
          SizedBox(
            height: Sizes.x16,
          ),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: Sizes.x16),
            child: Center(
              child: Column(
                children: [
                  isRecording
                      ? GestureDetector(
                          child: stopButtonWidget(context),
                          onTap: () {
                            _stopVideoRecording();
                          },
                        )
                      : GestureDetector(
                          child: playButtonWidget(context),
                          onTap: () {
                            _recordVideo();
                          },
                        ),
                  SizedBox(
                    height: Sizes.x16,
                  ),
                  isRecording
                      ? FittedBox(
                          fit: BoxFit.fitWidth,
                          child: Text(
                            l10n.vide_record_screen_end,
                          ),
                        )
                      : FittedBox(
                          fit: BoxFit.fitWidth,
                          child: Text(
                            l10n.vide_record_screen_start,
                            style: Theme.of(context).Style
                          ),
                        ),
                  SizedBox(
                    height: Sizes.x24,
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img