diff --git a/analysis_options.yaml b/analysis_options.yaml index 18aea978..13024eef 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -4,7 +4,6 @@ analyzer: missing_required_param: error prefer_const_declarations: warning prefer_const_constructors: warning - import_of_legacy_library_into_null_safe: warning public_member_api_docs: ignore language: strict-casts: true diff --git a/lib/pod_player.dart b/lib/pod_player.dart index e7a0d631..1420b406 100644 --- a/lib/pod_player.dart +++ b/lib/pod_player.dart @@ -12,4 +12,5 @@ export 'src/models/pod_progress_bar_config.dart'; export 'src/models/vimeo_models.dart'; export 'src/pod_player.dart'; export 'src/utils/enums.dart'; +export 'src/utils/video_apis.dart'; export 'src/widgets/pod_progress_bar.dart'; diff --git a/lib/src/controllers/pod_getx_video_controller.dart b/lib/src/controllers/pod_getx_video_controller.dart index 7a46d30d..168effa3 100644 --- a/lib/src/controllers/pod_getx_video_controller.dart +++ b/lib/src/controllers/pod_getx_video_controller.dart @@ -10,7 +10,6 @@ import 'package:wakelock_plus/wakelock_plus.dart'; import '../../pod_player.dart'; import '../utils/logger.dart'; -import '../utils/video_apis.dart'; part 'pod_base_controller.dart'; part 'pod_gestures_controller.dart'; @@ -93,7 +92,6 @@ class PodGetXVideoController extends _PodGesturesController { httpHeaders: playVideoFrom.httpHeaders, ); playingVideoUrl = playVideoFrom.dataSource; - break; case PodVideoPlayerType.networkQualityUrls: final url = await getUrlFromVideoQualityUrls( qualityList: podPlayerConfig.videoQualityPriority, @@ -110,7 +108,6 @@ class PodGetXVideoController extends _PodGesturesController { ); playingVideoUrl = url; - break; case PodVideoPlayerType.youtube: final urls = await getVideoQualityUrlsFromYoutube( playVideoFrom.dataSource!, @@ -131,7 +128,6 @@ class PodGetXVideoController extends _PodGesturesController { ); playingVideoUrl = url; - break; case PodVideoPlayerType.vimeo: await getQualityUrlsFromVimeoId( playVideoFrom.dataSource!, @@ -151,7 +147,6 @@ class PodGetXVideoController extends _PodGesturesController { ); playingVideoUrl = url; - break; case PodVideoPlayerType.asset: /// @@ -163,7 +158,6 @@ class PodGetXVideoController extends _PodGesturesController { ); playingVideoUrl = playVideoFrom.dataSource; - break; case PodVideoPlayerType.file: if (kIsWeb) { throw Exception('file doesnt support web'); @@ -176,7 +170,6 @@ class PodGetXVideoController extends _PodGesturesController { videoPlayerOptions: playVideoFrom.videoPlayerOptions, ); - break; case PodVideoPlayerType.vimeoPrivateVideos: await getQualityUrlsFromVimeoPrivateId( playVideoFrom.dataSource!, @@ -195,49 +188,49 @@ class PodGetXVideoController extends _PodGesturesController { httpHeaders: playVideoFrom.httpHeaders, ); playingVideoUrl = url; - - break; } } ///Listning on keyboard events void onKeyBoardEvents({ - required RawKeyEvent event, + required KeyEvent event, required BuildContext appContext, required String tag, }) { - if (kIsWeb) { - if (event.isKeyPressed(LogicalKeyboardKey.space)) { - togglePlayPauseVideo(); - return; - } - if (event.isKeyPressed(LogicalKeyboardKey.keyM)) { - toggleMute(); - return; - } - if (event.isKeyPressed(LogicalKeyboardKey.arrowLeft)) { - onLeftDoubleTap(); - return; - } - if (event.isKeyPressed(LogicalKeyboardKey.arrowRight)) { - onRightDoubleTap(); - return; - } - if (event.isKeyPressed(LogicalKeyboardKey.keyF) && - event.logicalKey.keyLabel == 'F') { - toggleFullScreenOnWeb(appContext, tag); - } - if (event.isKeyPressed(LogicalKeyboardKey.escape)) { - if (isFullScreen) { - uni_html.document.exitFullscreen(); - if (!isWebPopupOverlayOpen) { - disableFullScreen(appContext, tag); - } - } - } + if (!kIsWeb) return; + + if (event is! KeyDownEvent) { + return; + } + if (event.logicalKey == LogicalKeyboardKey.space) { + togglePlayPauseVideo(); return; } + if (event.logicalKey == LogicalKeyboardKey.keyM) { + toggleMute(); + return; + } + if (event.logicalKey == LogicalKeyboardKey.arrowLeft) { + onLeftDoubleTap(); + return; + } + if (event.logicalKey == LogicalKeyboardKey.arrowRight) { + onRightDoubleTap(); + return; + } + if (event.logicalKey == LogicalKeyboardKey.keyF && + event.logicalKey.keyLabel == 'F') { + toggleFullScreenOnWeb(appContext, tag); + } + if (event.logicalKey == LogicalKeyboardKey.escape) { + if (isFullScreen) { + uni_html.document.exitFullscreen(); + if (!isWebPopupOverlayOpen) { + disableFullScreen(appContext, tag); + } + } + } } void toggleFullScreenOnWeb(BuildContext context, String tag) { @@ -259,18 +252,14 @@ class PodGetXVideoController extends _PodGesturesController { case PodVideoState.playing: if (podPlayerConfig.wakelockEnabled) WakelockPlus.enable(); playVideo(true); - break; case PodVideoState.paused: if (podPlayerConfig.wakelockEnabled) WakelockPlus.disable(); playVideo(false); - break; case PodVideoState.loading: isShowOverlay(true); - break; case PodVideoState.error: if (podPlayerConfig.wakelockEnabled) WakelockPlus.disable(); playVideo(false); - break; } } diff --git a/lib/src/controllers/pod_player_controller.dart b/lib/src/controllers/pod_player_controller.dart index 229ce884..be99918c 100644 --- a/lib/src/controllers/pod_player_controller.dart +++ b/lib/src/controllers/pod_player_controller.dart @@ -7,7 +7,6 @@ import 'package:wakelock_plus/wakelock_plus.dart'; import '../../pod_player.dart'; import '../utils/logger.dart'; -import '../utils/video_apis.dart'; import 'pod_getx_video_controller.dart'; class PodPlayerController { diff --git a/lib/src/controllers/pod_url_cache_singleton.dart b/lib/src/controllers/pod_url_cache_singleton.dart new file mode 100644 index 00000000..b21446bc --- /dev/null +++ b/lib/src/controllers/pod_url_cache_singleton.dart @@ -0,0 +1,25 @@ +import '../../pod_player.dart'; + +class PodUrlCacheSingleton { + static final PodUrlCacheSingleton _singleton = + PodUrlCacheSingleton._internal(); + + factory PodUrlCacheSingleton() { + return _singleton; + } + + PodUrlCacheSingleton._internal(); + + final Map> _podPreFetchMap = {}; + + /// Add a list of urls to the pre-fetch list. + void addUrls(String key, List urls) { + _podPreFetchMap[key] = urls; + } + + /// Get the list of urls from the pre-fetch list. + List getUrls(String key) { + final urls = _podPreFetchMap[key] ?? []; + return urls; + } +} diff --git a/lib/src/controllers/pod_video_controller.dart b/lib/src/controllers/pod_video_controller.dart index 0a0d4ea6..b4763b17 100644 --- a/lib/src/controllers/pod_video_controller.dart +++ b/lib/src/controllers/pod_video_controller.dart @@ -206,7 +206,7 @@ class _PodVideoController extends _PodUiController { SystemUiMode.manual, overlays: SystemUiOverlay.values, ), - ] + ], ]); } diff --git a/lib/src/utils/video_apis.dart b/lib/src/utils/video_apis.dart index 69153a19..1edbec5e 100644 --- a/lib/src/utils/video_apis.dart +++ b/lib/src/utils/video_apis.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:http/http.dart'; import 'package:youtube_explode_dart/youtube_explode_dart.dart'; +import '../controllers/pod_url_cache_singleton.dart'; import '../models/vimeo_models.dart'; String podErrorString(String val) { @@ -28,6 +29,12 @@ class VideoApis { String videoId, String? hash, ) async { + final podCache = PodUrlCacheSingleton(); + final cachedUrls = podCache.getUrls(videoId); + if (cachedUrls.isNotEmpty) { + return cachedUrls; + } + try { final response = await _makeRequestHash(videoId, hash); final jsonData = jsonDecode(response.body)['request']['files']; @@ -66,6 +73,8 @@ class VideoApis { ); } + podCache.addUrls(videoId, vimeoQualityUrls); + return vimeoQualityUrls; } catch (error) { if (error.toString().contains('XMLHttpRequest')) { @@ -84,6 +93,12 @@ class VideoApis { String videoId, Map httpHeader, ) async { + final podCache = PodUrlCacheSingleton(); + final cachedUrls = podCache.getUrls(videoId); + if (cachedUrls.isNotEmpty) { + return cachedUrls; + } + try { final response = await http.get( Uri.parse('https://api.vimeo.com/videos/$videoId'), @@ -106,6 +121,9 @@ class VideoApis { ); } } + + podCache.addUrls(videoId, list); + return list; } catch (error) { if (error.toString().contains('XMLHttpRequest')) { @@ -124,6 +142,12 @@ class VideoApis { String youtubeIdOrUrl, bool live, ) async { + final podCache = PodUrlCacheSingleton(); + final cachedUrls = podCache.getUrls(youtubeIdOrUrl); + if (cachedUrls.isNotEmpty) { + return cachedUrls; + } + try { final yt = YoutubeExplode(); final urls = []; @@ -151,6 +175,9 @@ class VideoApis { } // Close the YoutubeExplode's http client. yt.close(); + + podCache.addUrls(youtubeIdOrUrl, urls); + return urls; } catch (error) { if (error.toString().contains('XMLHttpRequest')) { diff --git a/lib/src/widgets/core/overlays/web_dropdown_menu.dart b/lib/src/widgets/core/overlays/web_dropdown_menu.dart index 78965f89..783a8999 100644 --- a/lib/src/widgets/core/overlays/web_dropdown_menu.dart +++ b/lib/src/widgets/core/overlays/web_dropdown_menu.dart @@ -68,14 +68,11 @@ class _WebSettingsDropdownState extends State<_WebSettingsDropdown> { switch (settingsMenu) { case 'OUALITY': await _onVimeoQualitySelect(details, podCtr); - break; case 'SPEED': await _onPlaybackSpeedSelect(details, podCtr); - break; case 'LOOP': podCtr.isWebPopupOverlayOpen = false; await podCtr.toggleLooping(); - break; default: podCtr.isWebPopupOverlayOpen = false; } diff --git a/lib/src/widgets/core/pod_core_player.dart b/lib/src/widgets/core/pod_core_player.dart index 7a7a3e47..9dddf9ba 100644 --- a/lib/src/widgets/core/pod_core_player.dart +++ b/lib/src/widgets/core/pod_core_player.dart @@ -16,12 +16,12 @@ class _PodCoreVideoPlayer extends StatelessWidget { final podCtr = Get.find(tag: tag); return Builder( builder: (ctrx) { - return RawKeyboardListener( + return KeyboardListener( autofocus: true, focusNode: (podCtr.isFullScreen ? FocusNode() : podCtr.keyboardFocusWeb) ?? FocusNode(), - onKey: (value) => podCtr.onKeyBoardEvents( + onKeyEvent: (value) => podCtr.onKeyBoardEvents( event: value, appContext: ctrx, tag: tag, diff --git a/lib/src/widgets/doubble_tap_effect.dart b/lib/src/widgets/doubble_tap_effect.dart index f23915f9..a9570a5a 100644 --- a/lib/src/widgets/doubble_tap_effect.dart +++ b/lib/src/widgets/doubble_tap_effect.dart @@ -199,7 +199,7 @@ class _DoubleTapRippleEffectState extends State fillColor: widget.rippleColor, ), ), - ) + ), ], ), ), diff --git a/pubspec.yaml b/pubspec.yaml index c04b2050..293e6fa2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: pod_player description: Vimeo and youtube player for flutter, Pod player provides customizable video player controls that support android, ios and web. -version: 0.2.2 +version: 0.2.6 homepage: https://github.com/newtaDev/pod_player environment: