From e9d2669a5a8ad5ce500972811b4251f38b482a16 Mon Sep 17 00:00:00 2001 From: alr2413 Date: Thu, 25 Mar 2021 23:50:10 +0430 Subject: [PATCH 01/10] updated vlc event handling code --- .../example/lib/controls_overlay.dart | 2 +- .../example/lib/single_tab.dart | 8 ++- .../lib/src/vlc_player_controller.dart | 60 ++++++++++--------- flutter_vlc_player/pubspec.yaml | 4 +- 4 files changed, 40 insertions(+), 34 deletions(-) diff --git a/flutter_vlc_player/example/lib/controls_overlay.dart b/flutter_vlc_player/example/lib/controls_overlay.dart index d48bb9f2..9cfdeaf7 100644 --- a/flutter_vlc_player/example/lib/controls_overlay.dart +++ b/flutter_vlc_player/example/lib/controls_overlay.dart @@ -22,7 +22,7 @@ class ControlsOverlay extends StatelessWidget { reverseDuration: Duration(milliseconds: 200), child: Builder( builder: (ctx) { - if (controller.value.isEnded) { + if (controller.value.isEnded || controller.value.hasError) { return Center( child: FittedBox( child: IconButton( diff --git a/flutter_vlc_player/example/lib/single_tab.dart b/flutter_vlc_player/example/lib/single_tab.dart index a3097b41..a2201cd3 100644 --- a/flutter_vlc_player/example/lib/single_tab.dart +++ b/flutter_vlc_player/example/lib/single_tab.dart @@ -38,7 +38,7 @@ class _SingleTabState extends State { listVideos.add(VideoData( name: 'Network Video 1', path: - 'http://samples.mplayerhq.hu/MPEG-4/embedded_subs/1Video_2Audio_2SUBs_timed_text_streams_.mp4', + 'http://samples.mplayerhq.hu/MPEG-4/embedded_subs/1Video_2Audio_2SUBs_timed_text_streams_.mp42', type: VideoType.network, )); // @@ -186,8 +186,10 @@ class _SingleTabState extends State { onTap: () async { switch (video.type) { case VideoType.network: - await _controller.setMediaFromNetwork(video.path, - hwAcc: HwAcc.FULL); + await _controller.setMediaFromNetwork( + video.path, + hwAcc: HwAcc.FULL, + ); break; case VideoType.file: ScaffoldMessenger.of(context).showSnackBar( diff --git a/flutter_vlc_player/lib/src/vlc_player_controller.dart b/flutter_vlc_player/lib/src/vlc_player_controller.dart index c5fbebad..52a70bf5 100644 --- a/flutter_vlc_player/lib/src/vlc_player_controller.dart +++ b/flutter_vlc_player/lib/src/vlc_player_controller.dart @@ -35,11 +35,9 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - VoidCallback? onInit, - RendererCallback? onRendererHandler, + this.onInit, + this.onRendererHandler, }) : _dataSourceType = DataSourceType.asset, - _onInit = onInit, - _onRendererHandler = onRendererHandler, super(VlcPlayerValue(duration: Duration.zero)); /// Constructs a [VlcPlayerController] playing a video from obtained from @@ -53,12 +51,10 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - VoidCallback? onInit, - RendererCallback? onRendererHandler, + this.onInit, + this.onRendererHandler, }) : package = null, _dataSourceType = DataSourceType.network, - _onInit = onInit, - _onRendererHandler = onRendererHandler, super(VlcPlayerValue(duration: Duration.zero)); /// Constructs a [VlcPlayerController] playing a video from a file. @@ -71,13 +67,11 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - VoidCallback? onInit, - RendererCallback? onRendererHandler, + this.onInit, + this.onRendererHandler, }) : dataSource = 'file://${file.path}', package = null, _dataSourceType = DataSourceType.file, - _onInit = onInit, - _onRendererHandler = onRendererHandler, super(VlcPlayerValue(duration: Duration.zero)); /// The URI to the video file. This will be in different formats depending on @@ -120,11 +114,11 @@ class VlcPlayerController extends ValueNotifier { /// This is a callback that will be executed once the platform view has been initialized. /// If you want the media to play as soon as the platform view has initialized, you could just call /// [VlcPlayerController.play] in this callback. (see the example) - final _onInit; + VoidCallback? onInit; /// This is a callback that will be executed every time a new renderer cast device attached/detached /// It should be defined as "void Function(VlcRendererEventType, String, String)", where the VlcRendererEventType is an enum { attached, detached } and the next two String arguments are unique-id and name of renderer device, respectively. - final _onRendererHandler; + RendererCallback? onRendererHandler; bool _isDisposed = false; @@ -168,6 +162,7 @@ class VlcPlayerController extends ValueNotifier { isBuffering: true, isEnded: false, playingState: PlayingState.buffering, + errorDescription: null, ); break; @@ -201,6 +196,7 @@ class VlcPlayerController extends ValueNotifier { activeAudioTrack: event.activeAudioTrack, spuTracksCount: event.spuTracksCount, activeSpuTrack: event.activeSpuTrack, + errorDescription: null, ); break; @@ -218,6 +214,7 @@ class VlcPlayerController extends ValueNotifier { case VlcMediaEventType.timeChanged: value = value.copyWith( isEnded: false, + isBuffering: (event.mediaEventType == VlcMediaEventType.buffering), position: event.position, duration: event.duration, playbackSpeed: event.playbackSpeed, @@ -231,6 +228,7 @@ class VlcPlayerController extends ValueNotifier { playingState: (event.isPlaying ?? false) ? PlayingState.playing : value.playingState, + errorDescription: null, ); break; @@ -239,11 +237,11 @@ class VlcPlayerController extends ValueNotifier { case VlcMediaEventType.error: value = value.copyWith( - isPlaying: false, - isBuffering: false, - isEnded: false, - playingState: PlayingState.error, - ); + isPlaying: false, + isBuffering: false, + isEnded: false, + playingState: PlayingState.error, + errorDescription: 'VLC encountered an error!'); break; case VlcMediaEventType.unknown: @@ -270,15 +268,15 @@ class VlcPlayerController extends ValueNotifier { } switch (event.eventType) { case VlcRendererEventType.attached: - if (_onRendererHandler != null) { - _onRendererHandler(VlcRendererEventType.attached, event.rendererId, - event.rendererName); + if (onRendererHandler != null) { + onRendererHandler!(VlcRendererEventType.attached, event.rendererId!, + event.rendererName!); } break; case VlcRendererEventType.detached: - if (_onRendererHandler != null) { - _onRendererHandler(VlcRendererEventType.detached, event.rendererId, - event.rendererName); + if (onRendererHandler != null) { + onRendererHandler!(VlcRendererEventType.detached, event.rendererId!, + event.rendererName!); } break; case VlcRendererEventType.unknown: @@ -297,7 +295,7 @@ class VlcPlayerController extends ValueNotifier { playingState: PlayingState.initialized, ); - if (_onInit != null) _onInit(); + if (onInit != null) onInit!(); return initializingCompleter.future; } @@ -799,18 +797,24 @@ class VlcPlayerController extends ValueNotifier { return await vlcPlayerPlatform.takeSnapshot(_viewId); } + /// Get list of available renderer services which is supported by vlc library + Future> getAvailableRendererServices() async { + _throwIfNotInitialized('getAvailableRendererServices'); + return await vlcPlayerPlatform.getAvailableRendererServices(_viewId); + } + /// Start vlc cast discovery to find external display devices (chromecast) /// By setting serviceName, the vlc discovers renderer with that service Future startRendererScanning({String? rendererService}) async { _throwIfNotInitialized('startRendererScanning'); - return await vlcPlayerPlatform.startRendererScanning(viewId!, + return await vlcPlayerPlatform.startRendererScanning(_viewId, rendererService: rendererService ?? ''); } /// Stop vlc cast and scan Future stopRendererScanning() async { _throwIfNotInitialized('stopRendererScanning'); - return await vlcPlayerPlatform.stopRendererScanning(viewId!); + return await vlcPlayerPlatform.stopRendererScanning(_viewId); } /// Returns all detected renderer devices as array of diff --git a/flutter_vlc_player/pubspec.yaml b/flutter_vlc_player/pubspec.yaml index a153b7a7..85bd2941 100644 --- a/flutter_vlc_player/pubspec.yaml +++ b/flutter_vlc_player/pubspec.yaml @@ -29,7 +29,7 @@ dev_dependencies: sdk: flutter pigeon: git: - url: https://github.com/Goddchen/packages.git + url: https://github.com/gaaclarke/packages.git path: packages/pigeon - ref: pigeon-null-safety + ref: pigeon-2-0-0 plugin_platform_interface: ^2.0.0 From 9df3744d6e9aa03ecae841b9142daa0a2ea979ed Mon Sep 17 00:00:00 2001 From: alr2413 Date: Fri, 26 Mar 2021 00:41:02 +0430 Subject: [PATCH 02/10] fix vlc error description --- flutter_vlc_player/example/lib/single_tab.dart | 2 +- .../lib/src/vlc_player_controller.dart | 17 +++++++++-------- .../lib/src/vlc_player_value.dart | 13 ++++++++----- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/flutter_vlc_player/example/lib/single_tab.dart b/flutter_vlc_player/example/lib/single_tab.dart index a2201cd3..17a1b96c 100644 --- a/flutter_vlc_player/example/lib/single_tab.dart +++ b/flutter_vlc_player/example/lib/single_tab.dart @@ -38,7 +38,7 @@ class _SingleTabState extends State { listVideos.add(VideoData( name: 'Network Video 1', path: - 'http://samples.mplayerhq.hu/MPEG-4/embedded_subs/1Video_2Audio_2SUBs_timed_text_streams_.mp42', + 'http://samples.mplayerhq.hu/MPEG-4/embedded_subs/1Video_2Audio_2SUBs_timed_text_streams_.mp4', type: VideoType.network, )); // diff --git a/flutter_vlc_player/lib/src/vlc_player_controller.dart b/flutter_vlc_player/lib/src/vlc_player_controller.dart index 52a70bf5..a84b6ae9 100644 --- a/flutter_vlc_player/lib/src/vlc_player_controller.dart +++ b/flutter_vlc_player/lib/src/vlc_player_controller.dart @@ -162,7 +162,7 @@ class VlcPlayerController extends ValueNotifier { isBuffering: true, isEnded: false, playingState: PlayingState.buffering, - errorDescription: null, + errorDescription: VlcPlayerValue.emptyString, ); break; @@ -196,7 +196,7 @@ class VlcPlayerController extends ValueNotifier { activeAudioTrack: event.activeAudioTrack, spuTracksCount: event.spuTracksCount, activeSpuTrack: event.activeSpuTrack, - errorDescription: null, + errorDescription: VlcPlayerValue.emptyString, ); break; @@ -228,7 +228,7 @@ class VlcPlayerController extends ValueNotifier { playingState: (event.isPlaying ?? false) ? PlayingState.playing : value.playingState, - errorDescription: null, + errorDescription: VlcPlayerValue.emptyString, ); break; @@ -237,11 +237,12 @@ class VlcPlayerController extends ValueNotifier { case VlcMediaEventType.error: value = value.copyWith( - isPlaying: false, - isBuffering: false, - isEnded: false, - playingState: PlayingState.error, - errorDescription: 'VLC encountered an error!'); + isPlaying: false, + isBuffering: false, + isEnded: false, + playingState: PlayingState.error, + errorDescription: 'VLC encountered an error!', + ); break; case VlcMediaEventType.unknown: diff --git a/flutter_vlc_player/lib/src/vlc_player_value.dart b/flutter_vlc_player/lib/src/vlc_player_value.dart index a91a3a72..5f2d77af 100644 --- a/flutter_vlc_player/lib/src/vlc_player_value.dart +++ b/flutter_vlc_player/lib/src/vlc_player_value.dart @@ -7,6 +7,9 @@ import 'enums/playing_state.dart'; /// The duration, current position, buffering state, error state and settings /// of a [VlcPlayerController]. class VlcPlayerValue { + /// Define Empty String + static const String emptyString = ''; + /// Constructs a video with the given values. Only [duration] is required. The /// rest will initialize with default values when unset. VlcPlayerValue({ @@ -31,7 +34,7 @@ class VlcPlayerValue { this.spuDelay = 0, this.videoTracksCount = 1, this.activeVideoTrack = 0, - this.errorDescription, + this.errorDescription = VlcPlayerValue.emptyString, }); /// Returns an instance with a `null` [Duration]. @@ -49,7 +52,7 @@ class VlcPlayerValue { duration: Duration.zero, playingState: PlayingState.error, isInitialized: false, - errorDescription: errorDescription, + errorDescription: errorDescription ?? VlcPlayerValue.emptyString, ); } @@ -114,8 +117,8 @@ class VlcPlayerValue { /// A description of the error if present. /// - /// If [hasError] is false this is [null]. - final String? errorDescription; + /// If [hasError] is false this is [empty]. + final String errorDescription; /// The [size] of the currently loaded video. /// @@ -127,7 +130,7 @@ class VlcPlayerValue { /// Indicates whether or not the video is in an error state. If this is true /// [errorDescription] should have information about the problem. - bool get hasError => errorDescription != null; + bool get hasError => errorDescription.isNotEmpty; /// Returns [size.width] / [size.height] when the player is initialized, or `1.0.` when /// the player is not initialized or the aspect ratio would be less than or equal to 0.0. From 768f7ea9f9ac6662412bd4f4facd1236fb78ca55 Mon Sep 17 00:00:00 2001 From: alr2413 Date: Fri, 26 Mar 2021 13:37:22 +0430 Subject: [PATCH 03/10] renamed error const strings --- flutter_vlc_player/lib/src/vlc_player_controller.dart | 8 ++++---- flutter_vlc_player/lib/src/vlc_player_value.dart | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/flutter_vlc_player/lib/src/vlc_player_controller.dart b/flutter_vlc_player/lib/src/vlc_player_controller.dart index a84b6ae9..84ca2ad1 100644 --- a/flutter_vlc_player/lib/src/vlc_player_controller.dart +++ b/flutter_vlc_player/lib/src/vlc_player_controller.dart @@ -162,7 +162,7 @@ class VlcPlayerController extends ValueNotifier { isBuffering: true, isEnded: false, playingState: PlayingState.buffering, - errorDescription: VlcPlayerValue.emptyString, + errorDescription: VlcPlayerValue.noError, ); break; @@ -196,7 +196,7 @@ class VlcPlayerController extends ValueNotifier { activeAudioTrack: event.activeAudioTrack, spuTracksCount: event.spuTracksCount, activeSpuTrack: event.activeSpuTrack, - errorDescription: VlcPlayerValue.emptyString, + errorDescription: VlcPlayerValue.noError, ); break; @@ -228,7 +228,7 @@ class VlcPlayerController extends ValueNotifier { playingState: (event.isPlaying ?? false) ? PlayingState.playing : value.playingState, - errorDescription: VlcPlayerValue.emptyString, + errorDescription: VlcPlayerValue.noError, ); break; @@ -241,7 +241,7 @@ class VlcPlayerController extends ValueNotifier { isBuffering: false, isEnded: false, playingState: PlayingState.error, - errorDescription: 'VLC encountered an error!', + errorDescription: VlcPlayerValue.unknownError, ); break; diff --git a/flutter_vlc_player/lib/src/vlc_player_value.dart b/flutter_vlc_player/lib/src/vlc_player_value.dart index 5f2d77af..f89a0fa7 100644 --- a/flutter_vlc_player/lib/src/vlc_player_value.dart +++ b/flutter_vlc_player/lib/src/vlc_player_value.dart @@ -7,8 +7,9 @@ import 'enums/playing_state.dart'; /// The duration, current position, buffering state, error state and settings /// of a [VlcPlayerController]. class VlcPlayerValue { - /// Define Empty String - static const String emptyString = ''; + /// Define no error string + static const String noError = ''; + static const String unknownError = 'An Unknown Error Occurred!'; /// Constructs a video with the given values. Only [duration] is required. The /// rest will initialize with default values when unset. @@ -34,7 +35,7 @@ class VlcPlayerValue { this.spuDelay = 0, this.videoTracksCount = 1, this.activeVideoTrack = 0, - this.errorDescription = VlcPlayerValue.emptyString, + this.errorDescription = VlcPlayerValue.noError, }); /// Returns an instance with a `null` [Duration]. @@ -52,7 +53,7 @@ class VlcPlayerValue { duration: Duration.zero, playingState: PlayingState.error, isInitialized: false, - errorDescription: errorDescription ?? VlcPlayerValue.emptyString, + errorDescription: errorDescription ?? VlcPlayerValue.unknownError, ); } From 9958ce0d2a39abc22236cec892b7ac19410b8fe0 Mon Sep 17 00:00:00 2001 From: alr2413 Date: Fri, 26 Mar 2021 13:40:49 +0430 Subject: [PATCH 04/10] fixed a minor bug --- flutter_vlc_player/lib/src/vlc_player_value.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter_vlc_player/lib/src/vlc_player_value.dart b/flutter_vlc_player/lib/src/vlc_player_value.dart index f89a0fa7..afd1a23b 100644 --- a/flutter_vlc_player/lib/src/vlc_player_value.dart +++ b/flutter_vlc_player/lib/src/vlc_player_value.dart @@ -131,7 +131,7 @@ class VlcPlayerValue { /// Indicates whether or not the video is in an error state. If this is true /// [errorDescription] should have information about the problem. - bool get hasError => errorDescription.isNotEmpty; + bool get hasError => errorDescription != VlcPlayerValue.noError; /// Returns [size.width] / [size.height] when the player is initialized, or `1.0.` when /// the player is not initialized or the aspect ratio would be less than or equal to 0.0. From d8799496ad7577a7876ff11ef160e2016291e9ce Mon Sep 17 00:00:00 2001 From: Guillermo Jeremy De La Cruz Onton Date: Mon, 29 Mar 2021 03:16:58 -0500 Subject: [PATCH 05/10] Avoid FlutterVlcPlayerFactory new instances onAttachedToActivity (#214) * Avoid FlutterVlcPlayerFactory new instances onAttachedToActivity * Avoid FlutterVlcPlayerFactory instances in registerWith --- .../FlutterVlcPlayerPlugin.java | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayerPlugin.java b/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayerPlugin.java index 2cc001a9..e2f7e944 100644 --- a/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayerPlugin.java +++ b/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayerPlugin.java @@ -22,19 +22,21 @@ public FlutterVlcPlayerPlugin() { @SuppressWarnings("deprecation") public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { - flutterVlcPlayerFactory = - new FlutterVlcPlayerFactory( - registrar.messenger(), - registrar.textures(), - registrar::lookupKeyForAsset, - registrar::lookupKeyForAsset - ); - registrar - .platformViewRegistry() - .registerViewFactory( - VIEW_TYPE, - flutterVlcPlayerFactory - ); + if (flutterVlcPlayerFactory == null) { + flutterVlcPlayerFactory = + new FlutterVlcPlayerFactory( + registrar.messenger(), + registrar.textures(), + registrar::lookupKeyForAsset, + registrar::lookupKeyForAsset + ); + registrar + .platformViewRegistry() + .registerViewFactory( + VIEW_TYPE, + flutterVlcPlayerFactory + ); + } registrar.addViewDestroyListener(view -> { stopListening(); return false; @@ -56,22 +58,24 @@ public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { @RequiresApi(api = Build.VERSION_CODES.N) @Override public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { - final FlutterInjector injector = FlutterInjector.instance(); - // - flutterVlcPlayerFactory = - new FlutterVlcPlayerFactory( - flutterPluginBinding.getBinaryMessenger(), - flutterPluginBinding.getTextureRegistry(), - injector.flutterLoader()::getLookupKeyForAsset, - injector.flutterLoader()::getLookupKeyForAsset - ); - flutterPluginBinding - .getPlatformViewRegistry() - .registerViewFactory( - VIEW_TYPE, - flutterVlcPlayerFactory - ); - // + if (flutterVlcPlayerFactory == null) { + final FlutterInjector injector = FlutterInjector.instance(); + // + flutterVlcPlayerFactory = + new FlutterVlcPlayerFactory( + flutterPluginBinding.getBinaryMessenger(), + flutterPluginBinding.getTextureRegistry(), + injector.flutterLoader()::getLookupKeyForAsset, + injector.flutterLoader()::getLookupKeyForAsset + ); + flutterPluginBinding + .getPlatformViewRegistry() + .registerViewFactory( + VIEW_TYPE, + flutterVlcPlayerFactory + ); + // + } startListening(); } From 3bb853c7aac810074c3c07e86369d8fb22fc6d26 Mon Sep 17 00:00:00 2001 From: alr2413 Date: Mon, 29 Mar 2021 23:38:00 +0430 Subject: [PATCH 06/10] fix error description docs --- flutter_vlc_player/lib/src/vlc_player_controller.dart | 2 +- flutter_vlc_player/lib/src/vlc_player_value.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter_vlc_player/lib/src/vlc_player_controller.dart b/flutter_vlc_player/lib/src/vlc_player_controller.dart index 84ca2ad1..df43fa6d 100644 --- a/flutter_vlc_player/lib/src/vlc_player_controller.dart +++ b/flutter_vlc_player/lib/src/vlc_player_controller.dart @@ -214,7 +214,7 @@ class VlcPlayerController extends ValueNotifier { case VlcMediaEventType.timeChanged: value = value.copyWith( isEnded: false, - isBuffering: (event.mediaEventType == VlcMediaEventType.buffering), + isBuffering: event.mediaEventType == VlcMediaEventType.buffering, position: event.position, duration: event.duration, playbackSpeed: event.playbackSpeed, diff --git a/flutter_vlc_player/lib/src/vlc_player_value.dart b/flutter_vlc_player/lib/src/vlc_player_value.dart index afd1a23b..0d1fab21 100644 --- a/flutter_vlc_player/lib/src/vlc_player_value.dart +++ b/flutter_vlc_player/lib/src/vlc_player_value.dart @@ -118,7 +118,7 @@ class VlcPlayerValue { /// A description of the error if present. /// - /// If [hasError] is false this is [empty]. + /// If [hasError] is false this is [VlcPlayerValue.noError]. final String errorDescription; /// The [size] of the currently loaded video. From b904bd9ed465b6f10b1edd1e17d386ab84db1f1f Mon Sep 17 00:00:00 2001 From: alr2413 Date: Tue, 30 Mar 2021 23:50:46 +0430 Subject: [PATCH 07/10] Added onInit & onRenderer listeners --- flutter_vlc_player/CHANGELOG.md | 5 + .../lib/src/vlc_player_controller.dart | 95 ++++++++++++++----- flutter_vlc_player/pubspec.yaml | 2 +- 3 files changed, 78 insertions(+), 24 deletions(-) diff --git a/flutter_vlc_player/CHANGELOG.md b/flutter_vlc_player/CHANGELOG.md index eb2efcad..a5bfe450 100644 --- a/flutter_vlc_player/CHANGELOG.md +++ b/flutter_vlc_player/CHANGELOG.md @@ -1,3 +1,8 @@ +## 6.0.2 +* Fix issue with vlc error event +* Added onInit & onRenderer listeners +Credits to Alireza Setayesh (https://github.com/alr2413) and solid-vovabeloded (https://github.com/solid-vovabeloded). + ## 6.0.1 * Fix issue with black screen / offstage Credits to Mitch Ross (https://github.com/mitchross) diff --git a/flutter_vlc_player/lib/src/vlc_player_controller.dart b/flutter_vlc_player/lib/src/vlc_player_controller.dart index df43fa6d..a2d21ed5 100644 --- a/flutter_vlc_player/lib/src/vlc_player_controller.dart +++ b/flutter_vlc_player/lib/src/vlc_player_controller.dart @@ -35,9 +35,11 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - this.onInit, - this.onRendererHandler, + VoidCallback? onInit, + RendererCallback? onRendererHandler, }) : _dataSourceType = DataSourceType.asset, + _onInit = onInit, + _onRendererHandler = onRendererHandler, super(VlcPlayerValue(duration: Duration.zero)); /// Constructs a [VlcPlayerController] playing a video from obtained from @@ -51,10 +53,12 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - this.onInit, - this.onRendererHandler, + VoidCallback? onInit, + RendererCallback? onRendererHandler, }) : package = null, _dataSourceType = DataSourceType.network, + _onInit = onInit, + _onRendererHandler = onRendererHandler, super(VlcPlayerValue(duration: Duration.zero)); /// Constructs a [VlcPlayerController] playing a video from a file. @@ -67,11 +71,13 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - this.onInit, - this.onRendererHandler, + VoidCallback? onInit, + RendererCallback? onRendererHandler, }) : dataSource = 'file://${file.path}', package = null, _dataSourceType = DataSourceType.file, + _onInit = onInit, + _onRendererHandler = onRendererHandler, super(VlcPlayerValue(duration: Duration.zero)); /// The URI to the video file. This will be in different formats depending on @@ -91,6 +97,15 @@ class VlcPlayerController extends ValueNotifier { /// Initialize vlc player when the platform is ready automatically final bool autoInitialize; + /// This is a callback that will be executed once the platform view has been initialized. + /// If you want the media to play as soon as the platform view has initialized, you could just call + /// [VlcPlayerController.play] in this callback. (see the example) + final VoidCallback? _onInit; + + /// This is a callback that will be executed every time a new renderer cast device attached/detached + /// It should be defined as "void Function(VlcRendererEventType, String, String)", where the VlcRendererEventType is an enum { attached, detached } and the next two String arguments are unique-id and name of renderer device, respectively. + final RendererCallback? _onRendererHandler; + /// Only set for [asset] videos. The package that the asset was loaded from. String? package; @@ -111,14 +126,31 @@ class VlcPlayerController extends ValueNotifier { /// The viewId for this controller late int _viewId; - /// This is a callback that will be executed once the platform view has been initialized. - /// If you want the media to play as soon as the platform view has initialized, you could just call - /// [VlcPlayerController.play] in this callback. (see the example) - VoidCallback? onInit; + /// List of onInit listeners + final List _onInitListeners = []; - /// This is a callback that will be executed every time a new renderer cast device attached/detached - /// It should be defined as "void Function(VlcRendererEventType, String, String)", where the VlcRendererEventType is an enum { attached, detached } and the next two String arguments are unique-id and name of renderer device, respectively. - RendererCallback? onRendererHandler; + /// add a listener to be notified on controller initialization + void addOnInitListener(VoidCallback listener) { + _onInitListeners.add(listener); + } + + /// remove an onInit attached listener + void removeOnInitListener(VoidCallback listener) { + _onInitListeners.remove(listener); + } + + /// List of onRenderer listeners + final List _onRendererListeners = []; + + /// add a listener to be notified when a cast renderer device gets attached/detached + void addOnRendererListener(RendererCallback listener) { + _onRendererListeners.add(listener); + } + + /// remove a renderer attached listener + void removeOnRendererListener(RendererCallback listener) { + _onRendererListeners.remove(listener); + } bool _isDisposed = false; @@ -269,16 +301,12 @@ class VlcPlayerController extends ValueNotifier { } switch (event.eventType) { case VlcRendererEventType.attached: - if (onRendererHandler != null) { - onRendererHandler!(VlcRendererEventType.attached, event.rendererId!, - event.rendererName!); - } - break; case VlcRendererEventType.detached: - if (onRendererHandler != null) { - onRendererHandler!(VlcRendererEventType.detached, event.rendererId!, - event.rendererName!); - } + _notifyOnRendererListeners( + event.eventType, + event.rendererId, + event.rendererName, + ); break; case VlcRendererEventType.unknown: break; @@ -296,11 +324,12 @@ class VlcPlayerController extends ValueNotifier { playingState: PlayingState.initialized, ); - if (onInit != null) onInit!(); + _notifyOnInitListeners(); return initializingCompleter.future; } + /// Dispose controller @override Future dispose() async { if (_isDisposed) { @@ -314,6 +343,26 @@ class VlcPlayerController extends ValueNotifier { await vlcPlayerPlatform.dispose(_viewId); } + /// notify onInit callback & all registered listeners + void _notifyOnInitListeners() { + if (_onInit != null) { + _onInit!(); + } + _onInitListeners.forEach((listener) => listener()); + } + + /// notify onRendererHandler callback & all registered listeners + void _notifyOnRendererListeners( + VlcRendererEventType type, + String? id, + String? name, + ) { + if (_onRendererHandler != null) { + _onRendererHandler!(type, id!, name!); + } + _onRendererListeners.forEach((listener) => listener(type, id!, name!)); + } + /// This stops playback and changes the data source. Once the new data source has been loaded, the playback state will revert to /// its state before the method was called. (i.e. if this method is called whilst media is playing, once the new /// data source has been loaded, the new stream will begin playing.) diff --git a/flutter_vlc_player/pubspec.yaml b/flutter_vlc_player/pubspec.yaml index 85bd2941..457bae09 100644 --- a/flutter_vlc_player/pubspec.yaml +++ b/flutter_vlc_player/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_vlc_player description: A VLC-powered alternative to Flutter's video_player. Supports multiple players on one screen. -version: 6.0.1 +version: 6.0.2 homepage: https://github.com/solid-software/flutter_vlc_player/ environment: From 0805cfb47788641484fcd06baf15103730b0e12d Mon Sep 17 00:00:00 2001 From: alr2413 Date: Thu, 1 Apr 2021 10:43:52 +0430 Subject: [PATCH 08/10] updated docs mark onInit & onRendererHandler as deprecated. --- .../example/lib/multiple_tab.dart | 1 - .../example/lib/single_tab.dart | 24 +++------ .../lib/src/vlc_player_controller.dart | 53 ++++++++++--------- 3 files changed, 34 insertions(+), 44 deletions(-) diff --git a/flutter_vlc_player/example/lib/multiple_tab.dart b/flutter_vlc_player/example/lib/multiple_tab.dart index 3f32cb2f..a82ccb87 100644 --- a/flutter_vlc_player/example/lib/multiple_tab.dart +++ b/flutter_vlc_player/example/lib/multiple_tab.dart @@ -28,7 +28,6 @@ class _MultipleTabState extends State { urls[i], hwAcc: HwAcc.FULL, autoPlay: false, - onInit: () async {}, options: VlcPlayerOptions( advanced: VlcAdvancedOptions([ VlcAdvancedOptions.networkCaching(2000), diff --git a/flutter_vlc_player/example/lib/single_tab.dart b/flutter_vlc_player/example/lib/single_tab.dart index 17a1b96c..657c3e99 100644 --- a/flutter_vlc_player/example/lib/single_tab.dart +++ b/flutter_vlc_player/example/lib/single_tab.dart @@ -82,12 +82,6 @@ class _SingleTabState extends State { _controller = VlcPlayerController.network( initVideo.path, hwAcc: HwAcc.FULL, - onInit: () async { - await _controller.startRendererScanning(); - }, - onRendererHandler: (type, id, name) { - print('onRendererHandler $type $id $name'); - }, options: VlcPlayerOptions( advanced: VlcAdvancedOptions([ VlcAdvancedOptions.networkCaching(2000), @@ -110,27 +104,21 @@ class _SingleTabState extends State { var file = File(initVideo.path); _controller = VlcPlayerController.file( file, - onInit: () async { - await _controller.startRendererScanning(); - }, - onRendererHandler: (type, id, name) { - print('onRendererHandler $type $id $name'); - }, ); break; case VideoType.asset: _controller = VlcPlayerController.asset( initVideo.path, - onInit: () async { - await _controller.startRendererScanning(); - }, - onRendererHandler: (type, id, name) { - print('onRendererHandler $type $id $name'); - }, options: VlcPlayerOptions(), ); break; } + _controller.addOnInitListener(() async { + await _controller.startRendererScanning(); + }); + _controller.addOnRendererEventListener((type, id, name) { + print('OnRendererEventListener $type $id $name'); + }); } @override diff --git a/flutter_vlc_player/lib/src/vlc_player_controller.dart b/flutter_vlc_player/lib/src/vlc_player_controller.dart index a2d21ed5..8f9c55d1 100644 --- a/flutter_vlc_player/lib/src/vlc_player_controller.dart +++ b/flutter_vlc_player/lib/src/vlc_player_controller.dart @@ -35,8 +35,8 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - VoidCallback? onInit, - RendererCallback? onRendererHandler, + @deprecated VoidCallback? onInit, + @deprecated RendererCallback? onRendererHandler, }) : _dataSourceType = DataSourceType.asset, _onInit = onInit, _onRendererHandler = onRendererHandler, @@ -53,8 +53,8 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - VoidCallback? onInit, - RendererCallback? onRendererHandler, + @deprecated VoidCallback? onInit, + @deprecated RendererCallback? onRendererHandler, }) : package = null, _dataSourceType = DataSourceType.network, _onInit = onInit, @@ -71,8 +71,8 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - VoidCallback? onInit, - RendererCallback? onRendererHandler, + @deprecated VoidCallback? onInit, + @deprecated RendererCallback? onRendererHandler, }) : dataSource = 'file://${file.path}', package = null, _dataSourceType = DataSourceType.file, @@ -97,11 +97,13 @@ class VlcPlayerController extends ValueNotifier { /// Initialize vlc player when the platform is ready automatically final bool autoInitialize; + /// This parameter is deprecated, please, use the [addOnInitListener] method instead. /// This is a callback that will be executed once the platform view has been initialized. /// If you want the media to play as soon as the platform view has initialized, you could just call /// [VlcPlayerController.play] in this callback. (see the example) final VoidCallback? _onInit; + /// This parameter is deprecated, please, use the [addOnRendererEventListener] method instead. /// This is a callback that will be executed every time a new renderer cast device attached/detached /// It should be defined as "void Function(VlcRendererEventType, String, String)", where the VlcRendererEventType is an enum { attached, detached } and the next two String arguments are unique-id and name of renderer device, respectively. final RendererCallback? _onRendererHandler; @@ -129,33 +131,33 @@ class VlcPlayerController extends ValueNotifier { /// List of onInit listeners final List _onInitListeners = []; - /// add a listener to be notified on controller initialization + /// List of onRenderer listeners + final List _onRendererEventListeners = []; + + bool _isDisposed = false; + + VlcAppLifeCycleObserver? _lifeCycleObserver; + + /// Register a [VoidCallback] closure to be called when the controller gets initialized void addOnInitListener(VoidCallback listener) { _onInitListeners.add(listener); } - /// remove an onInit attached listener + /// Remove a previously registered closure from the list of onInit closures void removeOnInitListener(VoidCallback listener) { _onInitListeners.remove(listener); } - /// List of onRenderer listeners - final List _onRendererListeners = []; - - /// add a listener to be notified when a cast renderer device gets attached/detached - void addOnRendererListener(RendererCallback listener) { - _onRendererListeners.add(listener); + /// Register a [RendererCallback] closure to be called when a cast renderer device gets attached/detached + void addOnRendererEventListener(RendererCallback listener) { + _onRendererEventListeners.add(listener); } - /// remove a renderer attached listener - void removeOnRendererListener(RendererCallback listener) { - _onRendererListeners.remove(listener); + /// Remove a previously registered closure from the list of OnRendererEvent closures + void removeOnRendererEventListener(RendererCallback listener) { + _onRendererEventListeners.remove(listener); } - bool _isDisposed = false; - - VlcAppLifeCycleObserver? _lifeCycleObserver; - /// Attempts to open the given [url] and load metadata about the video. Future initialize() async { if (_isDisposed) { @@ -335,15 +337,16 @@ class VlcPlayerController extends ValueNotifier { if (_isDisposed) { return; } + _onInitListeners.clear(); + _onRendererEventListeners.clear(); _lifeCycleObserver?.dispose(); _isDisposed = true; super.dispose(); // - await vlcPlayerPlatform.dispose(_viewId); } - /// notify onInit callback & all registered listeners + /// Notify onInit callback & all registered listeners void _notifyOnInitListeners() { if (_onInit != null) { _onInit!(); @@ -351,7 +354,7 @@ class VlcPlayerController extends ValueNotifier { _onInitListeners.forEach((listener) => listener()); } - /// notify onRendererHandler callback & all registered listeners + /// Notify onRendererHandler callback & all registered listeners void _notifyOnRendererListeners( VlcRendererEventType type, String? id, @@ -360,7 +363,7 @@ class VlcPlayerController extends ValueNotifier { if (_onRendererHandler != null) { _onRendererHandler!(type, id!, name!); } - _onRendererListeners.forEach((listener) => listener(type, id!, name!)); + _onRendererEventListeners.forEach((listener) => listener(type, id!, name!)); } /// This stops playback and changes the data source. Once the new data source has been loaded, the playback state will revert to From 69edd263297c89095210f9a5e326c15a0b178b3b Mon Sep 17 00:00:00 2001 From: alr2413 Date: Tue, 6 Apr 2021 00:23:26 +0430 Subject: [PATCH 09/10] updated documentation --- .../lib/src/vlc_player_controller.dart | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/flutter_vlc_player/lib/src/vlc_player_controller.dart b/flutter_vlc_player/lib/src/vlc_player_controller.dart index 8f9c55d1..58bcd82a 100644 --- a/flutter_vlc_player/lib/src/vlc_player_controller.dart +++ b/flutter_vlc_player/lib/src/vlc_player_controller.dart @@ -35,8 +35,10 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - @deprecated VoidCallback? onInit, - @deprecated RendererCallback? onRendererHandler, + @Deprecated('Please, use the addOnInitListener method instead.') + VoidCallback? onInit, + @Deprecated('Please, use the addOnRendererEventListener method instead.') + RendererCallback? onRendererHandler, }) : _dataSourceType = DataSourceType.asset, _onInit = onInit, _onRendererHandler = onRendererHandler, @@ -53,8 +55,10 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - @deprecated VoidCallback? onInit, - @deprecated RendererCallback? onRendererHandler, + @Deprecated('Please, use the addOnInitListener method instead.') + VoidCallback? onInit, + @Deprecated('Please, use the addOnRendererEventListener method instead.') + RendererCallback? onRendererHandler, }) : package = null, _dataSourceType = DataSourceType.network, _onInit = onInit, @@ -71,8 +75,10 @@ class VlcPlayerController extends ValueNotifier { this.hwAcc = HwAcc.AUTO, this.autoPlay = true, this.options, - @deprecated VoidCallback? onInit, - @deprecated RendererCallback? onRendererHandler, + @Deprecated('Please, use the addOnInitListener method instead.') + VoidCallback? onInit, + @Deprecated('Please, use the addOnRendererEventListener method instead.') + RendererCallback? onRendererHandler, }) : dataSource = 'file://${file.path}', package = null, _dataSourceType = DataSourceType.file, @@ -97,15 +103,17 @@ class VlcPlayerController extends ValueNotifier { /// Initialize vlc player when the platform is ready automatically final bool autoInitialize; - /// This parameter is deprecated, please, use the [addOnInitListener] method instead. /// This is a callback that will be executed once the platform view has been initialized. /// If you want the media to play as soon as the platform view has initialized, you could just call - /// [VlcPlayerController.play] in this callback. (see the example) + /// [VlcPlayerController.play] in this callback. (see the example). + /// + /// This member is deprecated, please, use the [addOnInitListener] method instead. final VoidCallback? _onInit; - /// This parameter is deprecated, please, use the [addOnRendererEventListener] method instead. /// This is a callback that will be executed every time a new renderer cast device attached/detached /// It should be defined as "void Function(VlcRendererEventType, String, String)", where the VlcRendererEventType is an enum { attached, detached } and the next two String arguments are unique-id and name of renderer device, respectively. + /// + /// This member is deprecated, please, use the [addOnRendererEventListener] method instead. final RendererCallback? _onRendererHandler; /// Only set for [asset] videos. The package that the asset was loaded from. From 9ba4c986baece924421c9604053d7164d1a613c7 Mon Sep 17 00:00:00 2001 From: alr2413 Date: Tue, 6 Apr 2021 21:57:30 +0430 Subject: [PATCH 10/10] fix initialization value of renderer variables --- .../software/solid/fluttervlcplayer/FlutterVlcPlayer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayer.java b/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayer.java index 52bbe1d2..1d314d9f 100644 --- a/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayer.java +++ b/flutter_vlc_player/android/src/main/java/software/solid/fluttervlcplayer/FlutterVlcPlayer.java @@ -50,8 +50,8 @@ final class FlutterVlcPlayer implements PlatformView { // private LibVLC libVLC; private MediaPlayer mediaPlayer; - private List rendererDiscoverers; - private List rendererItems; + private List rendererDiscoverers = new ArrayList<>();; + private List rendererItems = new ArrayList<>();; private boolean isDisposed = false; // Platform view