mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -04:00
wip: CanPlay check
This commit is contained in:
parent
55f55db030
commit
69a2821477
@ -149,6 +149,11 @@ export const WatchInfoP = z
|
|||||||
* The extension used to store this video file.
|
* The extension used to store this video file.
|
||||||
*/
|
*/
|
||||||
extension: z.string(),
|
extension: z.string(),
|
||||||
|
/**
|
||||||
|
* The whole mimetype (defined as the RFC 6381).
|
||||||
|
* ex: `video/mp4; codecs="avc1.640028, mp4a.40.2"`
|
||||||
|
*/
|
||||||
|
mimeCodec: z.string(),
|
||||||
/**
|
/**
|
||||||
* The file size of the video file.
|
* The file size of the video file.
|
||||||
*/
|
*/
|
||||||
|
@ -153,6 +153,7 @@ export const Player = ({
|
|||||||
links={data?.links}
|
links={data?.links}
|
||||||
audios={info?.audios}
|
audios={info?.audios}
|
||||||
subtitles={info?.subtitles}
|
subtitles={info?.subtitles}
|
||||||
|
codec={info?.mimeCodec}
|
||||||
setError={setPlaybackError}
|
setError={setPlaybackError}
|
||||||
fonts={info?.fonts}
|
fonts={info?.fonts}
|
||||||
startTime={startTime}
|
startTime={startTime}
|
||||||
|
@ -100,6 +100,7 @@ export const Video = memo(function Video({
|
|||||||
links,
|
links,
|
||||||
subtitles,
|
subtitles,
|
||||||
audios,
|
audios,
|
||||||
|
codec,
|
||||||
setError,
|
setError,
|
||||||
fonts,
|
fonts,
|
||||||
startTime: startTimeP,
|
startTime: startTimeP,
|
||||||
@ -108,6 +109,7 @@ export const Video = memo(function Video({
|
|||||||
links?: Episode["links"];
|
links?: Episode["links"];
|
||||||
subtitles?: Subtitle[];
|
subtitles?: Subtitle[];
|
||||||
audios?: Audio[];
|
audios?: Audio[];
|
||||||
|
codec?: string;
|
||||||
setError: (error: string | undefined) => void;
|
setError: (error: string | undefined) => void;
|
||||||
fonts?: string[];
|
fonts?: string[];
|
||||||
startTime?: number | null;
|
startTime?: number | null;
|
||||||
@ -133,9 +135,19 @@ export const Video = memo(function Video({
|
|||||||
|
|
||||||
const getProgress = useAtomCallback(useCallback((get) => get(progressAtom), []));
|
const getProgress = useAtomCallback(useCallback((get) => get(progressAtom), []));
|
||||||
const oldLinks = useRef<typeof links | null>(null);
|
const oldLinks = useRef<typeof links | null>(null);
|
||||||
useLayoutEffect(() => {
|
useEffect(() => {
|
||||||
// Reset the state when a new video is loaded.
|
// Reset the state when a new video is loaded.
|
||||||
setSource((mode === PlayMode.Direct ? links?.direct : links?.hls) ?? null);
|
|
||||||
|
let newMode = getLocalSetting("playmode", "direct") !== "auto" ? PlayMode.Direct : PlayMode.Hls;
|
||||||
|
// Only allow direct play if the device supports it
|
||||||
|
console.log(codec, ref.current, ref.current?.canPlay?.(codec!))
|
||||||
|
if (newMode === PlayMode.Direct && codec && ref.current?.canPlay?.(codec) === false) {
|
||||||
|
console.log(`Browser can't natively play ${codec}, switching to hls stream.`);
|
||||||
|
newMode = PlayMode.Hls;
|
||||||
|
}
|
||||||
|
setPlayMode(newMode);
|
||||||
|
|
||||||
|
setSource((newMode === PlayMode.Direct ? links?.direct : links?.hls) ?? null);
|
||||||
setLoad(true);
|
setLoad(true);
|
||||||
if (oldLinks.current !== links) {
|
if (oldLinks.current !== links) {
|
||||||
setPrivateProgress(startTime.current ?? 0);
|
setPrivateProgress(startTime.current ?? 0);
|
||||||
@ -146,7 +158,16 @@ export const Video = memo(function Video({
|
|||||||
}
|
}
|
||||||
oldLinks.current = links;
|
oldLinks.current = links;
|
||||||
setPlay(true);
|
setPlay(true);
|
||||||
}, [mode, links, setLoad, setPrivateProgress, setPublicProgress, setPlay, getProgress]);
|
}, [
|
||||||
|
links,
|
||||||
|
codec,
|
||||||
|
setLoad,
|
||||||
|
setPrivateProgress,
|
||||||
|
setPublicProgress,
|
||||||
|
setPlay,
|
||||||
|
getProgress,
|
||||||
|
setPlayMode,
|
||||||
|
]);
|
||||||
|
|
||||||
const account = useAccount();
|
const account = useAccount();
|
||||||
const defaultSubLanguage = account?.settings.subtitleLanguage;
|
const defaultSubLanguage = account?.settings.subtitleLanguage;
|
||||||
|
@ -29,6 +29,10 @@ declare module "react-native-video" {
|
|||||||
export type VideoProps = Omit<ReactVideoProps, "source"> & {
|
export type VideoProps = Omit<ReactVideoProps, "source"> & {
|
||||||
source: { uri: string; hls: string | null; startPosition?: number };
|
source: { uri: string; hls: string | null; startPosition?: number };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface VideoRef {
|
||||||
|
canPlay?: (codec: string) => boolean;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from "react-native-video";
|
export * from "react-native-video";
|
||||||
|
@ -104,7 +104,10 @@ const initHls = (): Hls => {
|
|||||||
return hls;
|
return hls;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function Video(
|
const Video = forwardRef<
|
||||||
|
{ seek: (value: number) => void; canPlay: (codec: string) => boolean },
|
||||||
|
VideoProps
|
||||||
|
>(function Video(
|
||||||
{
|
{
|
||||||
source,
|
source,
|
||||||
paused,
|
paused,
|
||||||
@ -124,6 +127,8 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
|
|||||||
const ref = useRef<HTMLVideoElement>(null);
|
const ref = useRef<HTMLVideoElement>(null);
|
||||||
const oldHls = useRef<string | null>(null);
|
const oldHls = useRef<string | null>(null);
|
||||||
const { css } = useYoshiki();
|
const { css } = useYoshiki();
|
||||||
|
const errorHandler = useRef<typeof onError>(onError);
|
||||||
|
errorHandler.current = onError;
|
||||||
|
|
||||||
useImperativeHandle(
|
useImperativeHandle(
|
||||||
forwaredRef,
|
forwaredRef,
|
||||||
@ -131,6 +136,10 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
|
|||||||
seek: (value: number) => {
|
seek: (value: number) => {
|
||||||
if (ref.current) ref.current.currentTime = value;
|
if (ref.current) ref.current.currentTime = value;
|
||||||
},
|
},
|
||||||
|
canPlay: (codec: string) => {
|
||||||
|
if (!ref.current) return false;
|
||||||
|
return !!ref.current.canPlayType(codec);
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
@ -148,7 +157,6 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
|
|||||||
const subtitle = useAtomValue(subtitleAtom);
|
const subtitle = useAtomValue(subtitleAtom);
|
||||||
useSubtitle(ref, subtitle, fonts);
|
useSubtitle(ref, subtitle, fonts);
|
||||||
|
|
||||||
// biome-ignore lint/correctness/useExhaustiveDependencies: onError changes should not restart the playback.
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (!ref?.current || !source.uri) return;
|
if (!ref?.current || !source.uri) return;
|
||||||
if (!hls || oldHls.current !== source.hls) {
|
if (!hls || oldHls.current !== source.hls) {
|
||||||
@ -168,7 +176,7 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
|
|||||||
hls.on(Hls.Events.ERROR, (_, d) => {
|
hls.on(Hls.Events.ERROR, (_, d) => {
|
||||||
if (!d.fatal || !hls?.media) return;
|
if (!d.fatal || !hls?.media) return;
|
||||||
console.warn("Hls error", d);
|
console.warn("Hls error", d);
|
||||||
onError?.call(null, {
|
errorHandler.current?.({
|
||||||
error: { errorString: d.reason ?? d.error?.message ?? "Unknown hls error" },
|
error: { errorString: d.reason ?? d.error?.message ?? "Unknown hls error" },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -55,10 +55,7 @@ export const PlaybackSettings = () => {
|
|||||||
<Select
|
<Select
|
||||||
label={t("settings.playback.playmode.label")}
|
label={t("settings.playback.playmode.label")}
|
||||||
value={playMode}
|
value={playMode}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => setDefaultPlayMode(value)}
|
||||||
setDefaultPlayMode(value);
|
|
||||||
setCurrentPlayMode(value === "direct" ? PlayMode.Direct : PlayMode.Hls);
|
|
||||||
}}
|
|
||||||
values={["direct", "auto"]}
|
values={["direct", "auto"]}
|
||||||
getLabel={(key) => t(`player.${key}`)}
|
getLabel={(key) => t(`player.${key}`)}
|
||||||
/>
|
/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user