mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -153,6 +153,7 @@ export const Player = ({
|
||||
links={data?.links}
|
||||
audios={info?.audios}
|
||||
subtitles={info?.subtitles}
|
||||
codec={info?.mimeCodec}
|
||||
setError={setPlaybackError}
|
||||
fonts={info?.fonts}
|
||||
startTime={startTime}
|
||||
|
@ -100,6 +100,7 @@ export const Video = memo(function Video({
|
||||
links,
|
||||
subtitles,
|
||||
audios,
|
||||
codec,
|
||||
setError,
|
||||
fonts,
|
||||
startTime: startTimeP,
|
||||
@ -108,6 +109,7 @@ export const Video = memo(function Video({
|
||||
links?: Episode["links"];
|
||||
subtitles?: Subtitle[];
|
||||
audios?: Audio[];
|
||||
codec?: string;
|
||||
setError: (error: string | undefined) => void;
|
||||
fonts?: string[];
|
||||
startTime?: number | null;
|
||||
@ -133,9 +135,19 @@ export const Video = memo(function Video({
|
||||
|
||||
const getProgress = useAtomCallback(useCallback((get) => get(progressAtom), []));
|
||||
const oldLinks = useRef<typeof links | null>(null);
|
||||
useLayoutEffect(() => {
|
||||
useEffect(() => {
|
||||
// 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);
|
||||
if (oldLinks.current !== links) {
|
||||
setPrivateProgress(startTime.current ?? 0);
|
||||
@ -146,7 +158,16 @@ export const Video = memo(function Video({
|
||||
}
|
||||
oldLinks.current = links;
|
||||
setPlay(true);
|
||||
}, [mode, links, setLoad, setPrivateProgress, setPublicProgress, setPlay, getProgress]);
|
||||
}, [
|
||||
links,
|
||||
codec,
|
||||
setLoad,
|
||||
setPrivateProgress,
|
||||
setPublicProgress,
|
||||
setPlay,
|
||||
getProgress,
|
||||
setPlayMode,
|
||||
]);
|
||||
|
||||
const account = useAccount();
|
||||
const defaultSubLanguage = account?.settings.subtitleLanguage;
|
||||
|
@ -29,6 +29,10 @@ declare module "react-native-video" {
|
||||
export type VideoProps = Omit<ReactVideoProps, "source"> & {
|
||||
source: { uri: string; hls: string | null; startPosition?: number };
|
||||
};
|
||||
|
||||
interface VideoRef {
|
||||
canPlay?: (codec: string) => boolean;
|
||||
}
|
||||
}
|
||||
|
||||
export * from "react-native-video";
|
||||
|
@ -104,7 +104,10 @@ const initHls = (): 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,
|
||||
paused,
|
||||
@ -124,6 +127,8 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
|
||||
const ref = useRef<HTMLVideoElement>(null);
|
||||
const oldHls = useRef<string | null>(null);
|
||||
const { css } = useYoshiki();
|
||||
const errorHandler = useRef<typeof onError>(onError);
|
||||
errorHandler.current = onError;
|
||||
|
||||
useImperativeHandle(
|
||||
forwaredRef,
|
||||
@ -131,6 +136,10 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
|
||||
seek: (value: number) => {
|
||||
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);
|
||||
useSubtitle(ref, subtitle, fonts);
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: onError changes should not restart the playback.
|
||||
useLayoutEffect(() => {
|
||||
if (!ref?.current || !source.uri) return;
|
||||
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) => {
|
||||
if (!d.fatal || !hls?.media) return;
|
||||
console.warn("Hls error", d);
|
||||
onError?.call(null, {
|
||||
errorHandler.current?.({
|
||||
error: { errorString: d.reason ?? d.error?.message ?? "Unknown hls error" },
|
||||
});
|
||||
});
|
||||
|
@ -55,10 +55,7 @@ export const PlaybackSettings = () => {
|
||||
<Select
|
||||
label={t("settings.playback.playmode.label")}
|
||||
value={playMode}
|
||||
onValueChange={(value) => {
|
||||
setDefaultPlayMode(value);
|
||||
setCurrentPlayMode(value === "direct" ? PlayMode.Direct : PlayMode.Hls);
|
||||
}}
|
||||
onValueChange={(value) => setDefaultPlayMode(value)}
|
||||
values={["direct", "auto"]}
|
||||
getLabel={(key) => t(`player.${key}`)}
|
||||
/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user