Skip to content

Commit

Permalink
fix(client): english audio playback consistency (#54562)
Browse files Browse the repository at this point in the history
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
  • Loading branch information
moT01 and ojeytonwilliams committed May 6, 2024
1 parent 9130da7 commit 9342f8e
Showing 1 changed file with 51 additions and 17 deletions.
68 changes: 51 additions & 17 deletions client/src/templates/Challenges/components/scene/scene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import Character from './character';

import './scene.css';

const sToMs = (n: number) => {
return n * 1000;
};

export function Scene({
scene,
isPlaying,
Expand All @@ -21,12 +25,20 @@ export function Scene({
const { t } = useTranslation();
const { setup, commands } = scene;
const { audio, alwaysShowDialogue } = setup;
const { startTimestamp, finishTimestamp } = audio;

const audioTimestamp =
audio.startTimestamp !== null && audio.finishTimestamp !== null
? `#t=${audio.startTimestamp},${audio.finishTimestamp}`
startTimestamp !== null && finishTimestamp !== null
? `#t=${startTimestamp}`
: '';

const hasTimestamps = startTimestamp && finishTimestamp;
// if there are timestamps, we use the difference between them as the duration
// if not, we assume we're playing the whole audio file.
const duration = hasTimestamps
? sToMs(finishTimestamp - startTimestamp)
: Infinity;

const audioRef = useRef<HTMLAudioElement>(
new Audio(`${sounds}/${audio.filename}${audioTimestamp}`)
);
Expand All @@ -37,8 +49,7 @@ export function Scene({

// on mount
useEffect(() => {
const { current } = audioRef;
current.addEventListener('canplaythrough', audioLoaded);
audioRef.current.addEventListener('canplaythrough', audioLoaded);

// preload images
loadImage(`${backgrounds}/${setup.background}`);
Expand All @@ -64,10 +75,6 @@ export function Scene({
};
}, [audioRef, setup.background, setup.characters, commands]);

const audioLoaded = () => {
setSceneIsReady(true);
};

const initBackground = setup.background;
const initDialogue = { label: '', text: '', align: 'left' };
const initCharacters = setup.characters.map(character => {
Expand All @@ -78,7 +85,7 @@ export function Scene({
};
});

const [sceneIsReady, setSceneIsReady] = useState(true);
const [sceneIsReady, setSceneIsReady] = useState(false);
const [showDialogue, setShowDialogue] = useState(false);
const [accessibilityOn, setAccessibilityOn] = useState(false);
const [characters, setCharacters] = useState(initCharacters);
Expand All @@ -94,15 +101,41 @@ export function Scene({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isPlaying]);

const audioLoaded = () => {
setSceneIsReady(true);
};

let start = 0;
let stopAudio = false;

// this function exists because we couldn't reliably stop the audio when
// playing only part of the audio file. So it would get cut off
function maybeStopAudio() {
const runningTime = Date.now() - start;

if (runningTime >= duration) {
stopAudio = true;
audioRef.current.pause();
}

if (!stopAudio) {
window.requestAnimationFrame(maybeStopAudio);
}
}

const playScene = () => {
setShowDialogue(true);

commands.forEach((command, commandIndex) => {
// Start audio timeout
setTimeout(function () {
setTimeout(() => {
if (audioRef.current.paused) {
start = Date.now();
void audioRef.current.play();
}, audio.startTime * 1000);
}
// if there are no timestamps, we can let the audio play to the end
if (hasTimestamps) maybeStopAudio();
}, sToMs(audio.startTime));

commands.forEach((command, commandIndex) => {
// Start command timeout
setTimeout(() => {
if (command.background) setBackground(command.background);
Expand All @@ -127,7 +160,7 @@ export function Scene({
});
return newCharacters;
});
}, command.startTime * 1000);
}, sToMs(command.startTime));

// Finish command timeout, only used when there's a dialogue
if (command.dialogue) {
Expand All @@ -146,7 +179,7 @@ export function Scene({
return newCharacters;
});
},
(command.finishTime as number) * 1000
sToMs(command.finishTime as number)
);
}

Expand All @@ -156,9 +189,10 @@ export function Scene({
() => {
setIsPlaying(false);
},
// an extra 500ms at the end to let the characters fade out (CSS transition)
command.finishTime
? command.finishTime * 1000 + 500
: command.startTime * 1000 + 500
? sToMs(command.finishTime) + 500
: sToMs(command.startTime) + 500
);
}
});
Expand Down

0 comments on commit 9342f8e

Please sign in to comment.