sarbagyastha / youtube_player_flutter

A Flutter plugin for inline playback or streaming of YouTube videos using the official iFrame Player API.
https://youtube.sarbagyastha.com.np
BSD 3-Clause "New" or "Revised" License
709 stars 823 forks source link

[BUG] YouTubePlayerController emits two states PlayerState.ended #523

Open Beyga opened 3 years ago

Beyga commented 3 years ago

When the video ends the controller should emit PlayerState.ended value. Unfortunately, it emits it twice, not once. This is very problematic while performing actions with help of listeners.

I want to load nextTrack() on data change in the DB. When the data changes, the other listener invokes _controller.load('newVideoId') method.

late final YoutubePlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = YoutubePlayerController(
      initialVideoId: 'initialVideoId',
    );
    _controller.addListener(() {
      if (_controller.value.playerState == PlayerState.ended) {
        nextTrack();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return BlocListener<Cubit, State>(
      listener: (context, state) {
        final videoId = state.videoId;
        if (videoId != null) {
          _controller.load(videoId);
        }
      },
      child: ...

The nextTrack() method should be invoked once but it is not.

I handled this with throttler but it is not a very nice solution I think. Those two PlayerState.ended values are emitted in a very short period of time so this solution works.

class ThrottleFirst {
  final int milliseconds;
  Timer? _timer;

  ThrottleFirst({this.milliseconds = 1000});

  void run(VoidCallback action) {
    if (_timer != null) return;
    action();
    _timer = Timer(Duration(milliseconds: milliseconds), () {
      _timer = null;
    });
  }
}
ThrottleFirst throttler = ThrottleFirst();
 throttler.run(() => nextTrack());

Flutter doctor:

[✓] Flutter (Channel stable, 2.2.3, on macOS 11.2.3 20D91 darwin-x64, locale en-PL) • Flutter version 2.2.3 at /Users/konradbejger/Development/flutter • Framework revision f4abaa0735 (4 weeks ago), 2021-07-01 12:46:11 -0700 • Engine revision 241c87ad80 • Dart version 2.13.4

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3) • Android SDK at /Users/konradbejger/Library/Android/sdk • Platform android-30, build-tools 30.0.3 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264) • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 12.5.1, Build version 12E507 • CocoaPods version 1.10.1

[✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)

[✓] IntelliJ IDEA Community Edition (version 2020.3.2) • IntelliJ at /Applications/IntelliJ IDEA CE.app • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] VS Code (version 1.58.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.24.0

[✓] Connected device (2 available) • SM G975F (mobile) • R58M313QXFF • android-arm64 • Android 11 (API 30) • Chrome (web) • chrome • web-javascript • Google Chrome 91.0.4472.164

misrilibrary commented 5 days ago

I am using youtube_player_flutter: ^9.1.1 and still facing the same issue. Didnt try this workaround