From fa3156e6eefa0f1317644be9faf17e8e967322a8 Mon Sep 17 00:00:00 2001 From: mertalev <101130780+mertalev@users.noreply.github.com> Date: Thu, 21 Nov 2024 20:24:34 -0500 Subject: [PATCH] remove video_player --- mobile/lib/entities/asset.entity.dart | 1 + .../lib/pages/common/video_viewer.page.dart | 167 ------------------ .../video_player_controller_provider.dart | 46 ----- .../video_player_controller_provider.g.dart | Bin 4820 -> 0 bytes .../video_player_value_provider.dart | 24 --- mobile/lib/routing/router.gr.dart | 12 +- .../utils/hooks/chewiew_controller_hook.dart | 161 ----------------- .../widgets/asset_viewer/video_player.dart | 48 ----- 8 files changed, 7 insertions(+), 452 deletions(-) delete mode 100644 mobile/lib/pages/common/video_viewer.page.dart delete mode 100644 mobile/lib/providers/asset_viewer/video_player_controller_provider.dart delete mode 100644 mobile/lib/providers/asset_viewer/video_player_controller_provider.g.dart delete mode 100644 mobile/lib/utils/hooks/chewiew_controller_hook.dart delete mode 100644 mobile/lib/widgets/asset_viewer/video_player.dart diff --git a/mobile/lib/entities/asset.entity.dart b/mobile/lib/entities/asset.entity.dart index e47a4a24db..4bec35970a 100644 --- a/mobile/lib/entities/asset.entity.dart +++ b/mobile/lib/entities/asset.entity.dart @@ -93,6 +93,7 @@ class Asset { @ignore bool _didUpdateLocal = false; + @ignore Future get localAsync async { final local = this.local; if (local == null) { diff --git a/mobile/lib/pages/common/video_viewer.page.dart b/mobile/lib/pages/common/video_viewer.page.dart deleted file mode 100644 index 4a7617f4d5..0000000000 --- a/mobile/lib/pages/common/video_viewer.page.dart +++ /dev/null @@ -1,167 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/entities/asset.entity.dart'; -import 'package:immich_mobile/providers/asset_viewer/show_controls.provider.dart'; -import 'package:immich_mobile/providers/asset_viewer/video_player_controller_provider.dart'; -import 'package:immich_mobile/providers/asset_viewer/video_player_controls_provider.dart'; -import 'package:immich_mobile/providers/asset_viewer/video_player_value_provider.dart'; -import 'package:immich_mobile/widgets/asset_viewer/video_player.dart'; -import 'package:immich_mobile/widgets/common/delayed_loading_indicator.dart'; -import 'package:wakelock_plus/wakelock_plus.dart'; - -class VideoViewerPage extends HookConsumerWidget { - final Asset asset; - final bool isMotionVideo; - final Widget? placeholder; - final Duration hideControlsTimer; - final bool showControls; - final bool showDownloadingIndicator; - final bool loopVideo; - - const VideoViewerPage({ - super.key, - required this.asset, - this.isMotionVideo = false, - this.placeholder, - this.showControls = true, - this.hideControlsTimer = const Duration(seconds: 5), - this.showDownloadingIndicator = true, - this.loopVideo = false, - }); - - @override - build(BuildContext context, WidgetRef ref) { - final controller = - ref.watch(videoPlayerControllerProvider(asset: asset)).value; - // The last volume of the video used when mute is toggled - final lastVolume = useState(0.5); - - // When the volume changes, set the volume - ref.listen(videoPlayerControlsProvider.select((value) => value.mute), - (_, mute) { - if (mute) { - controller?.setVolume(0.0); - } else { - controller?.setVolume(lastVolume.value); - } - }); - - // When the position changes, seek to the position - ref.listen(videoPlayerControlsProvider.select((value) => value.position), - (_, position) { - if (controller == null) { - // No seeeking if there is no video - return; - } - - // Find the position to seek to - final Duration seek = controller.value.duration * (position / 100.0); - controller.seekTo(seek); - }); - - // When the custom video controls paus or plays - ref.listen(videoPlayerControlsProvider.select((value) => value.pause), - (lastPause, pause) { - if (pause) { - controller?.pause(); - } else { - controller?.play(); - } - }); - - // Updates the [videoPlaybackValueProvider] with the current - // position and duration of the video from the Chewie [controller] - // Also sets the error if there is an error in the playback - void updateVideoPlayback() { - final videoPlayback = VideoPlaybackValue.fromController(controller); - ref.read(videoPlaybackValueProvider.notifier).value = videoPlayback; - final state = videoPlayback.state; - - // Enable the WakeLock while the video is playing - if (state == VideoPlaybackState.playing) { - // Sync with the controls playing - WakelockPlus.enable(); - } else { - // Sync with the controls pause - WakelockPlus.disable(); - } - } - - // Adds and removes the listener to the video player - useEffect( - () { - Future.microtask( - () => ref.read(videoPlayerControlsProvider.notifier).reset(), - ); - // Guard no controller - if (controller == null) { - return null; - } - - // Hide the controls - // Done in a microtask to avoid setting the state while the is building - if (!isMotionVideo) { - Future.microtask(() { - ref.read(showControlsProvider.notifier).show = false; - }); - } - - // Subscribes to listener - Future.microtask(() { - controller.addListener(updateVideoPlayback); - }); - return () { - // Removes listener when we dispose - controller.removeListener(updateVideoPlayback); - controller.pause(); - }; - }, - [controller], - ); - - final size = MediaQuery.sizeOf(context); - - return PopScope( - onPopInvokedWithResult: (didPop, _) { - ref.read(videoPlaybackValueProvider.notifier).reset(); - }, - child: AnimatedSwitcher( - duration: const Duration(milliseconds: 400), - child: Stack( - children: [ - Visibility( - visible: controller == null, - child: Stack( - children: [ - if (placeholder != null) placeholder!, - const Positioned.fill( - child: Center( - child: DelayedLoadingIndicator( - fadeInDuration: Duration(milliseconds: 500), - ), - ), - ), - ], - ), - ), - if (controller != null) - SizedBox( - height: size.height, - width: size.width, - child: VideoPlayerViewer( - controller: controller, - isMotionVideo: isMotionVideo, - placeholder: placeholder, - hideControlsTimer: hideControlsTimer, - showControls: showControls, - showDownloadingIndicator: showDownloadingIndicator, - loopVideo: loopVideo, - ), - ), - ], - ), - ), - ); - } -} diff --git a/mobile/lib/providers/asset_viewer/video_player_controller_provider.dart b/mobile/lib/providers/asset_viewer/video_player_controller_provider.dart deleted file mode 100644 index 969e181cbb..0000000000 --- a/mobile/lib/providers/asset_viewer/video_player_controller_provider.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:immich_mobile/entities/asset.entity.dart'; -import 'package:immich_mobile/entities/store.entity.dart'; -import 'package:immich_mobile/services/api.service.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:video_player/video_player.dart'; - -part 'video_player_controller_provider.g.dart'; - -@riverpod -Future videoPlayerController( - VideoPlayerControllerRef ref, { - required Asset asset, -}) async { - late VideoPlayerController controller; - if (asset.isLocal && asset.livePhotoVideoId == null) { - // Use a local file for the video player controller - final file = await asset.local!.file; - if (file == null) { - throw Exception('No file found for the video'); - } - controller = VideoPlayerController.file(file); - } else { - // Use a network URL for the video player controller - final serverEndpoint = Store.get(StoreKey.serverEndpoint); - final String videoUrl = asset.livePhotoVideoId != null - ? '$serverEndpoint/assets/${asset.livePhotoVideoId}/video/playback' - : '$serverEndpoint/assets/${asset.remoteId}/video/playback'; - - final url = Uri.parse(videoUrl); - controller = VideoPlayerController.networkUrl( - url, - httpHeaders: ApiService.getRequestHeaders(), - videoPlayerOptions: asset.livePhotoVideoId != null - ? VideoPlayerOptions(mixWithOthers: true) - : VideoPlayerOptions(mixWithOthers: false), - ); - } - - await controller.initialize(); - - ref.onDispose(() { - controller.dispose(); - }); - - return controller; -} diff --git a/mobile/lib/providers/asset_viewer/video_player_controller_provider.g.dart b/mobile/lib/providers/asset_viewer/video_player_controller_provider.g.dart deleted file mode 100644 index 00ad37648a85e3bb6510919c7dbd153a69c0e755..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4820 zcmb_gZByem5dNNDu^&3%v@|5V^~e!8N_e^Hl-vMwotsYUb8H#ZajaC9Q-Oj3;nCxr1LPL*@v{<@CB1|5nZyB z$v_GD#!qx^mE`F?_}^(CKWP`wN)NAs?7{28=(q#;k(=-KraOlRgD~6)SP&mZ{oS4Y z{b(8=P7n9q?Hvs8n{a0@-Z!z>hBGneEP_~y8H_2Kx8q+rVG?8+__t4)Vl#RH{zdhb z|9igI#b5$tDo{KGo+=2%Y|2yS(ccevXG?#(2$Gz2^?d*g7r#%1WJAEr1v92FMfenc zIb*5Hv=4L_M$ms8#O4DV;OQ@a0Hf`_miynzJg@)Q@ArSASMUvbq6 za+&HA__HwL_!tiK@pHrfn5P_bVcmZ-pS790WhhEBcdeD*5(pi~iYtRb-BoAQi$L|s zh+3fbjS0^kjKwyZamyG4NhaWTXRZFx>wNfB0P;de&neXHAbc|g&O>_}>*F&azKMp5 zV8)XtU7PFKV=8@xE?o!gQL!}2z^Feu&7RWmGZprc^Cp%E;blDw0D(jPIyF`NSzn)1 zQyIB1ND`0CL$+Xl=UgKCPqU0EKp--;g(uIpcBQHRl?pwr3e4@{QVGBkB_9NGq{M`w z>`G;D&y=-vQrs~Qgklj$9w4`@RxmH>i~MM~p*^o#Yo&Xo?^Ux4ax?k)h+Gv+6LwVE zCrx&aPr#4Z91Db{A!ixZW|}97rpKz|s}!KyP}gx>S6U_8HSED0-^n1&xWeuP6x#r{FKk^47ou&nv0trCGAlrB)#);@us+R|81rl{GIo(8 z<1;JO0`G4^_sVj89f(6v4?OGn*jAWKgT%s(@astyQ|otgWmS@}9wRp0;JINj!Dac; zXsBV?oOP>WG%^g`Puuua#VOCjSF>Eb5wU50f63IDWPxJ0B9|e%!X`be*=qT7Dn!yF zo6ge(mqHH|-X@KGy~V6Immdp`WVN?ysXawJ|027{)))e(cAL&-6=wMyCu={{`MDN~$DGNnV%960i;<%A8zUMA zRoZh3yyDXfb?%~Zs-|*j9B8za-2gk`5R3yQ08OB9+6$6u<9tDKwts-U+GBY^NPf>#!!ITXP@39O#8y?a z5C}yj85u+9-&KTDp%OzR%UqB)!xq#>t!YqekVB2xSd$J5qvCL&fmh?AVzsYbP((k_twEs%Mt z_>A2>%~{W0)*iyDizK;a%&Fee%wCML)g882*yvUfJ#=8kA9?DgLByR_B~oZjHp;Xm z+O7n54{W*p!dJ~TU+G5-N@EG^9zJ!d$8rjw7Sa8mmSxwJBZa73hy7ScKjsOJ9SRF+lwdhJPqTbV z0=|g-j0Fjcd>v)_0Rw+<;E|ta`p~ujf5v80>U53s1M;cGKD|e6r!E~02R9= A&;S4c diff --git a/mobile/lib/providers/asset_viewer/video_player_value_provider.dart b/mobile/lib/providers/asset_viewer/video_player_value_provider.dart index 3c9ac0b99a..1a3c54e9e9 100644 --- a/mobile/lib/providers/asset_viewer/video_player_value_provider.dart +++ b/mobile/lib/providers/asset_viewer/video_player_value_provider.dart @@ -1,6 +1,5 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:native_video_player/native_video_player.dart'; -import 'package:video_player/video_player.dart'; enum VideoPlaybackState { initializing, @@ -54,29 +53,6 @@ class VideoPlaybackValue { ); } - factory VideoPlaybackValue.fromController(VideoPlayerController? controller) { - final video = controller?.value; - late VideoPlaybackState s; - if (video == null) { - s = VideoPlaybackState.initializing; - } else if (video.isCompleted) { - s = VideoPlaybackState.completed; - } else if (video.isPlaying) { - s = VideoPlaybackState.playing; - } else if (video.isBuffering) { - s = VideoPlaybackState.buffering; - } else { - s = VideoPlaybackState.paused; - } - - return VideoPlaybackValue( - position: video?.position ?? Duration.zero, - duration: video?.duration ?? Duration.zero, - state: s, - volume: video?.volume ?? 0.0, - ); - } - VideoPlaybackValue copyWith({ Duration? position, Duration? duration, diff --git a/mobile/lib/routing/router.gr.dart b/mobile/lib/routing/router.gr.dart index 6f9e8cb396..48ee4db5fd 100644 --- a/mobile/lib/routing/router.gr.dart +++ b/mobile/lib/routing/router.gr.dart @@ -1085,7 +1085,7 @@ class NativeVideoViewerRoute extends PageRouteInfo { NativeVideoViewerRoute({ Key? key, required Asset asset, - required Widget placeholder, + required Widget image, bool showControls = true, List? children, }) : super( @@ -1093,7 +1093,7 @@ class NativeVideoViewerRoute extends PageRouteInfo { args: NativeVideoViewerRouteArgs( key: key, asset: asset, - placeholder: placeholder, + image: image, showControls: showControls, ), initialChildren: children, @@ -1108,7 +1108,7 @@ class NativeVideoViewerRoute extends PageRouteInfo { return NativeVideoViewerPage( key: args.key, asset: args.asset, - image: args.placeholder, + image: args.image, showControls: args.showControls, ); }, @@ -1119,7 +1119,7 @@ class NativeVideoViewerRouteArgs { const NativeVideoViewerRouteArgs({ this.key, required this.asset, - required this.placeholder, + required this.image, this.showControls = true, }); @@ -1127,13 +1127,13 @@ class NativeVideoViewerRouteArgs { final Asset asset; - final Widget placeholder; + final Widget image; final bool showControls; @override String toString() { - return 'NativeVideoViewerRouteArgs{key: $key, asset: $asset, placeholder: $placeholder, showControls: $showControls}'; + return 'NativeVideoViewerRouteArgs{key: $key, asset: $asset, image: $image, showControls: $showControls}'; } } diff --git a/mobile/lib/utils/hooks/chewiew_controller_hook.dart b/mobile/lib/utils/hooks/chewiew_controller_hook.dart deleted file mode 100644 index 2868e896cf..0000000000 --- a/mobile/lib/utils/hooks/chewiew_controller_hook.dart +++ /dev/null @@ -1,161 +0,0 @@ -import 'package:chewie/chewie.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:video_player/video_player.dart'; - -/// Provides the initialized video player controller -/// If the asset is local, use the local file -/// Otherwise, use a video player with a URL -ChewieController useChewieController({ - required VideoPlayerController controller, - EdgeInsets controlsSafeAreaMinimum = const EdgeInsets.only( - bottom: 100, - ), - bool showOptions = true, - bool showControlsOnInitialize = false, - bool autoPlay = true, - bool allowFullScreen = false, - bool allowedScreenSleep = false, - bool showControls = true, - bool loopVideo = false, - Widget? customControls, - Widget? placeholder, - Duration hideControlsTimer = const Duration(seconds: 1), - VoidCallback? onPlaying, - VoidCallback? onPaused, - VoidCallback? onVideoEnded, -}) { - return use( - _ChewieControllerHook( - controller: controller, - placeholder: placeholder, - showOptions: showOptions, - controlsSafeAreaMinimum: controlsSafeAreaMinimum, - autoPlay: autoPlay, - allowFullScreen: allowFullScreen, - customControls: customControls, - hideControlsTimer: hideControlsTimer, - showControlsOnInitialize: showControlsOnInitialize, - showControls: showControls, - loopVideo: loopVideo, - allowedScreenSleep: allowedScreenSleep, - onPlaying: onPlaying, - onPaused: onPaused, - onVideoEnded: onVideoEnded, - ), - ); -} - -class _ChewieControllerHook extends Hook { - final VideoPlayerController controller; - final EdgeInsets controlsSafeAreaMinimum; - final bool showOptions; - final bool showControlsOnInitialize; - final bool autoPlay; - final bool allowFullScreen; - final bool allowedScreenSleep; - final bool showControls; - final bool loopVideo; - final Widget? customControls; - final Widget? placeholder; - final Duration hideControlsTimer; - final VoidCallback? onPlaying; - final VoidCallback? onPaused; - final VoidCallback? onVideoEnded; - - const _ChewieControllerHook({ - required this.controller, - this.controlsSafeAreaMinimum = const EdgeInsets.only( - bottom: 100, - ), - this.showOptions = true, - this.showControlsOnInitialize = false, - this.autoPlay = true, - this.allowFullScreen = false, - this.allowedScreenSleep = false, - this.showControls = true, - this.loopVideo = false, - this.customControls, - this.placeholder, - this.hideControlsTimer = const Duration(seconds: 3), - this.onPlaying, - this.onPaused, - this.onVideoEnded, - }); - - @override - createState() => _ChewieControllerHookState(); -} - -class _ChewieControllerHookState - extends HookState { - late ChewieController chewieController = ChewieController( - videoPlayerController: hook.controller, - controlsSafeAreaMinimum: hook.controlsSafeAreaMinimum, - showOptions: hook.showOptions, - showControlsOnInitialize: hook.showControlsOnInitialize, - autoPlay: hook.autoPlay, - allowFullScreen: hook.allowFullScreen, - allowedScreenSleep: hook.allowedScreenSleep, - showControls: hook.showControls, - looping: hook.loopVideo, - customControls: hook.customControls, - placeholder: hook.placeholder, - hideControlsTimer: hook.hideControlsTimer, - ); - - @override - void dispose() { - chewieController.dispose(); - super.dispose(); - } - - @override - ChewieController build(BuildContext context) { - return chewieController; - } - - /* - /// Initializes the chewie controller and video player controller - Future _initialize() async { - if (hook.asset.isLocal && hook.asset.livePhotoVideoId == null) { - // Use a local file for the video player controller - final file = await hook.asset.local!.file; - if (file == null) { - throw Exception('No file found for the video'); - } - videoPlayerController = VideoPlayerController.file(file); - } else { - // Use a network URL for the video player controller - final serverEndpoint = store.Store.get(store.StoreKey.serverEndpoint); - final String videoUrl = hook.asset.livePhotoVideoId != null - ? '$serverEndpoint/assets/${hook.asset.livePhotoVideoId}/video/playback' - : '$serverEndpoint/assets/${hook.asset.remoteId}/video/playback'; - - final url = Uri.parse(videoUrl); - final accessToken = store.Store.get(StoreKey.accessToken); - - videoPlayerController = VideoPlayerController.networkUrl( - url, - httpHeaders: {"x-immich-user-token": accessToken}, - ); - } - - await videoPlayerController!.initialize(); - - chewieController = ChewieController( - videoPlayerController: videoPlayerController!, - controlsSafeAreaMinimum: hook.controlsSafeAreaMinimum, - showOptions: hook.showOptions, - showControlsOnInitialize: hook.showControlsOnInitialize, - autoPlay: hook.autoPlay, - allowFullScreen: hook.allowFullScreen, - allowedScreenSleep: hook.allowedScreenSleep, - showControls: hook.showControls, - customControls: hook.customControls, - placeholder: hook.placeholder, - hideControlsTimer: hook.hideControlsTimer, - ); - } - */ -} diff --git a/mobile/lib/widgets/asset_viewer/video_player.dart b/mobile/lib/widgets/asset_viewer/video_player.dart deleted file mode 100644 index ebf158b59a..0000000000 --- a/mobile/lib/widgets/asset_viewer/video_player.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:chewie/chewie.dart'; -import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/utils/hooks/chewiew_controller_hook.dart'; -import 'package:immich_mobile/widgets/asset_viewer/custom_video_player_controls.dart'; -import 'package:video_player/video_player.dart'; - -class VideoPlayerViewer extends HookConsumerWidget { - final VideoPlayerController controller; - final bool isMotionVideo; - final Widget? placeholder; - final Duration hideControlsTimer; - final bool showControls; - final bool showDownloadingIndicator; - final bool loopVideo; - - const VideoPlayerViewer({ - super.key, - required this.controller, - required this.isMotionVideo, - this.placeholder, - required this.hideControlsTimer, - required this.showControls, - required this.showDownloadingIndicator, - required this.loopVideo, - }); - - @override - Widget build(BuildContext context, WidgetRef ref) { - final chewie = useChewieController( - controller: controller, - controlsSafeAreaMinimum: const EdgeInsets.only( - bottom: 100, - ), - placeholder: SizedBox.expand(child: placeholder), - customControls: CustomVideoPlayerControls( - hideTimerDuration: hideControlsTimer, - ), - showControls: showControls && !isMotionVideo, - hideControlsTimer: hideControlsTimer, - loopVideo: loopVideo, - ); - - return Chewie( - controller: chewie, - ); - } -}