This commit is contained in:
Fredrik Burmester
2024-10-14 18:30:01 +02:00
parent 67be97d857
commit 3807f847fd
4 changed files with 99 additions and 47 deletions

View File

@@ -1,5 +1,4 @@
import { Controls } from "@/components/video-player/Controls";
import { VideoDebugInfo } from "@/components/vlc/VideoDebugInfo";
import { useAndroidNavigationBar } from "@/hooks/useAndroidNavigationBar";
import { useOrientation } from "@/hooks/useOrientation";
import { useOrientationSettings } from "@/hooks/useOrientationSettings";
@@ -24,7 +23,6 @@ import { getPlaystateApi } from "@jellyfin/sdk/lib/utils/api";
import * as Haptics from "expo-haptics";
import { useFocusEffect } from "expo-router";
import { useAtomValue } from "jotai";
import { set } from "lodash";
import React, {
useCallback,
useEffect,
@@ -32,13 +30,9 @@ import React, {
useRef,
useState,
} from "react";
import { Alert, Dimensions, Pressable, StatusBar, View } from "react-native";
import { Dimensions, Pressable, StatusBar, View } from "react-native";
import { useSharedValue } from "react-native-reanimated";
import Video, {
OnProgressData,
SelectedTrackType,
VideoRef,
} from "react-native-video";
import { SelectedTrackType } from "react-native-video";
export default function page() {
const { playSettings, playUrl, playSessionId } = usePlaySettings();
@@ -276,6 +270,8 @@ export default function page() {
};
}, []);
const [isVideoLoaded, setIsVideoLoaded] = useState(false);
return (
<View
style={{
@@ -307,6 +303,7 @@ export default function page() {
console.log("onVideoLoadStart");
}}
onVideoLoadEnd={() => {
setIsVideoLoaded(true);
console.log("onVideoLoadEnd");
}}
/>
@@ -340,6 +337,7 @@ export default function page() {
setShowControls={setShowControls}
setIgnoreSafeAreas={setIgnoreSafeAreas}
ignoreSafeAreas={ignoreSafeAreas}
isVideoLoaded={isVideoLoaded}
/>
</View>
);

View File

@@ -59,6 +59,7 @@ interface Props {
togglePlay: (ticks: number) => void;
setShowControls: (shown: boolean) => void;
offline?: boolean;
isVideoLoaded?: boolean;
}
export const Controls: React.FC<Props> = ({
@@ -74,6 +75,7 @@ export const Controls: React.FC<Props> = ({
setShowControls,
ignoreSafeAreas,
setIgnoreSafeAreas,
isVideoLoaded,
offline = false,
}) => {
const [settings] = useSettings();
@@ -247,14 +249,6 @@ export const Controls: React.FC<Props> = ({
MediaStream | undefined
>(undefined);
const allSubtitleTracks = useMemo(() => {
const subs = item.MediaStreams?.filter(
(stream) => stream.Type === "Subtitle"
);
console.log("allSubtitleTracks", subs);
return subs;
}, [item]);
const [audioTracks, setAudioTracks] = useState<TrackInfo[] | null>(null);
const [subtitleTracks, setSubtitleTracks] = useState<TrackInfo[] | null>(
null
@@ -273,7 +267,55 @@ export const Controls: React.FC<Props> = ({
};
fetchTracks();
}, [videoRef]);
}, [videoRef, isVideoLoaded]);
type EmbeddedSubtitle = {
name: string;
index: number;
isExternal: false;
};
type ExternalSubtitle = {
name: string;
index: number;
isExternal: true;
deliveryUrl: string;
};
const allSubtitleTracks = useMemo(() => {
const embeddedSubs =
subtitleTracks?.map((s) => ({
name: s.name,
index: s.index,
isExternal: false,
deliveryUrl: undefined,
})) || [];
const externalSubs =
item.MediaStreams?.filter(
(stream) => stream.Type === "Subtitle" && stream.IsExternal
).map((s) => ({
name: s.DisplayTitle!,
index: s.Index!,
isExternal: s.DeliveryMethod === "External",
deliveryUrl: s.DeliveryUrl,
})) || [];
// Create a Set of embedded subtitle names for quick lookup
const embeddedSubNames = new Set(embeddedSubs.map((sub) => sub.name));
// Filter out external subs that have the same name as embedded subs
const uniqueExternalSubs = externalSubs.filter(
(sub) => !embeddedSubNames.has(sub.name)
);
console.log([...embeddedSubs, ...uniqueExternalSubs]);
// Combine embedded and unique external subs
return [...embeddedSubs, ...uniqueExternalSubs] as (
| EmbeddedSubtitle
| ExternalSubtitle
)[];
}, [item, isVideoLoaded, subtitleTracks]);
return (
<View
@@ -325,39 +367,47 @@ export const Controls: React.FC<Props> = ({
loop={true}
sideOffset={10}
>
<DropdownMenu.CheckboxItem
key="subtitle--1"
{/* <DropdownMenu.CheckboxItem
key="none-item"
value="off"
onValueChange={() => {
videoRef.current?.setSubtitleTrack(-1);
}}
>
<DropdownMenu.ItemIndicator />
<DropdownMenu.ItemTitle key={`subtitle-item--1`}>
<DropdownMenu.ItemTitle key={`none-item-title`}>
None
</DropdownMenu.ItemTitle>
</DropdownMenu.CheckboxItem>
{subtitleTracks?.map((sub, idx: number) => (
</DropdownMenu.CheckboxItem> */}
{allSubtitleTracks.length > 0
? allSubtitleTracks?.map((sub, idx: number) => (
<DropdownMenu.CheckboxItem
key={`subtitle-${idx}`}
key={`subtitle-item-${idx}`}
value="off"
onValueChange={() => {
// if(sub. === 'External') {
// videoRef.current?.setSubtitleURL(
// `https://fredflix.se/Providers/Subtitles/Subtitles/`
// );
// }
if (sub.isExternal) {
videoRef.current?.setSubtitleURL(sub.deliveryUrl);
console.log(
"Setting external subtitle:",
sub.deliveryUrl
);
return;
}
videoRef.current?.setSubtitleTrack(-1);
console.log("Settings embedded subtitle", sub.name);
videoRef.current?.setSubtitleTrack(sub.index);
console.log(sub);
}}
>
<DropdownMenu.ItemIndicator />
<DropdownMenu.ItemTitle key={`subtitle-item-${idx}`}>
<DropdownMenu.ItemTitle
key={`subtitle-item-title-${idx}`}
>
{sub.name}
</DropdownMenu.ItemTitle>
</DropdownMenu.CheckboxItem>
))}
))
: null}
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
</DropdownMenu.Content>

View File

@@ -557,7 +557,7 @@ extension VlcPlayerView: VLCMediaPlayerDelegate {
}
// Dermine if the media has finished loading
if currentState == .buffering && !self.isMediaReady {
if player.isPlaying && !self.isMediaReady {
self.isMediaReady = true
self.onVideoLoadEnd?(stateInfo)
}

View File

@@ -260,23 +260,27 @@ export default {
SubtitleProfiles: [
{
Format: "pgssub",
Method: "encode",
Method: "embed",
},
{
Format: "subrip",
Method: "embed",
},
{
Format: "dvdsub",
Method: "encode",
Method: "embed",
},
{
Format: "dvbsub",
Method: "encode",
Method: "embed",
},
{
Format: "xsub",
Method: "encode",
Method: "embed",
},
{
Format: "vtt",
Method: "hls",
Method: "embed",
},
{
Format: "ttml",