mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Move canPlay to method instead of ref function
This commit is contained in:
parent
764fff7677
commit
5de584d6e3
@ -29,7 +29,8 @@ const suboctopus = path.resolve(path.dirname(require.resolve("jassub")), "../dis
|
||||
*/
|
||||
const nextConfig = {
|
||||
swcMinify: true,
|
||||
reactStrictMode: true,
|
||||
// can't be true since we would run hls cleanup twice and run on race conditions
|
||||
reactStrictMode: false,
|
||||
output: "standalone",
|
||||
webpack: (config) => {
|
||||
config.plugins = [
|
||||
|
@ -33,7 +33,7 @@ import {
|
||||
} from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Platform } from "react-native";
|
||||
import NativeVideo, { type VideoProps } from "./video";
|
||||
import NativeVideo, { canPlay, type VideoProps } from "./video";
|
||||
|
||||
export const playAtom = atom(true);
|
||||
export const loadAtom = atom(false);
|
||||
@ -134,14 +134,12 @@ export const Video = memo(function Video({
|
||||
}, [publicProgress]);
|
||||
|
||||
const getProgress = useAtomCallback(useCallback((get) => get(progressAtom), []));
|
||||
const oldLinks = useRef<typeof links | null>(null);
|
||||
useEffect(() => {
|
||||
// Reset the state when a new video is loaded.
|
||||
|
||||
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) {
|
||||
if (newMode === PlayMode.Direct && codec && !canPlay(codec)) {
|
||||
console.log(`Browser can't natively play ${codec}, switching to hls stream.`);
|
||||
newMode = PlayMode.Hls;
|
||||
}
|
||||
@ -149,25 +147,18 @@ export const Video = memo(function Video({
|
||||
|
||||
setSource((newMode === PlayMode.Direct ? links?.direct : links?.hls) ?? null);
|
||||
setLoad(true);
|
||||
if (oldLinks.current !== links) {
|
||||
setPrivateProgress(startTime.current ?? 0);
|
||||
setPublicProgress(startTime.current ?? 0);
|
||||
} else {
|
||||
// keep current time when changing between direct and hls.
|
||||
startTime.current = getProgress();
|
||||
}
|
||||
oldLinks.current = links;
|
||||
setPrivateProgress(startTime.current ?? 0);
|
||||
setPublicProgress(startTime.current ?? 0);
|
||||
setPlay(true);
|
||||
}, [
|
||||
links,
|
||||
codec,
|
||||
setLoad,
|
||||
setPrivateProgress,
|
||||
setPublicProgress,
|
||||
setPlay,
|
||||
getProgress,
|
||||
setPlayMode,
|
||||
]);
|
||||
}, [links, codec, setLoad, setPrivateProgress, setPublicProgress, setPlay, setPlayMode]);
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: do not change source when links change, this is done above
|
||||
useEffect(() => {
|
||||
setSource((mode === PlayMode.Direct ? links?.direct : links?.hls) ?? null);
|
||||
// keep current time when changing between direct and hls.
|
||||
startTime.current = getProgress();
|
||||
setPlay(true);
|
||||
}, [mode, getProgress, setPlay]);
|
||||
|
||||
const account = useAccount();
|
||||
const defaultSubLanguage = account?.settings.subtitleLanguage;
|
||||
|
@ -29,10 +29,6 @@ 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";
|
||||
@ -133,6 +129,9 @@ const Video = forwardRef<VideoRef, VideoProps>(function Video(
|
||||
|
||||
export default Video;
|
||||
|
||||
// mobile should be able to play everything
|
||||
export const canPlay = (codec: string) => true;
|
||||
|
||||
type CustomMenu = ComponentProps<typeof Menu<ComponentProps<typeof IconButton>>>;
|
||||
export const AudiosMenu = ({ audios, ...props }: CustomMenu & { audios?: Audio[] }) => {
|
||||
const info = useAtomValue(infoAtom);
|
||||
|
@ -50,7 +50,7 @@ function uuidv4(): string {
|
||||
const client_id = typeof window === "undefined" ? "ssr" : uuidv4();
|
||||
|
||||
const initHls = (): Hls => {
|
||||
if (hls !== null) return hls;
|
||||
if (hls) hls.destroy();
|
||||
const loadPolicy: LoadPolicy = {
|
||||
default: {
|
||||
maxTimeToFirstByteMs: Number.POSITIVE_INFINITY,
|
||||
@ -104,10 +104,7 @@ const initHls = (): Hls => {
|
||||
return hls;
|
||||
};
|
||||
|
||||
const Video = forwardRef<
|
||||
{ seek: (value: number) => void; canPlay: (codec: string) => boolean },
|
||||
VideoProps
|
||||
>(function Video(
|
||||
const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function Video(
|
||||
{
|
||||
source,
|
||||
paused,
|
||||
@ -161,8 +158,6 @@ const Video = forwardRef<
|
||||
if (!ref?.current || !source.uri) return;
|
||||
if (!hls || oldHls.current !== source.hls) {
|
||||
// Reinit the hls player when we change track.
|
||||
if (hls) hls.destroy();
|
||||
hls = null;
|
||||
hls = initHls();
|
||||
hls.loadSource(source.hls!);
|
||||
oldHls.current = source.hls;
|
||||
@ -181,11 +176,15 @@ const Video = forwardRef<
|
||||
});
|
||||
});
|
||||
}
|
||||
}, [source.uri, source.hls]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
console.log("hls cleanup")
|
||||
if (hls) hls.destroy();
|
||||
hls = null;
|
||||
};
|
||||
}, [source.uri, source.hls]);
|
||||
}, []);
|
||||
|
||||
const mode = useAtomValue(playModeAtom);
|
||||
const audio = useAtomValue(audioAtom);
|
||||
@ -256,6 +255,12 @@ const Video = forwardRef<
|
||||
|
||||
export default Video;
|
||||
|
||||
export const canPlay = (codec: string) => {
|
||||
const videos = document.getElementsByTagName("video");
|
||||
const video = videos.item(0) ?? document.createElement("video");
|
||||
return !!video.canPlayType(codec);
|
||||
};
|
||||
|
||||
const useSubtitle = (
|
||||
player: RefObject<HTMLVideoElement>,
|
||||
value: Subtitle | null,
|
||||
@ -385,11 +390,12 @@ export const QualitiesMenu = (props: ComponentProps<typeof Menu>) => {
|
||||
const [mode, setPlayMode] = useAtom(playModeAtom);
|
||||
const rerender = useForceRerender();
|
||||
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: Inculde hls in dependency array
|
||||
useEffect(() => {
|
||||
if (!hls) return;
|
||||
hls.on(Hls.Events.LEVEL_SWITCHED, rerender);
|
||||
return () => hls?.off(Hls.Events.LEVEL_SWITCHED, rerender);
|
||||
});
|
||||
}, [hls]);
|
||||
|
||||
const levelName = (label: Level, auto?: boolean): string => {
|
||||
const height = `${label.height}p`;
|
||||
|
@ -42,7 +42,8 @@ export const WatchStatusObserver = ({
|
||||
await queryClient.invalidateQueries({ queryKey: [type === "episode" ? "show" : type, slug] }),
|
||||
});
|
||||
const mutate = useCallback(
|
||||
(type: string, slug: string, seconds: number) =>
|
||||
(type: string, slug: string, seconds: number) => {
|
||||
if (seconds < 0 || duration <= 0) return;
|
||||
_mutate({
|
||||
method: "POST",
|
||||
path: [type, slug, "watchStatus"],
|
||||
@ -51,7 +52,8 @@ export const WatchStatusObserver = ({
|
||||
watchedTime: Math.round(seconds),
|
||||
percent: Math.round((seconds / duration) * 100),
|
||||
},
|
||||
}),
|
||||
});
|
||||
},
|
||||
[_mutate, duration],
|
||||
);
|
||||
const readProgress = useAtomCallback(
|
||||
|
Loading…
x
Reference in New Issue
Block a user