Kopie van https://gitlab.com/studieverenigingvia/ict/centurion met een paar aanpassingen
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

110 lines
3.6 KiB

import {roomTime, useRoomRunningAndReadyChanged, useRoomTime, useTimelineSongFileChanged} from "../lib/Connection";
import React, {createRef, SyntheticEvent, useRef, useState} from "react";
import '../css/player.sass'
import {Room} from "../types/types";
import {parse as parseQueryString} from "query-string";
const Player = () => {
const room = useRoomRunningAndReadyChanged();
const _ = useRoomTime()
const timeline = useTimelineSongFileChanged();
let player = useRef<HTMLAudioElement>(null)
const [timesSeeked, setTimesSeeked] = useState(0);
const [hadError, setHadError] = useState(false);
// If our time synchronisation algorithm thing thinks the time is off by more
// than this value, we seek the running player to correct it.
const diffSecondsRequiredToSeekRunningPlayer = 0.20;
// Hard cap we are allowed to seek this player. Some browsers are slow or inaccurate
// and will always be off. To avoid endless skipping of the song this cap stops seeking the
// player.
const maxTimesSeekAllow = 25;
const query = parseQueryString(window.location.search);
if (query.nosound) {
return null;
}
if (player.current && player.current.dataset.src != timeline!!.songFile) {
player.current.dataset.src = timeline!!.songFile;
player.current.src = timeline!!.songFile;
}
function handlePlayerOnPlay(e: SyntheticEvent) {
e.preventDefault();
// For when the user manually started the player for when autoplay is off.
setHadError(false);
if (shouldPlay()) {
startPlaying(true)
}
}
function shouldPlay() {
return player.current && timeline && room && room.running && room.readyToParticipate
}
function startPlaying(manual: boolean) {
if (!player.current) return;
if (player.current.paused && !hadError) {
player.current.play().then(() => {
setHadError(false);
}).catch(e => {
console.error('Error playing', e);
setHadError(true);
})
}
if (!hadError) {
setPlayerTime(room!!, manual);
}
}
function setPlayerTime(room: Room, manualAdjustment: boolean) {
if (!player.current) return;
let targetTime = roomTime() / 1000;
let diff = player.current.currentTime - targetTime;
console.log('PLAYER DIFF', diff,
'min req to seek: ', diffSecondsRequiredToSeekRunningPlayer);
if (player.current && Math.abs(diff) > diffSecondsRequiredToSeekRunningPlayer) {
if (room.speedFactor != 1 || manualAdjustment || timesSeeked < maxTimesSeekAllow) {
player.current.currentTime = targetTime;
player.current.playbackRate = Math.max(Math.min(4.0, room.speedFactor), 0.25);
if (!manualAdjustment) {
setTimesSeeked(timesSeeked + 1);
}
console.log('PLAYER SEEKED', 'Player was seeked (total: ' + timesSeeked + ')');
} else {
console.warn('The running player is off, but we\'ve changed the time ' +
'too often, skipping synchronizing the player.');
}
}
}
if (shouldPlay()) {
startPlaying(false)
} else {
if (player.current) {
player.current.pause();
}
}
function render() {
return (
<audio ref={player} className='player' hidden={!hadError} controls={true} onPlay={handlePlayerOnPlay}/>
)
}
return render();
}
export default Player;