jhomlala / betterplayer

Better video player for Flutter, with multiple configuration options. Solving typical use cases!
Apache License 2.0
917 stars 972 forks source link

[BUG] BetterPlayerController not posting BetterPlayerEventType.pipStart event on iOS #1168

Open ChopinDavid opened 1 year ago

ChopinDavid commented 1 year ago

History check Please confirm that you've checked issues history and you didn't find anything which may solve your issue.

Describe the bug Whenever the user enters pip (picture-in-picture) mode, we are wanting to post a BetterPlayerEventType.pipStart BetterPlayerEvent to BetterPlayerController's _eventListeners. This is only being posted on Android, not iOS.

To Reproduce Steps to reproduce the behavior:

  1. Add print statements in a BetterPlayerController listener, so that we can see which BetterPlayerEvent.betterPlayerEventType is being posted.
  2. Go into a video on a pip-enabled iOS device and app.
  3. Enter pip mode.
  4. Exit pip mode.
  5. See that only BetterPlayerEventType.pipStop BetterPlayerEvents are ever being posted to the listener.

Example code

import 'package:better_player/better_player.dart';
import 'package:flutter/material.dart';

class ExampleWidget extends StatefulWidget {
  const ExampleWidget({
    Key? key,
  }) : super(key: key);

  @override
  State<ExampleWidget> createState() => _ExampleWidgetState();
}

class _ExampleWidgetState extends State<ExampleWidget>
    with WidgetsBindingObserver {
  BetterPlayerController? _controller;
  GlobalKey _betterPlayerKey = GlobalKey();

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

    WidgetsBinding.instance.addObserver(this);
    _controller = BetterPlayerController(const BetterPlayerConfiguration(),
        betterPlayerDataSource: BetterPlayerDataSource.file(
          '/assets/someVideo.mp4',
        ));
    _betterPlayerKey = GlobalKey();
    _controller?.setBetterPlayerGlobalKey(_betterPlayerKey);

    _controller?.addEventsListener(listener);

  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    _controller?.removeEventsListener(listener);
    super.dispose();
  }

  Future<void> listener(BetterPlayerEvent event) async {
    if (event.betterPlayerEventType == BetterPlayerEventType.pipStart) {
      print('pipStart');
    }
    if (event.betterPlayerEventType == BetterPlayerEventType.pipStop) {
      print('pipStop');
    }
  }

  @override
  Widget build(BuildContext context) {
    return BetterPlayer(
      controller: _controller,
      key: _betterPlayerKey,
    );
  }
}

Expected behavior Both "pipStart" and "pipStop" would be logged when entering and exiting pip mode.

Screenshots N/a

Flutter doctor [✓] Flutter (Channel stable, 3.0.4, on macOS 12.6.1 21G217 darwin-arm, locale en-US) [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) [✓] Xcode - develop for iOS and macOS (Xcode 14.1) [✓] Chrome - develop for the web [✓] Android Studio (version 2021.2) [✓] VS Code (version 1.70.0) [✓] Connected device (3 available) [✓] HTTP Host Availability

• No issues found!

Better Player version

Smartphone (please complete the following information):

Additional context My team was wanting to log analytics anytime a user enters/exits pip mode, and this was a blocker to us completing this task.

ChopinDavid commented 1 year ago

The fix for this issue can be found in this PR. I am willing to reproduce this PR on @jhomlala's repo so long as it will be merged into main.