diff --git a/mobile/ios/Podfile.lock b/mobile/ios/Podfile.lock index 55d8e0fa00..bd6da47db9 100644 --- a/mobile/ios/Podfile.lock +++ b/mobile/ios/Podfile.lock @@ -65,6 +65,8 @@ PODS: - maplibre_gl (0.0.1): - Flutter - MapLibre (= 5.14.0-pre3) + - native_video_player (1.0.0): + - Flutter - package_info_plus (0.4.5): - Flutter - path_provider_foundation (0.0.1): @@ -115,6 +117,7 @@ DEPENDENCIES: - integration_test (from `.symlinks/plugins/integration_test/ios`) - isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`) - maplibre_gl (from `.symlinks/plugins/maplibre_gl/ios`) + - native_video_player (from `.symlinks/plugins/native_video_player/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) @@ -168,6 +171,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/isar_flutter_libs/ios" maplibre_gl: :path: ".symlinks/plugins/maplibre_gl/ios" + native_video_player: + :path: ".symlinks/plugins/native_video_player/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: @@ -210,6 +215,7 @@ SPEC CHECKSUMS: isar_flutter_libs: fdf730ca925d05687f36d7f1d355e482529ed097 MapLibre: 620fc933c1d6029b33738c905c1490d024e5d4ef maplibre_gl: a2efec727dd340e4c65e26d2b03b584f14881fd9 + native_video_player: d12af78a1a4a8cf09775a5177d5b392def6fd23c package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 diff --git a/mobile/lib/pages/common/video_viewer.page.dart b/mobile/lib/pages/common/video_viewer.page.dart index 573f7277f2..401e0fab73 100644 --- a/mobile/lib/pages/common/video_viewer.page.dart +++ b/mobile/lib/pages/common/video_viewer.page.dart @@ -103,7 +103,7 @@ class VideoViewerPage extends HookConsumerWidget { // Done in a microtask to avoid setting the state while the is building if (!isMotionVideo) { Future.microtask(() { - ref.read(showControlsProvider.notifier).show = false; + ref.read(showControlsProvider.notifier).show = true; }); } @@ -148,16 +148,20 @@ class VideoViewerPage extends HookConsumerWidget { ), if (controller != null) SizedBox( - height: size.height, + height: 16 / 9 * size.width, width: size.width, - child: VideoPlayerViewer( - controller: controller, - isMotionVideo: isMotionVideo, - placeholder: placeholder, - hideControlsTimer: hideControlsTimer, - showControls: showControls, - showDownloadingIndicator: showDownloadingIndicator, - loopVideo: loopVideo, + child: AspectRatio( + aspectRatio: 16 / 9, + child: VideoPlayerViewer( + controller: controller, + isMotionVideo: isMotionVideo, + placeholder: placeholder, + hideControlsTimer: hideControlsTimer, + showControls: showControls, + showDownloadingIndicator: showDownloadingIndicator, + loopVideo: loopVideo, + asset: asset, + ), ), ), ], diff --git a/mobile/lib/widgets/asset_viewer/video_player.dart b/mobile/lib/widgets/asset_viewer/video_player.dart index ebf158b59a..3e8a3c623c 100644 --- a/mobile/lib/widgets/asset_viewer/video_player.dart +++ b/mobile/lib/widgets/asset_viewer/video_player.dart @@ -1,8 +1,11 @@ import 'package:chewie/chewie.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/entities/asset.entity.dart'; +import 'package:immich_mobile/entities/store.entity.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:native_video_player/native_video_player.dart'; import 'package:video_player/video_player.dart'; class VideoPlayerViewer extends HookConsumerWidget { @@ -13,6 +16,7 @@ class VideoPlayerViewer extends HookConsumerWidget { final bool showControls; final bool showDownloadingIndicator; final bool loopVideo; + final Asset asset; const VideoPlayerViewer({ super.key, @@ -23,26 +27,59 @@ class VideoPlayerViewer extends HookConsumerWidget { required this.showControls, required this.showDownloadingIndicator, required this.loopVideo, + required this.asset, }); @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, - ); + // 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, + // return Chewie( + // controller: chewie, + // ); + + return NativeVideoPlayerView( + onViewReady: (controller) async { + try { + String path = ''; + VideoSourceType type = VideoSourceType.file; + 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'); + } + path = file.path; + type = VideoSourceType.file; + + final videoSource = await VideoSource.init( + path: path, + type: type, + ); + + await controller.loadVideoSource(videoSource); + await controller.play(); + + Future.delayed(const Duration(milliseconds: 100), () async { + await controller.setVolume(0.5); + }); + } + } catch (e) { + print('Error loading video: $e'); + } + }, ); } } diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 8b43cf33de..af4561db05 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -1024,6 +1024,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + native_video_player: + dependency: "direct main" + description: + name: native_video_player + sha256: "8df92df138c13ebf9df6b30525f9c4198534705fd450a98da14856d3a0e48cd4" + url: "https://pub.dev" + source: hosted + version: "1.3.1" nested: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index f20fb7afda..e8d8d35529 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -64,6 +64,7 @@ dependencies: async: ^2.11.0 dynamic_color: ^1.7.0 #package to apply system theme background_downloader: ^8.5.5 + native_video_player: ^1.3.1 #image editing packages crop_image: ^1.0.13