diff --git a/mobile/lib/modules/asset_viewer/hooks/chewiew_controller_hook.dart b/mobile/lib/modules/asset_viewer/hooks/chewiew_controller_hook.dart index 2192963fa1..e4b435ed97 100644 --- a/mobile/lib/modules/asset_viewer/hooks/chewiew_controller_hook.dart +++ b/mobile/lib/modules/asset_viewer/hooks/chewiew_controller_hook.dart @@ -11,7 +11,7 @@ import 'package:immich_mobile/shared/models/store.dart' as store; /// 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( +AsyncSnapshot useChewieController( Asset asset, { EdgeInsets controlsSafeAreaMinimum = const EdgeInsets.only( bottom: 100, @@ -29,96 +29,12 @@ ChewieController? useChewieController( VoidCallback? onPaused, VoidCallback? onVideoEnded, }) { - return use( - _ChewieControllerHook( - keys: [asset], - asset: asset, - placeholder: placeholder, - showOptions: showOptions, - controlsSafeAreaMinimum: controlsSafeAreaMinimum, - autoPlay: autoPlay, - allowFullScreen: allowFullScreen, - customControls: customControls, - hideControlsTimer: hideControlsTimer, - showControlsOnInitialize: showControlsOnInitialize, - showControls: showControls, - allowedScreenSleep: allowedScreenSleep, - onPlaying: onPlaying, - onPaused: onPaused, - onVideoEnded: onVideoEnded, - ), - ); -} - -class _ChewieControllerHook extends Hook { - final Asset asset; - final EdgeInsets controlsSafeAreaMinimum; - final bool showOptions; - final bool showControlsOnInitialize; - final bool autoPlay; - final bool allowFullScreen; - final bool allowedScreenSleep; - final bool showControls; - final Widget? customControls; - final Widget? placeholder; - final Duration hideControlsTimer; - final VoidCallback? onPlaying; - final VoidCallback? onPaused; - final VoidCallback? onVideoEnded; - - const _ChewieControllerHook({ - super.keys, - required this.asset, - 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.customControls, - this.placeholder, - this.hideControlsTimer = const Duration(seconds: 3), - this.onPlaying, - this.onPaused, - this.onVideoEnded, - }); - - @override - createState() => _ChewieControllerHookState(); -} - -class _ChewieControllerHookState - extends HookState { - ChewieController? chewieController; - VideoPlayerController? videoPlayerController; - - @override - void initHook() { - super.initHook(); - _initialize().whenComplete(() => setState(() {})); - } - - @override - void dispose() { - videoPlayerController?.pause(); - videoPlayerController?.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) { + Future initializeChewie(Asset asset) async { + late VideoPlayerController videoPlayerController; + if (asset.isLocal && asset.livePhotoVideoId == null) { // Use a local file for the video player controller - final file = await hook.asset.local!.file; + final file = await asset.local!.file; if (file == null) { throw Exception('No file found for the video'); } @@ -126,9 +42,9 @@ class _ChewieControllerHookState } 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/asset/file/${hook.asset.livePhotoVideoId}' - : '$serverEndpoint/asset/file/${hook.asset.remoteId}'; + final String videoUrl = asset.livePhotoVideoId != null + ? '$serverEndpoint/asset/file/${asset.livePhotoVideoId}' + : '$serverEndpoint/asset/file/${asset.remoteId}'; final url = Uri.parse(videoUrl); final accessToken = store.Store.get(StoreKey.accessToken); @@ -139,20 +55,23 @@ class _ChewieControllerHookState ); } - await videoPlayerController!.initialize(); + 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, + return ChewieController( + videoPlayerController: videoPlayerController, + controlsSafeAreaMinimum: controlsSafeAreaMinimum, + showOptions: showOptions, + showControlsOnInitialize: showControlsOnInitialize, + autoPlay: autoPlay, + allowFullScreen: allowFullScreen, + allowedScreenSleep: allowedScreenSleep, + showControls: showControls, + customControls: customControls, + placeholder: placeholder, + hideControlsTimer: hideControlsTimer, ); } + + final controller = useMemoized(() => initializeChewie(asset)); + return useFuture(controller); } diff --git a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart index 41417decb2..0feb734aae 100644 --- a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart +++ b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart @@ -45,7 +45,7 @@ class VideoViewerPage extends HookConsumerWidget { ), showControls: showControls && !isMotionVideo, hideControlsTimer: hideControlsTimer, - ); + ).data; // The last volume of the video used when mute is toggled final lastVolume = useState(0.0);