80 lines
1.7 KiB
TypeScript
80 lines
1.7 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
|
|
interface Props {
|
|
playState: PlayState;
|
|
audioSrc: string;
|
|
videoSrc: string;
|
|
// used to jump to a new position:
|
|
currentTime?: number;
|
|
onPositionChanged: (currentTime: number) => void;
|
|
}
|
|
|
|
export enum PlayState {
|
|
Paused,
|
|
Playing,
|
|
}
|
|
|
|
const triggerCallbackIntervalMillis = 20;
|
|
|
|
export const Player: React.FC<Props> = ({
|
|
playState,
|
|
audioSrc,
|
|
videoSrc,
|
|
currentTime,
|
|
onPositionChanged,
|
|
}) => {
|
|
const audioRef = useRef(new Audio());
|
|
const videoRef = useRef(document.createElement('video'));
|
|
|
|
useEffect(() => {
|
|
setInterval(() => {
|
|
if (audioRef.current.paused) {
|
|
return;
|
|
}
|
|
|
|
onPositionChanged(audioRef.current.currentTime);
|
|
}, triggerCallbackIntervalMillis);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (playState == PlayState.Paused && !audioRef.current.paused) {
|
|
audioRef.current.pause();
|
|
videoRef.current.pause();
|
|
return;
|
|
}
|
|
|
|
if (playState == PlayState.Playing && audioRef.current.paused) {
|
|
audioRef.current.play();
|
|
videoRef.current.play();
|
|
return;
|
|
}
|
|
}, [playState]);
|
|
|
|
useEffect(() => {
|
|
if (audioSrc == '') {
|
|
return;
|
|
}
|
|
audioRef.current.src = audioSrc;
|
|
console.log('set audio src', audioSrc);
|
|
}, [audioSrc]);
|
|
|
|
useEffect(() => {
|
|
if (videoSrc == '') {
|
|
return;
|
|
}
|
|
videoRef.current.src = videoSrc;
|
|
console.log('set video src', videoSrc);
|
|
}, [videoSrc]);
|
|
|
|
useEffect(() => {
|
|
if (currentTime == undefined) {
|
|
return;
|
|
}
|
|
audioRef.current.currentTime = currentTime;
|
|
videoRef.current.currentTime = currentTime;
|
|
onPositionChanged(currentTime);
|
|
}, [currentTime]);
|
|
|
|
return null;
|
|
};
|