From bc89dc420610b5c24047b262d11db2ae0d02f4ac Mon Sep 17 00:00:00 2001 From: Mario Graf Date: Mon, 2 Dec 2024 17:27:07 +0100 Subject: [PATCH 1/3] Support isPaused and isMuted API calls --- .../kotlin/com/bitmovin/player/flutter/FlutterPlayer.kt | 2 ++ .../src/main/kotlin/com/bitmovin/player/flutter/Methods.kt | 2 ++ example/lib/player_info.dart | 4 ++++ ios/Classes/FlutterPlayer.swift | 4 ++++ ios/Classes/Methods.swift | 2 ++ lib/src/api/player/player_api.dart | 7 +++++++ lib/src/methods.dart | 2 ++ lib/src/platform/player_platform_method_channel.dart | 6 ++++++ lib/src/platform/web/bitmovin_player_web_api.dart | 2 ++ lib/src/platform/web/player_platform_web.dart | 6 ++++++ lib/src/player.dart | 6 ++++++ 11 files changed, 43 insertions(+) diff --git a/android/src/main/kotlin/com/bitmovin/player/flutter/FlutterPlayer.kt b/android/src/main/kotlin/com/bitmovin/player/flutter/FlutterPlayer.kt index 8626e45f..f6d8773d 100644 --- a/android/src/main/kotlin/com/bitmovin/player/flutter/FlutterPlayer.kt +++ b/android/src/main/kotlin/com/bitmovin/player/flutter/FlutterPlayer.kt @@ -92,6 +92,8 @@ class FlutterPlayer( Methods.MAX_TIME_SHIFT -> maxTimeShift Methods.IS_LIVE -> isLive Methods.IS_PLAYING -> isPlaying + Methods.IS_PAUSED -> isPaused + Methods.IS_MUTED -> isMuted Methods.SEND_CUSTOM_DATA_EVENT -> this.analytics?.sendCustomDataEvent(arg.asCustomData.toNative()) ?: Unit diff --git a/android/src/main/kotlin/com/bitmovin/player/flutter/Methods.kt b/android/src/main/kotlin/com/bitmovin/player/flutter/Methods.kt index f62229cc..45f9f390 100644 --- a/android/src/main/kotlin/com/bitmovin/player/flutter/Methods.kt +++ b/android/src/main/kotlin/com/bitmovin/player/flutter/Methods.kt @@ -21,6 +21,8 @@ class Methods { const val MAX_TIME_SHIFT = "maxTimeShift" const val IS_LIVE = "isLive" const val IS_PLAYING = "isPlaying" + const val IS_PAUSED = "isPaused" + const val IS_MUTED = "isMuted" const val SEND_CUSTOM_DATA_EVENT = "sendCustomDataEvent" const val AVAILABLE_SUBTITLES = "availableSubtitles" const val SET_SUBTITLE = "setSubtitle" diff --git a/example/lib/player_info.dart b/example/lib/player_info.dart index be4220ac..c078eb17 100644 --- a/example/lib/player_info.dart +++ b/example/lib/player_info.dart @@ -41,6 +41,10 @@ class PlayerInfoState extends State { } if (event is PlayingEvent || event is PausedEvent) { _updatePlayerInfoForField('isPlaying', player.isPlaying); + _updatePlayerInfoForField('isPaused', player.isPaused); + } + if (event is MutedEvent || event is UnmutedEvent) { + _updatePlayerInfoForField('isMuted', player.isMuted); } if (event is TimeChangedEvent) { _updatePlayerInfoForField('currentTime', player.currentTime); diff --git a/ios/Classes/FlutterPlayer.swift b/ios/Classes/FlutterPlayer.swift index 09ca65a6..bebfa9d8 100644 --- a/ios/Classes/FlutterPlayer.swift +++ b/ios/Classes/FlutterPlayer.swift @@ -117,6 +117,10 @@ private extension FlutterPlayer { return player.isLive case (Methods.isPlaying, .empty): return player.isPlaying + case (Methods.isPaused, .empty): + return player.isPaused + case (Methods.isMuted, .empty): + return player.isMuted case (Methods.destroy, .empty): destroyPlayer() case (Methods.sendCustomDataEvent, .json(let customDataJson)): diff --git a/ios/Classes/Methods.swift b/ios/Classes/Methods.swift index 5d7b8fad..28d43393 100644 --- a/ios/Classes/Methods.swift +++ b/ios/Classes/Methods.swift @@ -18,6 +18,8 @@ internal enum Methods { static let maxTimeShift = "maxTimeShift" static let isLive = "isLive" static let isPlaying = "isPlaying" + static let isPaused = "isPaused" + static let isMuted = "isMuted" static let sendCustomDataEvent = "sendCustomDataEvent" static let availableSubtitles = "availableSubtitles" static let getSubtitle = "getSubtitle" diff --git a/lib/src/api/player/player_api.dart b/lib/src/api/player/player_api.dart index 02f9547f..12812310 100644 --- a/lib/src/api/player/player_api.dart +++ b/lib/src/api/player/player_api.dart @@ -65,6 +65,13 @@ abstract class PlayerApi { /// not paused. Future get isPlaying; + /// Whether the player is currently paused, i.e. has started playback but is + /// currently paused. + Future get isPaused; + + /// Whether the player is muted. + Future get isMuted; + /// A list of all available [SubtitleTrack]s of the active [Source], /// including "off" subtitle track. Future> get availableSubtitles; diff --git a/lib/src/methods.dart b/lib/src/methods.dart index c5b0be59..56157173 100644 --- a/lib/src/methods.dart +++ b/lib/src/methods.dart @@ -16,6 +16,8 @@ class Methods { static const String maxTimeShift = 'maxTimeShift'; static const String isLive = 'isLive'; static const String isPlaying = 'isPlaying'; + static const String isPaused = 'isPaused'; + static const String isMuted = 'isMuted'; static const String sendCustomDataEvent = 'sendCustomDataEvent'; static const String availableSubtitles = 'availableSubtitles'; static const String setSubtitle = 'setSubtitle'; diff --git a/lib/src/platform/player_platform_method_channel.dart b/lib/src/platform/player_platform_method_channel.dart index c08a01e6..ea6106bb 100644 --- a/lib/src/platform/player_platform_method_channel.dart +++ b/lib/src/platform/player_platform_method_channel.dart @@ -197,6 +197,12 @@ class PlayerPlatformMethodChannel extends PlayerPlatformInterface { @override Future get isPlaying async => _invokeMethod(Methods.isPlaying); + @override + Future get isPaused async => _invokeMethod(Methods.isPaused); + + @override + Future get isMuted async => _invokeMethod(Methods.isMuted); + @override Future loadSource(Source source) async { await super.loadSource(source); diff --git a/lib/src/platform/web/bitmovin_player_web_api.dart b/lib/src/platform/web/bitmovin_player_web_api.dart index f06018ec..f6215aa3 100644 --- a/lib/src/platform/web/bitmovin_player_web_api.dart +++ b/lib/src/platform/web/bitmovin_player_web_api.dart @@ -19,6 +19,8 @@ class BitmovinPlayerJs { external void castVideo(); external void castStop(); external bool isPlaying(); + external bool isPaused(); + external bool isMuted(); external bool isLive(); external bool isCasting(); external bool isCastAvailable(); diff --git a/lib/src/platform/web/player_platform_web.dart b/lib/src/platform/web/player_platform_web.dart index c3ed1056..da80ee95 100644 --- a/lib/src/platform/web/player_platform_web.dart +++ b/lib/src/platform/web/player_platform_web.dart @@ -75,6 +75,12 @@ class PlayerPlatformWeb extends PlayerPlatformInterface { @override Future get isPlaying async => _player.isPlaying(); + @override + Future get isPaused async => _player.isPaused(); + + @override + Future get isMuted async => _player.isMuted(); + @override Future loadSource(Source source) async { await super.loadSource(source); diff --git a/lib/src/player.dart b/lib/src/player.dart index 3e2b41f7..d21e1f65 100644 --- a/lib/src/player.dart +++ b/lib/src/player.dart @@ -81,6 +81,12 @@ class Player with PlayerEventHandler implements PlayerApi { @override Future get isPlaying async => _playerPlatformInterface.isPlaying; + @override + Future get isPaused async => _playerPlatformInterface.isPaused; + + @override + Future get isMuted async => _playerPlatformInterface.isMuted; + @override Future> get availableSubtitles async => _playerPlatformInterface.availableSubtitles; From 187405b73bc814308e2b9b7fbffd1168d748bf11 Mon Sep 17 00:00:00 2001 From: Mario Graf Date: Mon, 2 Dec 2024 17:29:57 +0100 Subject: [PATCH 2/3] Add CHANGELOG entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5107934f..e182fbf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/). +## [Unreleased] +- Support for `Player.isPaused` and `Player.isMuted` + ## [0.13.0] - 2024-11-26 - Introduce platform support for web. - Supported API calls: `loadSource(source)`, `play`, `pause`, `mute`, `unmute`, `seek(time)`, `timeShift(timeShift)`, `getCurrentTime`, `getTimeShift`, `getDuration`, `getMaxTimeShift`, `isLive`, `isPlaying`, `isAirplayActive`, `isAirplayAvailable`, `castVideo`, `castStop`, `isCastAvailable`, `isCasting`, `showAirPlayTargetPicker`, `destroy` From b0fad91a4c1f9cbd07489c414c2831a01dc0a13e Mon Sep 17 00:00:00 2001 From: Mario Graf Date: Mon, 2 Dec 2024 17:37:23 +0100 Subject: [PATCH 3/3] Display doubles with two decimals --- example/lib/player_info.dart | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/example/lib/player_info.dart b/example/lib/player_info.dart index c078eb17..edcb8b0c 100644 --- a/example/lib/player_info.dart +++ b/example/lib/player_info.dart @@ -12,7 +12,7 @@ class PlayerInfo extends StatefulWidget { } class PlayerInfoState extends State { - final Map _data = {}; + final Map _data = {}; Future updatePlayerInfo(Player player, Event event) async { if (event is ReadyEvent) { @@ -67,8 +67,13 @@ class PlayerInfoState extends State { void _updatePlayerInfoForField(String field, Future value) { value.then((dynamic value) { + var valueString = value.toString(); + if (value is double) { + valueString = value.toStringAsFixed(2); + } + setState(() { - _data[field] = value.toString(); + _data[field] = valueString; }); }); } @@ -79,7 +84,7 @@ class PlayerInfoState extends State { itemCount: _data.length, itemBuilder: (context, index) { final key = _data.keys.elementAt(index); - final value = _data[key]; + final value = _data[key]!; return Padding( padding: const EdgeInsets.symmetric(vertical: 1, horizontal: 1), @@ -91,7 +96,7 @@ class PlayerInfoState extends State { ), Expanded( flex: 3, - child: Text(value.toString()), + child: Text(value), ), ], ),