diff --git a/mobile/assets/i18n/en-US.json b/mobile/assets/i18n/en-US.json index a7f31f8440f7e..47d07a30d221d 100644 --- a/mobile/assets/i18n/en-US.json +++ b/mobile/assets/i18n/en-US.json @@ -527,6 +527,8 @@ "settings_require_restart": "Please restart Immich to apply this setting", "setting_video_viewer_looping_subtitle": "Enable to automatically loop a video in the detail viewer.", "setting_video_viewer_looping_title": "Looping", + "setting_video_viewer_original_video_title": "Force original video", + "setting_video_viewer_original_video_subtitle": "When streaming a video from the server, play the original even when a transcode is available. May lead to buffering. Videos available locally are played in original quality regardless of this setting.", "setting_video_viewer_title": "Videos", "share_add": "Add", "share_add_photos": "Add photos", @@ -656,4 +658,4 @@ "viewer_unstack": "Un-Stack", "wifi_name": "WiFi Name", "your_wifi_name": "Your WiFi name" -} \ No newline at end of file +} diff --git a/mobile/lib/entities/store.entity.dart b/mobile/lib/entities/store.entity.dart index 316859b064d1e..a7f2db78d08c6 100644 --- a/mobile/lib/entities/store.entity.dart +++ b/mobile/lib/entities/store.entity.dart @@ -242,6 +242,9 @@ enum StoreKey { preferredWifiName(133, type: String), localEndpoint(134, type: String), externalEndpointList(135, type: String), + + // Video settings + loadOriginalVideo(136, type: bool), ; const StoreKey( diff --git a/mobile/lib/pages/common/native_video_viewer.page.dart b/mobile/lib/pages/common/native_video_viewer.page.dart index 9c50f49dbbac8..ad9d53b1bb0ef 100644 --- a/mobile/lib/pages/common/native_video_viewer.page.dart +++ b/mobile/lib/pages/common/native_video_viewer.page.dart @@ -75,9 +75,14 @@ class NativeVideoViewerPage extends HookConsumerWidget { // Use a network URL for the video player controller final serverEndpoint = Store.get(StoreKey.serverEndpoint); + final isOriginalVideo = ref + .read(appSettingsServiceProvider) + .getSetting(AppSettingsEnum.loadOriginalVideo); + final String postfixUrl = + isOriginalVideo ? 'original' : 'video/playback'; final String videoUrl = asset.livePhotoVideoId != null - ? '$serverEndpoint/assets/${asset.livePhotoVideoId}/video/playback' - : '$serverEndpoint/assets/${asset.remoteId}/video/playback'; + ? '$serverEndpoint/assets/${asset.livePhotoVideoId}/$postfixUrl' + : '$serverEndpoint/assets/${asset.remoteId}/$postfixUrl'; final source = await VideoSource.init( path: videoUrl, diff --git a/mobile/lib/services/app_settings.service.dart b/mobile/lib/services/app_settings.service.dart index c3fde894d545d..19e7093faf3c1 100644 --- a/mobile/lib/services/app_settings.service.dart +++ b/mobile/lib/services/app_settings.service.dart @@ -63,6 +63,11 @@ enum AppSettingsEnum { logLevel(StoreKey.logLevel, null, 5), // Level.INFO = 5 preferRemoteImage(StoreKey.preferRemoteImage, null, false), loopVideo(StoreKey.loopVideo, "loopVideo", true), + loadOriginalVideo( + StoreKey.loadOriginalVideo, + "loadOriginalVideo", + false, + ), mapThemeMode(StoreKey.mapThemeMode, null, 0), mapShowFavoriteOnly(StoreKey.mapShowFavoriteOnly, null, false), mapIncludeArchived(StoreKey.mapIncludeArchived, null, false), diff --git a/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart b/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart index e21c49bb06c61..ef99c79a7bca3 100644 --- a/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart +++ b/mobile/lib/widgets/settings/asset_viewer_settings/video_viewer_settings.dart @@ -15,6 +15,8 @@ class VideoViewerSettings extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final useLoopVideo = useAppSettingsState(AppSettingsEnum.loopVideo); + final useOriginalVideo = + useAppSettingsState(AppSettingsEnum.loadOriginalVideo); return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -26,6 +28,12 @@ class VideoViewerSettings extends HookConsumerWidget { subtitle: "setting_video_viewer_looping_subtitle".tr(), onChanged: (_) => ref.invalidate(appSettingsServiceProvider), ), + SettingsSwitchListTile( + valueNotifier: useOriginalVideo, + title: "setting_video_viewer_original_video_title".tr(), + subtitle: "setting_video_viewer_original_video_subtitle".tr(), + onChanged: (_) => ref.invalidate(appSettingsServiceProvider), + ), ], ); }