Repository: flutter
Issue: [camera_web] Disposing of CameraController while recording is paused or in progress throws Error
Labels: platform-web,p: camera,package,has reproducible steps,P2,team-web,triaged-web,found in release: 3.13,found in release: 3.15

### Is there an existing issue for this?

- [X] I have searched the [existing package issues](https://github.com/flutter/flutter/issues?q=is%3Aopen+is%3Aissue+label%3Apackage)
- [X] I have read the [guide to filing a bug](https://flutter.dev/docs/resources/bug-reports)

### What package does this bug report belong to?

camera

### What target platforms are you seeing this bug on?

Web

### Have you already upgraded your packages?

Yes

### Dependency versions

<details><summary>pubspec.lock</summary>

```lock
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
  _fe_analyzer_shared:
    dependency: transitive
    description:
      name: _fe_analyzer_shared
      sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
      url: "https://pub.dev"
    source: hosted
    version: "64.0.0"
  analyzer:
    dependency: transitive
    description:
      name: analyzer
      sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
      url: "https://pub.dev"
    source: hosted
    version: "6.2.0"
  args:
    dependency: transitive
    description:
      name: args
      sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
      url: "https://pub.dev"
    source: hosted
    version: "2.4.2"
  async:
    dependency: transitive
    description:
      name: async
      sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
      url: "https://pub.dev"
    source: hosted
    version: "2.11.0"
  boolean_selector:
    dependency: transitive
    description:
      name: boolean_selector
      sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.1"
  build:
    dependency: transitive
    description:
      name: build
      sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
      url: "https://pub.dev"
    source: hosted
    version: "2.4.1"
  build_config:
    dependency: transitive
    description:
      name: build_config
      sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
      url: "https://pub.dev"
    source: hosted
    version: "1.1.1"
  build_daemon:
    dependency: transitive
    description:
      name: build_daemon
      sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65"
      url: "https://pub.dev"
    source: hosted
    version: "4.0.0"
  build_resolvers:
    dependency: transitive
    description:
      name: build_resolvers
      sha256: d912852cce27c9e80a93603db721c267716894462e7033165178b91138587972
      url: "https://pub.dev"
    source: hosted
    version: "2.3.2"
  build_runner:
    dependency: "direct dev"
    description:
      name: build_runner
      sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b"
      url: "https://pub.dev"
    source: hosted
    version: "2.4.6"
  build_runner_core:
    dependency: transitive
    description:
      name: build_runner_core
      sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41"
      url: "https://pub.dev"
    source: hosted
    version: "7.2.10"
  built_collection:
    dependency: transitive
    description:
      name: built_collection
      sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
      url: "https://pub.dev"
    source: hosted
    version: "5.1.1"
  built_value:
    dependency: transitive
    description:
      name: built_value
      sha256: ff627b645b28fb8bdb69e645f910c2458fd6b65f6585c3a53e0626024897dedf
      url: "https://pub.dev"
    source: hosted
    version: "8.6.2"
  camera:
    dependency: "direct main"
    description:
      path: ".."
      relative: true
    source: path
    version: "0.10.5+4"
  camera_android:
    dependency: transitive
    description:
      name: camera_android
      sha256: ed4f645848074166fc3b8e20350f83ca07e09a2becc1e185040ee561f955d4df
      url: "https://pub.dev"
    source: hosted
    version: "0.10.8+8"
  camera_avfoundation:
    dependency: transitive
    description:
      name: camera_avfoundation
      sha256: "718b60ed2e22b4067fe6e2c0e9ebe2856c2de5c8b1289ba95d10db85b0b00bc2"
      url: "https://pub.dev"
    source: hosted
    version: "0.9.13+4"
  camera_platform_interface:
    dependency: transitive
    description:
      name: camera_platform_interface
      sha256: "8734d1c682f034bdb12d0d6ff379b0535a9b8e44266b530025bf8266d6a62f28"
      url: "https://pub.dev"
    source: hosted
    version: "2.5.2"
  camera_web:
    dependency: transitive
    description:
      name: camera_web
      sha256: d4c2c571c7af04f8b10702ca16bb9ed2a26e64534171e8f75c9349b2c004d8f1
      url: "https://pub.dev"
    source: hosted
    version: "0.3.2+3"
  characters:
    dependency: transitive
    description:
      name: characters
      sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
      url: "https://pub.dev"
    source: hosted
    version: "1.3.0"
  checked_yaml:
    dependency: transitive
    description:
      name: checked_yaml
      sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
      url: "https://pub.dev"
    source: hosted
    version: "2.0.3"
  clock:
    dependency: transitive
    description:
      name: clock
      sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
      url: "https://pub.dev"
    source: hosted
    version: "1.1.1"
  code_builder:
    dependency: transitive
    description:
      name: code_builder
      sha256: "315a598c7fbe77f22de1c9da7cfd6fd21816312f16ffa124453b4fc679e540f1"
      url: "https://pub.dev"
    source: hosted
    version: "4.6.0"
  collection:
    dependency: transitive
    description:
      name: collection
      sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
      url: "https://pub.dev"
    source: hosted
    version: "1.17.2"
  convert:
    dependency: transitive
    description:
      name: convert
      sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
      url: "https://pub.dev"
    source: hosted
    version: "3.1.1"
  cross_file:
    dependency: transitive
    description:
      name: cross_file
      sha256: fd832b5384d0d6da4f6df60b854d33accaaeb63aa9e10e736a87381f08dee2cb
      url: "https://pub.dev"
    source: hosted
    version: "0.3.3+5"
  crypto:
    dependency: transitive
    description:
      name: crypto
      sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
      url: "https://pub.dev"
    source: hosted
    version: "3.0.3"
  dart_style:
    dependency: transitive
    description:
      name: dart_style
      sha256: abd7625e16f51f554ea244d090292945ec4d4be7bfbaf2ec8cccea568919d334
      url: "https://pub.dev"
    source: hosted
    version: "2.3.3"
  fake_async:
    dependency: transitive
    description:
      name: fake_async
      sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
      url: "https://pub.dev"
    source: hosted
    version: "1.3.1"
  ffi:
    dependency: transitive
    description:
      name: ffi
      sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.0"
  file:
    dependency: transitive
    description:
      name: file
      sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
      url: "https://pub.dev"
    source: hosted
    version: "6.1.4"
  fixnum:
    dependency: transitive
    description:
      name: fixnum
      sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
      url: "https://pub.dev"
    source: hosted
    version: "1.1.0"
  flutter:
    dependency: "direct main"
    description: flutter
    source: sdk
    version: "0.0.0"
  flutter_driver:
    dependency: "direct dev"
    description: flutter
    source: sdk
    version: "0.0.0"
  flutter_plugin_android_lifecycle:
    dependency: transitive
    description:
      name: flutter_plugin_android_lifecycle
      sha256: f185ac890306b5779ecbd611f52502d8d4d63d27703ef73161ca0407e815f02c
      url: "https://pub.dev"
    source: hosted
    version: "2.0.16"
  flutter_test:
    dependency: "direct dev"
    description: flutter
    source: sdk
    version: "0.0.0"
  flutter_web_plugins:
    dependency: transitive
    description: flutter
    source: sdk
    version: "0.0.0"
  frontend_server_client:
    dependency: transitive
    description:
      name: frontend_server_client
      sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
      url: "https://pub.dev"
    source: hosted
    version: "3.2.0"
  fuchsia_remote_debug_protocol:
    dependency: transitive
    description: flutter
    source: sdk
    version: "0.0.0"
  glob:
    dependency: transitive
    description:
      name: glob
      sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.2"
  graphs:
    dependency: transitive
    description:
      name: graphs
      sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19
      url: "https://pub.dev"
    source: hosted
    version: "2.3.1"
  http_multi_server:
    dependency: transitive
    description:
      name: http_multi_server
      sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
      url: "https://pub.dev"
    source: hosted
    version: "3.2.1"
  http_parser:
    dependency: transitive
    description:
      name: http_parser
      sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
      url: "https://pub.dev"
    source: hosted
    version: "4.0.2"
  integration_test:
    dependency: "direct dev"
    description: flutter
    source: sdk
    version: "0.0.0"
  io:
    dependency: transitive
    description:
      name: io
      sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
      url: "https://pub.dev"
    source: hosted
    version: "1.0.4"
  js:
    dependency: transitive
    description:
      name: js
      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
      url: "https://pub.dev"
    source: hosted
    version: "0.6.7"
  json_annotation:
    dependency: transitive
    description:
      name: json_annotation
      sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
      url: "https://pub.dev"
    source: hosted
    version: "4.8.1"
  logging:
    dependency: transitive
    description:
      name: logging
      sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
      url: "https://pub.dev"
    source: hosted
    version: "1.2.0"
  matcher:
    dependency: transitive
    description:
      name: matcher
      sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
      url: "https://pub.dev"
    source: hosted
    version: "0.12.16"
  material_color_utilities:
    dependency: transitive
    description:
      name: material_color_utilities
      sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
      url: "https://pub.dev"
    source: hosted
    version: "0.5.0"
  meta:
    dependency: transitive
    description:
      name: meta
      sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
      url: "https://pub.dev"
    source: hosted
    version: "1.9.1"
  mime:
    dependency: transitive
    description:
      name: mime
      sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
      url: "https://pub.dev"
    source: hosted
    version: "1.0.4"
  package_config:
    dependency: transitive
    description:
      name: package_config
      sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.0"
  path:
    dependency: transitive
    description:
      name: path
      sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
      url: "https://pub.dev"
    source: hosted
    version: "1.8.3"
  path_provider:
    dependency: "direct main"
    description:
      name: path_provider
      sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
      url: "https://pub.dev"
    source: hosted
    version: "2.1.1"
  path_provider_android:
    dependency: transitive
    description:
      name: path_provider_android
      sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1"
      url: "https://pub.dev"
    source: hosted
    version: "2.2.0"
  path_provider_foundation:
    dependency: transitive
    description:
      name: path_provider_foundation
      sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
      url: "https://pub.dev"
    source: hosted
    version: "2.3.1"
  path_provider_linux:
    dependency: transitive
    description:
      name: path_provider_linux
      sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
      url: "https://pub.dev"
    source: hosted
    version: "2.2.1"
  path_provider_platform_interface:
    dependency: transitive
    description:
      name: path_provider_platform_interface
      sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.1"
  path_provider_windows:
    dependency: transitive
    description:
      name: path_provider_windows
      sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
      url: "https://pub.dev"
    source: hosted
    version: "2.2.1"
  platform:
    dependency: transitive
    description:
      name: platform
      sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
      url: "https://pub.dev"
    source: hosted
    version: "3.1.0"
  plugin_platform_interface:
    dependency: transitive
    description:
      name: plugin_platform_interface
      sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
      url: "https://pub.dev"
    source: hosted
    version: "2.1.6"
  pool:
    dependency: transitive
    description:
      name: pool
      sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
      url: "https://pub.dev"
    source: hosted
    version: "1.5.1"
  process:
    dependency: transitive
    description:
      name: process
      sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
      url: "https://pub.dev"
    source: hosted
    version: "4.2.4"
  pub_semver:
    dependency: transitive
    description:
      name: pub_semver
      sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.4"
  pubspec_parse:
    dependency: transitive
    description:
      name: pubspec_parse
      sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
      url: "https://pub.dev"
    source: hosted
    version: "1.2.3"
  quiver:
    dependency: transitive
    description:
      name: quiver
      sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47
      url: "https://pub.dev"
    source: hosted
    version: "3.2.1"
  shelf:
    dependency: transitive
    description:
      name: shelf
      sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
      url: "https://pub.dev"
    source: hosted
    version: "1.4.1"
  shelf_web_socket:
    dependency: transitive
    description:
      name: shelf_web_socket
      sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
      url: "https://pub.dev"
    source: hosted
    version: "1.0.4"
  sky_engine:
    dependency: transitive
    description: flutter
    source: sdk
    version: "0.0.99"
  source_span:
    dependency: transitive
    description:
      name: source_span
      sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
      url: "https://pub.dev"
    source: hosted
    version: "1.10.0"
  stack_trace:
    dependency: transitive
    description:
      name: stack_trace
      sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
      url: "https://pub.dev"
    source: hosted
    version: "1.11.0"
  stream_channel:
    dependency: transitive
    description:
      name: stream_channel
      sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.1"
  stream_transform:
    dependency: transitive
    description:
      name: stream_transform
      sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.0"
  string_scanner:
    dependency: transitive
    description:
      name: string_scanner
      sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
      url: "https://pub.dev"
    source: hosted
    version: "1.2.0"
  sync_http:
    dependency: transitive
    description:
      name: sync_http
      sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
      url: "https://pub.dev"
    source: hosted
    version: "0.3.1"
  term_glyph:
    dependency: transitive
    description:
      name: term_glyph
      sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
      url: "https://pub.dev"
    source: hosted
    version: "1.2.1"
  test_api:
    dependency: transitive
    description:
      name: test_api
      sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
      url: "https://pub.dev"
    source: hosted
    version: "0.6.0"
  timing:
    dependency: transitive
    description:
      name: timing
      sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
      url: "https://pub.dev"
    source: hosted
    version: "1.0.1"
  typed_data:
    dependency: transitive
    description:
      name: typed_data
      sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
      url: "https://pub.dev"
    source: hosted
    version: "1.3.2"
  vector_math:
    dependency: transitive
    description:
      name: vector_math
      sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
      url: "https://pub.dev"
    source: hosted
    version: "2.1.4"
  vm_service:
    dependency: transitive
    description:
      name: vm_service
      sha256: c620a6f783fa22436da68e42db7ebbf18b8c44b9a46ab911f666ff09ffd9153f
      url: "https://pub.dev"
    source: hosted
    version: "11.7.1"
  watcher:
    dependency: transitive
    description:
      name: watcher
      sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
      url: "https://pub.dev"
    source: hosted
    version: "1.1.0"
  web:
    dependency: transitive
    description:
      name: web
      sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
      url: "https://pub.dev"
    source: hosted
    version: "0.1.4-beta"
  web_socket_channel:
    dependency: transitive
    description:
      name: web_socket_channel
      sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
      url: "https://pub.dev"
    source: hosted
    version: "2.4.0"
  webdriver:
    dependency: transitive
    description:
      name: webdriver
      sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49"
      url: "https://pub.dev"
    source: hosted
    version: "3.0.2"
  win32:
    dependency: transitive
    description:
      name: win32
      sha256: "9e82a402b7f3d518fb9c02d0e9ae45952df31b9bf34d77baf19da2de03fc2aaa"
      url: "https://pub.dev"
    source: hosted
    version: "5.0.7"
  xdg_directories:
    dependency: transitive
    description:
      name: xdg_directories
      sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
      url: "https://pub.dev"
    source: hosted
    version: "1.0.3"
  yaml:
    dependency: transitive
    description:
      name: yaml
      sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
      url: "https://pub.dev"
    source: hosted
    version: "3.1.2"
sdks:
  dart: ">=3.1.0 <4.0.0"
  flutter: ">=3.13.0"

```

</details>


### Steps to reproduce

1. Tap on the `Open Camera` button
2. Start recording
3. [Optional] Pause the recording
4. Hit `cancel` (which pops the navigator)

### Expected results

CameraController disposes safely

### Actual results

CameraController throws an error

### Code sample

<details><summary>Code sample</summary>

Note: to reproduct you can also just wrap the official example in a navigated-to scaffold to (and make sure to call `_cameraController.dispose` in the `dispose` method.  But the official example is complex, and was throwing other errors in my logs.

```dart
// ignore_for_file: public_member_api_docs, use_key_in_widget_constructors

import 'dart:async';

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  try {
    WidgetsFlutterBinding.ensureInitialized();
  } on CameraException catch (e) {
    print('${e.code}, ${e.description}');
  }

  runApp(const CameraApp());
}

class CameraApp extends StatelessWidget {
  const CameraApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Builder(builder: (innerContext) {
            return TextButton(
              onPressed: () async {
                final XFile? file =
                    await Navigator.of(innerContext).push<XFile?>(
                  MaterialPageRoute<XFile?>(
                    builder: (_) => CameraRecorderWeb(),
                  ),
                );

                print('$file');
              },
              child: const Text('Open Camera'),
            );
          }),
        ),
      ),
    );
  }
}

enum RecordingMedium { audio, image, video }

class CameraRecorderWeb extends StatefulWidget {
  const CameraRecorderWeb();

  @override
  State<CameraRecorderWeb> createState() => _CameraRecorderWebState();
}

enum RecorderState { loading, ready }

class _CameraRecorderWebState extends State<CameraRecorderWeb> {
  late CameraController _controller;
  late final List<CameraDescription> _cameras;

  bool _initializedAtLeastOnce = false;

  RecorderState _cameraSelectorState = RecorderState.loading;
  RecorderState _previewState = RecorderState.loading;

  @override
  void initState() {
    super.initState();

    _init();
  }

  Future<void> _init() async {
    _cameras = await availableCameras();

    await _initController(_cameras.first);

    setState(() {
      _cameraSelectorState = RecorderState.ready;
    });
  }

  Future<void> _initController(CameraDescription cd) async {
    if (_initializedAtLeastOnce) {
      await _controller.dispose();
    }

    setState(() {
      _previewState = RecorderState.loading;
    });

    _controller = CameraController(cd, ResolutionPreset.max);

    try {
      await _controller.initialize();
      _initializedAtLeastOnce = true;

      if (!mounted) {
        return;
      }

      _controller.addListener(() => setState(() {}));

      setState(() {
        _previewState = RecorderState.ready;
      });
    } catch (e) {
      if (e is CameraException) {
        print(e);
        // Handle access errors here.
      }
    }
  }

  @override
  void dispose() {
    debugPrint('disposing of camera controller');

    _controller.dispose();
    super.dispose();
  }

  Future<void> setCamera(CameraDescription cd) async {
    if (cd == _controller.description) {
      return;
    }

    await _initController(cd);
  }

  List<DropdownMenuEntry<CameraDescription>> buildMenuItems() {
    return _cameras
        .map((cd) =>
            DropdownMenuEntry<CameraDescription>(value: cd, label: cd.name))
        .toList();
  }

  void _start() {
    _controller.startVideoRecording();
  }

  void _pause() {
    _controller.pauseVideoRecording();
  }

  void _resume() {
    _controller.resumeVideoRecording();
  }

  void _cancel() {
    Navigator.of(context).pop();
  }

  Future<void> _save() async {
    final XFile file = await _controller.stopVideoRecording();

    if (mounted) {
      Navigator.of(context).pop(file);
    }
  }

  @override
  Widget build(BuildContext context) {
    if (_cameraSelectorState == RecorderState.loading) {
      return const Scaffold(body: Center(child: CircularProgressIndicator()));
    }

    return Scaffold(
      body: Row(
        children: [
          Flexible(
            child: Center(
              child: Container(
                constraints: const BoxConstraints(maxWidth: 600),
                child: Column(
                  children: [
                    const SizedBox(height: 24),
                    Row(
                      children: [
                        DropdownMenu<CameraDescription>(
                          initialSelection: _controller.description,
                          dropdownMenuEntries: [
                            ...buildMenuItems(),
                          ],
                          onSelected: (cd) => setCamera(cd ?? _cameras.first),
                        ),
                      ],
                    ),
                    const SizedBox(height: 24),
                    Expanded(
                      child: Stack(
                        children: [
                          Center(
                            child: _previewState == RecorderState.loading
                                ? const CircularProgressIndicator()
                                : CameraPreview(_controller),
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(height: 24),
                    RecordingControls(
                      recording: _controller.value.isRecordingVideo,
                      paused: _controller.value.isRecordingPaused,
                      onSave: _save,
                      onCancel: _cancel,
                      onStart: _start,
                      onPause: _pause,
                      onResume: _resume,
                    ),
                    const SizedBox(height: 24),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class RecordingControls extends StatelessWidget {
  const RecordingControls({
    super.key,
    required this.recording,
    required this.paused,
    required this.onSave,
    required this.onCancel,
    required this.onStart,
    required this.onPause,
    required this.onResume,
  });
  final bool recording;
  final bool paused;

  final void Function() onSave;
  final void Function() onCancel;
  final void Function() onStart;
  final void Function() onPause;
  final void Function() onResume;

  Widget _padTextButton(Widget text) {
    return Padding(padding: const EdgeInsets.all(16), child: text);
  }

  @override
  Widget build(BuildContext context) {
    final TextStyle? cancelSaveStyle = Theme.of(context).textTheme.bodyLarge;

    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: [
        Expanded(
          child: Center(
            child: TextButton(
              onPressed: onCancel,
              child: _padTextButton(Text('Cancel', style: cancelSaveStyle)),
            ),
          ),
        ),
        if (recording)
          paused
              ? TextButton(
                  onPressed: onResume,
                  child: const Text('Resume'),
                )
              : IconButton(
                  color: Colors.red.shade400,
                  onPressed: () {},
                  icon: const Icon(Icons.pause),
                ),
        if (!recording)
          IconButton(
            icon: const Icon(Icons.videocam),
            onPressed: onStart,
          ),
        Expanded(
          child: Center(
            child: recording
                ? TextButton(
                    onPressed: onSave,
                    child: _padTextButton(Text('Save', style: cancelSaveStyle)),
                  )
                : const SizedBox(),
          ),
        ),
      ],
    );
  }
}

```

</details>


### Screenshots or Videos

_No response_

### Logs

<details><summary>Logs</summary>

```console
Uncaught (in promise) Error: Bad state: Cannot add new events after calling close
    at Object.throw_ [as throw] (errors.dart:294:49)
    at _AsyncBroadcastStreamController.new.add (broadcast_stream_controller.dart:243:46)
    at camera.Camera.new._onVideoRecordingStopped (camera.dart:520:31)
    at _onVideoRecordingStopped.next (<anonymous>)
    at runBody (async_patch.dart:84:54)
    at Object._async [as async] (async_patch.dart:127:5)
    at [_onVideoRecordingStopped] (camera.dart:503:40)
    at MediaRecorder.<anonymous> (camera.dart:459:31)
```
</details>


### Flutter Doctor output

<details><summary>Doctor output</summary>

```console
[✓] Flutter (Channel stable, 3.13.4, on macOS 12.6.6 21G646 darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0-rc1)
[✓] Xcode - develop for iOS and macOS (Xcode 14.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.3)
[✓] VS Code (version 1.82.0)
[✓] Connected device (2 available)
[✓] Network resources
```

</details>