6

I'm using flutter video_player package to play a list of video.

List sourceList;

sourceList = [
  {
    "size": 69742504,
    "name": "lucky-roulette.mp4",
    "mimetype": "video/mp4",
  },
  {
    "size": 69742504,
    "name": "BigBuckBunny.mp4",
    "mimetype": "video/mp4",
  }
];

I've checked out this issue, and did some custom codes upon it.

void play() {
  log.fine("Now playing: $_nowPlayingUrl");
  _adController = VideoPlayerController.network(_nowPlayingUrl);
  _adController.initialize().then((_) => setState(() {}));
  _adController.play();
  _adController.addListener(checkIfVideoFinished);
}

void checkIfVideoFinished() {
  if (_adController == null ||
      _adController.value == null ||
      _adController.value.position == null ||
      _adController.value.duration == null) return;
  if (_adController.value.position.inSeconds ==
      _adController.value.duration.inSeconds) {
    _adController.removeListener(checkIfVideoFinished);
    _adController.dispose();
    // Change _nowPlayingIndex
    setState(() {
      _nowPlayingIndex = (_nowPlayingIndex + 1) % _totalIndex;
    });
    play();
  }
}

But use this code snippet would send out an exception Another exception was thrown: A VideoPlayerController was used after being disposed.

Is there a better way to play and loop a list of video in Flutter?

Bobson Lin
  • 65
  • 1
  • 2
  • 5
  • The Best Answer Should Be, which is not mine but used in 2 flutter projects and working well https://stackoverflow.com/a/58959097/10329023 Special thanks to @igor-kharakhordin Help Others and Happy Coding :) – Kamlesh Nov 08 '20 at 13:30

2 Answers2

7

Recently I tested video list example. please check the source in github FlutterVideoListSample. I think the video widget must be disposed.

In my case, I clear the old VideoPlayerController before initialize it. And I don't use chewie plugin that make new page in entering fullscreen so cannot handle the next video widget.

dependencies
video_player: '>=0.10.11+1 <2.0.0'
some code in FlutterVideoListSample
VideoPlayerController _controller;

void _initializeAndPlay(int index) async {
  print("_initializeAndPlay ---------> $index");
  final clip = _clips[index];
  final controller = VideoPlayerController.asset(clip.videoPath());
  final old = _controller;
  if (old != null) {
    old.removeListener(_onControllerUpdated);
    old.pause(); // mute instantly
  }
  _controller = controller;
  setState(() {
    debugPrint("---- controller changed");
  });

  controller
    ..initialize().then((_) {
      debugPrint("---- controller initialized");
      old?.dispose();
      _playingIndex = index;
      controller.addListener(_onControllerUpdated);
      controller.play();
      setState(() {});
    });
}
Brownsoo Han
  • 4,343
  • 3
  • 19
  • 20
  • How long does it take to initialize the video? I'm using 'videoPlayerController.value.initialized' to check if the video is initialized...sometimes it takes up to 10 seconds to initialize the video. – Soropromo Mar 07 '20 at 20:03
  • I took under 1 sec. I don't know why your video take long time to initialize. But,, I used 720x480 short videos under 4min. And that videos rendered with 1 second interval key frame. @Soropromo – Brownsoo Han Mar 08 '20 at 07:31
  • 1
    Hi @BrownsooHan. I copied and pasted your code and after 5 times playing videos, throw this **exception: com.google.android.exoplayer2.ExoPlaybackException: com.google.android.exoplayer2.audio.AudioSink$InitializationException: AudioTrack init failed: 0, Config(48000, 12, 49248)** I'm using a Pixel C – Sami Issa Apr 01 '20 at 17:03
  • Hi, @SamiIssa , I used this code only in iOS. try `_controller?.dispose();` in _clearPrevious(). I gonna try this in android. If I also encount or resolve the issue, updated this post. If you find a solution, please reply the resolution. – Brownsoo Han Apr 03 '20 at 03:01
  • @SamiIssa : I agree.. I am facing this problem with the app that has already been pushed to prod now. – rohan koshti Jul 03 '20 at 11:56
  • In my case, I have video controller in separate widget and list videos in separate widget. I want when user click a video from list of video, then previously playing video should stop and new video should play. How can I do this with provider or scoped model. – Wikki Sep 29 '20 at 21:40
  • I think you need to use some property tracking play status in app level. – Brownsoo Han Sep 30 '20 at 23:39
  • @SamiIssa I was facing same issue but the best solution is at https://stackoverflow.com/a/64738624/10329023 – Kamlesh Nov 08 '20 at 13:30
  • How to add Video Quality option (720p, 480p, etc.) like Youtube to this video_player to play m3u8 format videos ??? any one knows? – Gulshan Yadav Dec 09 '20 at 10:43
2

You must call the video controller dispose method in Override dispose method. Need not call dispose method when removevideo.

Akio Alex
  • 186
  • 8