diff --git a/front/packages/ui/src/player/state.tsx b/front/packages/ui/src/player/state.tsx index 207ff92a..64de53b7 100644 --- a/front/packages/ui/src/player/state.tsx +++ b/front/packages/ui/src/player/state.tsx @@ -18,20 +18,13 @@ * along with Kyoo. If not, see . */ -import { Font, Track, WatchItem } from "@kyoo/models"; +import { Track, WatchItem } from "@kyoo/models"; import { atom, useAtomValue, useSetAtom } from "jotai"; -import { useEffect, useLayoutEffect, useRef } from "react"; +import { memo, useEffect, useLayoutEffect, useRef } from "react"; import NativeVideo, { VideoProperties as VideoProps } from "./video"; import { bakedAtom } from "../jotai-utils"; import { Platform } from "react-native"; -enum PlayMode { - Direct, - Transmux, -} - -const playModeAtom = atom(PlayMode.Direct); - export const playAtom = atom(true); export const loadAtom = atom(false); @@ -70,7 +63,9 @@ export const [privateFullscreen, fullscreenAtom] = bakedAtom( export const subtitleAtom = atom(null); -export const Video = ({ +const MemoVideo = memo(NativeVideo); + +export const Video = memo(function _Video({ links, setError, fonts, @@ -78,7 +73,7 @@ export const Video = ({ }: { links?: WatchItem["link"]; setError: (error: string | undefined) => void; -} & VideoProps) => { +} & Partial) { const ref = useRef(null); const isPlaying = useAtomValue(playAtom); const setLoad = useSetAtom(loadAtom); @@ -110,37 +105,13 @@ export const Video = ({ const subtitle = useAtomValue(subtitleAtom); - // useEffect(() => { - // setPlayMode(PlayMode.Direct); - // }, [links, setPlayMode]); - - // useEffect(() => { - // const src = playMode === PlayMode.Direct ? links?.direct : links?.transmux; - - // if (!player?.current || !src) return; - // if ( - // playMode == PlayMode.Direct || - // player.current.canPlayType("application/vnd.apple.mpegurl") - // ) { - // player.current.src = src; - // } else { - // if (hls === null) hls = new Hls(); - // hls.loadSource(src); - // hls.attachMedia(player.current); - // hls.on(Hls.Events.MANIFEST_LOADED, async () => { - // try { - // await player.current?.play(); - // } catch {} - // }); - // } - // }, [playMode, links, player]); - if (!links) return null; return ( - ); -}; +}); diff --git a/front/packages/ui/src/player/video.web.tsx b/front/packages/ui/src/player/video.web.tsx index 55cde67a..c1516433 100644 --- a/front/packages/ui/src/player/video.web.tsx +++ b/front/packages/ui/src/player/video.web.tsx @@ -19,25 +19,39 @@ */ import { Font, Track } from "@kyoo/models"; -import { forwardRef, RefObject, useEffect, useImperativeHandle, useRef } from "react"; -import { VideoProperties } from "react-native-video"; -import { useAtomValue } from "jotai"; +import { + forwardRef, + RefObject, + useEffect, + useImperativeHandle, + useLayoutEffect, + useRef, +} from "react"; +import { VideoProps } from "react-native-video"; +import { atom, useAtom, useAtomValue } from "jotai"; import { useYoshiki } from "yoshiki"; import SubtitleOctopus from "libass-wasm"; import { subtitleAtom } from "./state"; -// import Hls from "hls.js"; - -// let hls: Hls | null = null; - -// TODO fallback via links and hls. +import Hls from "hls.js"; declare module "react-native-video" { interface VideoProperties { fonts?: Font[]; } + export type VideoProps = Omit & { + source: { uri?: string; transmux?: string }; + }; } -const Video = forwardRef<{ seek: (value: number) => void }, VideoProperties>(function _Video( +enum PlayMode { + Direct, + Transmux, +} + +const playModeAtom = atom(PlayMode.Direct); +let hls: Hls | null = null; + +const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function _Video( { source, paused, muted, volume, onBuffer, onLoad, onProgress, onError, fonts }, forwaredRef, ) { @@ -56,7 +70,7 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProperties>(fun useEffect(() => { if (paused) ref.current?.pause(); - else ref.current?.play(); + else ref.current?.play().catch(() => {}); }, [paused]); useEffect(() => { if (!ref.current || !volume) return; @@ -67,10 +81,33 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProperties>(fun const subtitle = useAtomValue(subtitleAtom); useSubtitle(ref, subtitle, fonts); + const [playMode, setPlayMode] = useAtom(playModeAtom); + useEffect(() => { + setPlayMode(PlayMode.Direct); + }, [source.uri, setPlayMode]); + + useLayoutEffect(() => { + console.log("toto"); + const src = playMode === PlayMode.Direct ? source?.uri : source?.transmux; + + if (!ref?.current || !src) return; + if (playMode == PlayMode.Direct || ref.current.canPlayType("application/vnd.apple.mpegurl")) { + ref.current.src = src; + } else { + if (hls === null) hls = new Hls(); + hls.loadSource(src); + hls.attachMedia(ref.current); + hls.on(Hls.Events.MANIFEST_LOADED, async () => { + try { + await ref.current?.play(); + } catch {} + }); + } + }, [playMode, source?.uri, source?.transmux]); + return (