Add external subtitles handling

This commit is contained in:
Zoe Roux 2025-07-20 14:54:29 +02:00
parent a6e8b40ca9
commit 40c25690e7
No known key found for this signature in database
3 changed files with 30 additions and 10 deletions

View File

@ -67,6 +67,7 @@ export const expo: ExpoConfig = {
"react-native-video",
{
enableNotificationControls: true,
enableAndroidPictureInPicture: true,
},
],
],

View File

@ -46,6 +46,7 @@ export const Subtitle = z.object({
title: z.string().nullable(),
language: z.string().nullable(),
codec: z.string(),
mimeCodec: z.string().nullable(),
extension: z.string(),
isDefault: z.boolean(),
isForced: z.boolean(),

View File

@ -1,6 +1,7 @@
import { Stack } from "expo-router";
import { useEffect, useRef } from "react";
import { StyleSheet, View } from "react-native";
import { useVideoPlayer, VideoView } from "react-native-video";
import { useVideoPlayer, VideoView, VideoViewRef } from "react-native-video";
import { entryDisplayNumber } from "~/components/entries";
import { FullVideo, VideoInfo } from "~/models";
import { Head } from "~/primitives";
@ -34,19 +35,35 @@ const mapMetadata = (item: FullVideo | undefined) => {
export const Player = () => {
const [slug] = useQueryState("slug", undefined!);
const { apiUrl, authToken } = useToken();
const [playMode] = useLocalSetting<"direct" | "hls">("playMode", "direct");
const player = useVideoPlayer({
uri: `${apiUrl}/api/videos/${slug}/${playMode === "direct" ? "direct" : "master.m3u8"}`,
headers: {
Authorization: `Bearer ${authToken}`,
},
});
const { data, error } = useFetch(Player.query(slug));
const { data: info, error: infoError } = useFetch(Player.infoQuery(slug));
const metadata = mapMetadata(data);
const { apiUrl, authToken } = useToken();
const [playMode] = useLocalSetting<"direct" | "hls">("playMode", "direct");
const player = useVideoPlayer(
{
uri: `${apiUrl}/api/videos/${slug}/${playMode === "direct" ? "direct" : "master.m3u8"}`,
headers: {
Authorization: `Bearer ${authToken}`,
},
externalSubtitles: info?.subtitles
.filter((x) => x.link)
.map((x) => ({
uri: x.link!,
// TODO: translate this `Unknown`
label: x.title ?? "Unknown",
language: x.language ?? "und",
type: x.codec,
})),
},
(p) => {
p.playWhenInactive = true;
p.playInBackground = true;
p.play();
},
);
// const [playbackError, setPlaybackError] = useState<string | undefined>(
// undefined,
// );
@ -92,6 +109,7 @@ export const Player = () => {
navigationBarHidden: true,
statusBarHidden: true,
orientation: "landscape",
contentStyle: { paddingLeft: 0, paddingRight: 0 },
}}
/>
<VideoView