mirror of
https://github.com/streamyfin/streamyfin.git
synced 2025-08-20 18:37:18 +02:00
wip
This commit is contained in:
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user