diff --git a/viewer/src/components/Player.tsx b/viewer/src/components/Player.tsx index e42d1ed..4d1cdee 100644 --- a/viewer/src/components/Player.tsx +++ b/viewer/src/components/Player.tsx @@ -1,5 +1,5 @@ import { useRouter } from 'next/router'; -import WebVttPlayerFunctional from "./WebVttPlayer/WebVttPlayerFunctional"; +import WebVttPlayer from "./WebVttPlayer/WebVttPlayer"; // functional component PlayerReact that uses ReactPlayer // TODO: better parameterize video source and VTT source with props (general spec for 3rd party use!). must define spec. @@ -17,7 +17,7 @@ export default function Player() {
- import("react-player/lazy"), { ssr: false }); import Transcript from './Transcript' import Metadata from './Metadata' import Search from './Search' -import './WebVttPlayer.module.css' +const VideoPlayer = dynamic(() => import("../VideoPlayer"), { ssr: false }); -import dynamic from "next/dynamic"; -const ReactPlayer = dynamic(() => import("react-player/lazy"), { ssr: false }); +type WebVttPlayerProps = { + audio: string, + videoUrl: string, // TODO: make naming scheme consistent lol + transcript: string, + metadataUrl: string, + preload: boolean, +}; -// type for props -type WebVttProps = { - video: string, - transcript: string, - metadata: string, - preload: boolean +interface ReactPlayerRef { + seeking: boolean; + played: number; + duration: number; + seekTo: (time: number) => void; } - -interface VideoRef { - seeking: boolean; - played: number; - duration: number; - seekTo: (time: number) => void; +interface NativePlayerRef { + currentTime: number; + ended: boolean; + loop: boolean; + muted: boolean; + play: () => void; } -class WebVttPlayer extends Component { - metatrack: React.RefObject - video: React.RefObject - audio: React.RefObject - track: React.RefObject +export default function WebVttPlayer(props: WebVttPlayerProps) { + const [trackLoaded, setTrackLoaded] = useState(false); + const [metatrackLoaded, setMetatrackLoaded] = useState(false); + const [query, setQuery] = useState(''); - constructor(props: WebVttProps) { - super(props) - this.state = { - loaded: false, - currentTime: 0, - query: '', - seeking: false, - played: new Float64Array(0), - playing: false, + // TODO: determine if these should be set + const [currentTime, setCurrentTime] = useState(0); + const [seeking, setSeeking] = useState(false); + const [played, setPlayed] = useState(new Float64Array(0)); + const [playing, setPlaying] = useState(false); + + const trackRef = useRef(null); + const metatrackRef = useRef(null); + + const reactPlayerRef = useRef(null); + const nativePlayerRef = useRef(null); + + const preload = props.preload ? "true" : "false" + + useLayoutEffect(() => { + + // Get a reference to the track and metatrack elements + const track = trackRef.current; + const metatrack = metatrackRef.current; + + // Check if the tracks are fully loaded + if (track && track.track && track.track.cues && track.track.cues.length > 0) { + setTrackLoaded(true); + } + + if (metatrack && metatrack.track && metatrack.track.cues && metatrack.track.cues.length > 0) { + setMetatrackLoaded(true); + } + + }, [trackLoaded, metatrackLoaded]); + + + + // if we figure out how to get access to Track refs with react-player (even in YouTube videos! That would be awesome), then we can start using this + function reactPlayerSeek(secs: string) { + + if (reactPlayerRef.current) { + reactPlayerRef.current.seekTo(parseFloat(secs)) + } + setPlaying(true); } - this.track = React.createRef() - this.metatrack = React.createRef() - this.audio = React.createRef() - this.video = React.createRef(); - // const playerRef=useRef(); - - this.onLoaded = this.onLoaded.bind(this) - this.seek = this.seek.bind(this) - this.checkIfLoaded = this.checkIfLoaded.bind(this) - this.updateQuery = this.updateQuery.bind(this) - } + function seek(secs: number) { + if (nativePlayerRef.current) { - componentDidMount() { - this.checkIfLoaded() - } - - handlePause = () => { - console.log('onPause') - this.setState({ playing: false }) - } - - - render() { - let track = null - let metatrack = null - if (this.state.loaded) { - track = this.track.current.track - metatrack = this.metatrack.current.track - console.log("loaded video.current : ", this.video.current); + nativePlayerRef.current.currentTime = secs; + nativePlayerRef.current.play(); + } + setPlaying(true); } - const preload = this.props.preload ? "true" : "false" - const metadata = this.props.metadata - ? - : "" return ( -
-
-
- - console.log('onSeek', e)} - onProgress={this.handleProgress} - /> - -
-
- - {metadata} -
- -
-
- ) - } - - onLoaded() { - this.setState({ loaded: true }) - } - - checkIfLoaded(tries = 0) { - tries += 1 - const e = this.track.current - if (e && e.track && e.track.cues && e.track.cues.length > 0) { - this.onLoaded() - } else if (!this.state.loaded) { - const wait = 25 * Math.pow(tries, 2) - setTimeout(this.checkIfLoaded, wait, tries) - } - } - - // handleSeekMouseDown = e => { - // this.setState({ seeking: true }) - // } - - // handleSeekChange = e => { - // this.setState({ played: parseFloat(e.target.value) }) - // } - - // handleSeekMouseUp = e => { - // this.setState({ seeking: false }) - // this.player.seekTo(parseFloat(e.target.value)) - // } - - handleProgress = state => { - console.log('onProgress', state) - // We only want to update time slider if we are not currently seeking - if (!this.state.seeking) { - this.setState(state) - } - } - - // ORIGINAL - seek(secs: number) { - // scrub audio - this.audio.current.currentTime = secs - this.audio.current.play() - - // scrub video - this.setState({ seeking: true }) - console.log("this.video", this.video); - this.video.current?.seekTo(parseFloat(secs)) // TODO: should probs refactor ref to this.player - - } - - updateQuery(query: string) { - this.setState({ query: query }) - } - -} - -export default WebVttPlayer \ No newline at end of file + <> +
+
+
+ {/* */} + {/* a vanilla video element with source and tracks. so much easier oh my god */} + +
+
+ {trackLoaded ? ( + <> + + + ) : ( + "Loading transcript..." + )} + {metatrackLoaded && props.metadataUrl ? ( + <> + + + ) : ( + "\nLoading metadata..." // TODO: make better logic for showing if we wanna serve metadata + )} +
+
+
+ + ); +} \ No newline at end of file diff --git a/viewer/src/components/WebVttPlayer/WebVttPlayerFunctional.tsx b/viewer/src/components/WebVttPlayer/WebVttPlayerFunctional.tsx deleted file mode 100644 index 50caa77..0000000 --- a/viewer/src/components/WebVttPlayer/WebVttPlayerFunctional.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import { useLayoutEffect, useState, useEffect, useRef } from 'react'; -import dynamic from "next/dynamic"; -// const ReactPlayer = dynamic(() => import("react-player/lazy"), { ssr: false }); -import Transcript from './Transcript' -import Metadata from './Metadata' -import Search from './Search' -const VideoPlayer = dynamic(() => import("../VideoPlayer"), { ssr: false }); - -type WebVttPlayerFunctionalProps = { - audio: string, - videoUrl: string, // TODO: make naming scheme consistent lol - transcript: string, - metadataUrl: string, - preload: boolean, -}; - -interface ReactPlayerRef { - seeking: boolean; - played: number; - duration: number; - seekTo: (time: number) => void; -} - -interface NativePlayerRef { - currentTime: number; - ended: boolean; - loop: boolean; - muted: boolean; - play: () => void; -} - -export default function WebVttPlayerFunctional(props: WebVttPlayerFunctionalProps) { - const [trackLoaded, setTrackLoaded] = useState(false); - const [metatrackLoaded, setMetatrackLoaded] = useState(false); - const [query, setQuery] = useState(''); - - // TODO: determine if these should be set - const [currentTime, setCurrentTime] = useState(0); - const [seeking, setSeeking] = useState(false); - const [played, setPlayed] = useState(new Float64Array(0)); - const [playing, setPlaying] = useState(false); - - const trackRef = useRef(null); - const metatrackRef = useRef(null); - - const reactPlayerRef = useRef(null); - const nativePlayerRef = useRef(null); - - const preload = props.preload ? "true" : "false" - - useLayoutEffect(() => { - - // Get a reference to the track and metatrack elements - const track = trackRef.current; - const metatrack = metatrackRef.current; - - // Check if the tracks are fully loaded - if (track && track.track && track.track.cues && track.track.cues.length > 0) { - setTrackLoaded(true); - } - - if (metatrack && metatrack.track && metatrack.track.cues && metatrack.track.cues.length > 0) { - setMetatrackLoaded(true); - } - - }, [trackLoaded, metatrackLoaded]); - - - - // if we figure out how to get access to Track refs with react-player (even in YouTube videos! That would be awesome), then we can start using this - function reactPlayerSeek(secs: string) { - - if (reactPlayerRef.current) { - reactPlayerRef.current.seekTo(parseFloat(secs)) - } - setPlaying(true); - } - - function seek(secs: number) { - if (nativePlayerRef.current) { - - nativePlayerRef.current.currentTime = secs; - nativePlayerRef.current.play(); - } - setPlaying(true); - } - - return ( - <> -
-
-
- {/* */} - {/* a vanilla video element with source and tracks. so much easier oh my god */} - -
-
- {trackLoaded ? ( - <> - - - ) : ( - "Loading transcript..." - )} - {metatrackLoaded && props.metadataUrl ? ( - <> - - - ) : ( - "\nLoading metadata..." // TODO: make better logic for showing if we wanna serve metadata - )} -
-
-
- - ); -} \ No newline at end of file