feat: MPV player for both Android and iOS with added HW decoding PiP (with subtitles) (#1332)

Co-authored-by: Alex Kim <alexkim@Alexs-MacBook-Pro.local>
Co-authored-by: Alex <111128610+Alexk2309@users.noreply.github.com>
Co-authored-by: Simon-Eklundh <simon.eklundh@proton.me>
This commit is contained in:
Fredrik Burmester
2026-01-10 19:35:27 +01:00
committed by GitHub
parent df2f44e086
commit f1575ca48b
98 changed files with 3257 additions and 7448 deletions

View File

@@ -7,9 +7,11 @@ import {
type OptionGroup,
PlatformDropdown,
} from "@/components/PlatformDropdown";
import { PLAYBACK_SPEEDS } from "@/components/PlaybackSpeedSelector";
import { useSettings } from "@/utils/atoms/settings";
import { usePlayerContext } from "../contexts/PlayerContext";
import { useVideoContext } from "../contexts/VideoContext";
import { PlaybackSpeedScope } from "../utils/playback-speed-settings";
// Subtitle size presets (stored as scale * 100, so 1.0 = 100)
const SUBTITLE_SIZE_PRESETS = [
@@ -23,9 +25,17 @@ const SUBTITLE_SIZE_PRESETS = [
{ label: "1.2", value: 120 },
] as const;
const DropdownView = () => {
interface DropdownViewProps {
playbackSpeed?: number;
setPlaybackSpeed?: (speed: number, scope: PlaybackSpeedScope) => void;
}
const DropdownView = ({
playbackSpeed = 1.0,
setPlaybackSpeed,
}: DropdownViewProps) => {
const { subtitleTracks, audioTracks } = useVideoContext();
const { item, mediaSource, useVlcPlayer } = usePlayerContext();
const { item, mediaSource } = usePlayerContext();
const { settings, updateSettings } = useSettings();
const router = useRouter();
@@ -110,19 +120,17 @@ const DropdownView = () => {
})),
});
// Subtitle Size Section (KSPlayer only - VLC uses settings)
if (!useVlcPlayer) {
groups.push({
title: "Subtitle Size",
options: SUBTITLE_SIZE_PRESETS.map((preset) => ({
type: "radio" as const,
label: preset.label,
value: preset.value.toString(),
selected: settings.subtitleSize === preset.value,
onPress: () => updateSettings({ subtitleSize: preset.value }),
})),
});
}
// Subtitle Size Section
groups.push({
title: "Subtitle Size",
options: SUBTITLE_SIZE_PRESETS.map((preset) => ({
type: "radio" as const,
label: preset.label,
value: preset.value.toString(),
selected: settings.subtitleSize === preset.value,
onPress: () => updateSettings({ subtitleSize: preset.value }),
})),
});
}
// Audio Section
@@ -139,6 +147,20 @@ const DropdownView = () => {
});
}
// Speed Section
if (setPlaybackSpeed) {
groups.push({
title: "Speed",
options: PLAYBACK_SPEEDS.map((speed) => ({
type: "radio" as const,
label: speed.label,
value: speed.value.toString(),
selected: playbackSpeed === speed.value,
onPress: () => setPlaybackSpeed(speed.value, PlaybackSpeedScope.All),
})),
});
}
return groups;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
@@ -151,7 +173,8 @@ const DropdownView = () => {
audioIndex,
settings.subtitleSize,
updateSettings,
useVlcPlayer,
playbackSpeed,
setPlaybackSpeed,
// Note: subtitleTracks and audioTracks are intentionally excluded
// because we use subtitleTracksKey and audioTracksKey for stability
]);