diff --git a/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt b/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt index c74cb09c..daf68d99 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt @@ -99,7 +99,7 @@ class MpvPlayerCore(private val activity: Activity) : // Video output configuration MPVLib.setOptionString("vo", "gpu") MPVLib.setOptionString("gpu-context", "android") - MPVLib.setOptionString("hwdec", "mediacodec-copy") + // hwdec is set from Flutter via setProperty based on user preference // Audio configuration MPVLib.setOptionString("ao", "audiotrack") diff --git a/ios/Runner/MpvPlayer/MpvPlayerCore.swift b/ios/Runner/MpvPlayer/MpvPlayerCore.swift index 2e299ba6..e2465c52 100644 --- a/ios/Runner/MpvPlayer/MpvPlayerCore.swift +++ b/ios/Runner/MpvPlayer/MpvPlayerCore.swift @@ -113,7 +113,7 @@ class MpvPlayerCore: NSObject { checkError(mpv_set_option_string(mpv, "vo", "gpu-next")) checkError(mpv_set_option_string(mpv, "gpu-api", "vulkan")) checkError(mpv_set_option_string(mpv, "gpu-context", "moltenvk")) - checkError(mpv_set_option_string(mpv, "hwdec", "videotoolbox")) + // hwdec is set from Flutter via setProperty based on user preference // Initialize MPV let initResult = mpv_initialize(mpv) diff --git a/lib/mpv/src/player/player_native.dart b/lib/mpv/src/player/player_native.dart index 3967f55e..ee845ca6 100644 --- a/lib/mpv/src/player/player_native.dart +++ b/lib/mpv/src/player/player_native.dart @@ -52,7 +52,6 @@ class PlayerNative implements Player { StreamSubscription? _eventSubscription; bool _disposed = false; bool _initialized = false; - bool _isVisible = false; PlayerNative() { _streams = PlayerStreams( @@ -315,7 +314,6 @@ class PlayerNative implements Player { // Show the video layer await _methodChannel.invokeMethod('setVisible', {'visible': true}); - _isVisible = true; // Set start position if provided (must be set before loading file) if (media.start != null && media.start!.inSeconds > 0) { @@ -358,7 +356,6 @@ class PlayerNative implements Player { _checkDisposed(); await command(['stop']); await _methodChannel.invokeMethod('setVisible', {'visible': false}); - _isVisible = false; } @override @@ -479,7 +476,6 @@ class PlayerNative implements Player { try { await _methodChannel.invokeMethod('setVisible', {'visible': visible}); - _isVisible = visible; return true; } catch (e) { _errorController.add('Failed to set visibility: $e'); diff --git a/lib/screens/discover_screen.dart b/lib/screens/discover_screen.dart index 7549a54c..66f0b7b9 100644 --- a/lib/screens/discover_screen.dart +++ b/lib/screens/discover_screen.dart @@ -16,7 +16,6 @@ import '../widgets/user_avatar_widget.dart'; import '../widgets/horizontal_scroll_with_arrows.dart'; import '../widgets/hub_section.dart'; import '../widgets/hub_navigation_controller.dart'; -import '../widgets/focus/focus_indicator.dart'; import 'profile_switch_screen.dart'; import '../providers/user_profile_provider.dart'; import '../providers/settings_provider.dart'; @@ -1292,66 +1291,4 @@ class _DiscoverScreenState extends State ), ); } - - Widget _buildHorizontalList( - List items, { - bool isLarge = false, - bool isInContinueWatching = false, - }) { - return SliverToBoxAdapter( - child: LayoutBuilder( - builder: (context, constraints) { - // Responsive card width based on screen size - // Match Libraries screen sizing (190px baseline) - final screenWidth = constraints.maxWidth; - final cardWidth = screenWidth > 1600 - ? 220.0 - : screenWidth > 1200 - ? 200.0 - : screenWidth > 800 - ? 190.0 - : 160.0; - - // MediaCard has 8px padding on all sides (16px total horizontally) - // So actual poster width is cardWidth - 16 - final posterWidth = cardWidth - 16; - // 2:3 poster aspect ratio (height is 1.5x width) - final posterHeight = posterWidth * 1.5; - // Container height = poster + padding + spacing + text - // 8px top padding + posterHeight + 4px spacing + ~26px text + 8px bottom padding - final containerHeight = posterHeight + 46; - - return SizedBox( - height: containerHeight, - child: HorizontalScrollWithArrows( - builder: (scrollController) => ListView.builder( - controller: scrollController, - scrollDirection: Axis.horizontal, - padding: const EdgeInsets.symmetric(horizontal: 12), - itemCount: items.length, - itemBuilder: (context, index) { - final item = items[index]; - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 2), - child: MediaCard( - key: Key(item.ratingKey), - item: item, - width: cardWidth, - height: posterHeight, - onRefresh: updateItem, - onRemoveFromContinueWatching: isInContinueWatching - ? _refreshContinueWatching - : null, - forceGridMode: true, - isInContinueWatching: isInContinueWatching, - ), - ); - }, - ), - ), - ); - }, - ), - ); - } } diff --git a/lib/screens/video_player_screen.dart b/lib/screens/video_player_screen.dart index 59d6391d..7d39179e 100644 --- a/lib/screens/video_player_screen.dart +++ b/lib/screens/video_player_screen.dart @@ -255,7 +255,7 @@ class VideoPlayerScreenState extends State await player!.setProperty('sub-font', 'Go Noto Current-Regular'); await player!.setProperty('demuxer-max-bytes', bufferSizeBytes.toString()); await player!.setProperty('msg-level', debugLoggingEnabled ? 'all=debug' : 'all=error'); - // await player!.setProperty('hwdec', enableHardwareDecoding ? 'auto' : 'no'); + await player!.setProperty('hwdec', _getHwdecValue(enableHardwareDecoding)); // Subtitle styling await player!.setProperty('sub-font-size', settingsService.getSubtitleFontSize().toString()); @@ -1324,3 +1324,16 @@ class VideoPlayerScreenState extends State ); } } + +/// Returns the appropriate hwdec value based on platform and user preference. +String _getHwdecValue(bool enabled) { + if (!enabled) return 'no'; + + if (Platform.isMacOS || Platform.isIOS) { + return 'videotoolbox'; + } else if (Platform.isAndroid) { + return 'mediacodec-copy'; + } else { + return 'auto'; // Windows, Linux + } +} diff --git a/macos/Runner/MpvPlayer/MpvPlayerCore.swift b/macos/Runner/MpvPlayer/MpvPlayerCore.swift index 9d70c930..c94997cd 100644 --- a/macos/Runner/MpvPlayer/MpvPlayerCore.swift +++ b/macos/Runner/MpvPlayer/MpvPlayerCore.swift @@ -117,7 +117,7 @@ class MpvPlayerCore: NSObject { checkError(mpv_set_option_string(mpv, "vo", "gpu-next")) checkError(mpv_set_option_string(mpv, "gpu-api", "vulkan")) checkError(mpv_set_option_string(mpv, "gpu-context", "moltenvk")) - checkError(mpv_set_option_string(mpv, "hwdec", "videotoolbox")) + // hwdec is set from Flutter via setProperty based on user preference // Initialize MPV let initResult = mpv_initialize(mpv) diff --git a/windows/runner/mpv/mpv_player.cpp b/windows/runner/mpv/mpv_player.cpp index 7da9abeb..e6e278c4 100644 --- a/windows/runner/mpv/mpv_player.cpp +++ b/windows/runner/mpv/mpv_player.cpp @@ -70,7 +70,7 @@ bool MpvPlayer::Initialize(HWND container, HWND flutter_window) { // Configure mpv for embedded playback. LogToFile("MpvPlayer::Initialize - setting mpv options"); - mpv_set_option_string(mpv_, "hwdec", "auto"); + // hwdec is set from Flutter via setProperty based on user preference mpv_set_option_string(mpv_, "keep-open", "yes"); mpv_set_option_string(mpv_, "idle", "yes"); mpv_set_option_string(mpv_, "input-default-bindings", "no");