This repository has been archived by the owner on Feb 22, 2023. It is now read-only.
Fix global audio syncing and seeking issues #654
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes
Fixes #653 by @sarayourfriend
Closes #632 by @sarayourfriend — All audio tracks on the page buffer immediately so there's no longer a delay between playing them... do we need to prevent audio from loading until the "play" button is hit on it or it is seeked? Probably so.
Description
Switches to using a global ref for the currently active audio track and swapping between multiple audio elements (one per track on the page, aside from the global track).
Some notes/key concepts:
currentTime
ref (which is used for displaying the play progress on the waveform) using thetimeupdate
event exclusively. But to achieve a smooth animation, when a track is playing, we'll update thecurrentTime
ref in arequestAnimationFrame
loop.timeupdate
is still used to update the current time when the audio is not playing (for example if it is seeked while it is paused or ended). Otherwise thetimeupdate
event is ignored when the track is playing.GlobalAudioTrack
andAudioTrack
components share much of the same logic. At a glance it does appear that some of this stuff could be abstracted and I did spend a short amount of time thinking about how to do this. However, most of the "simple" ideas for how to do this, were thwarted by various issues with syncing global and local state selectively. The current implementation works, and while there is some duplicated code, most of it is subtly different. The approaching deadline for the audio release means spending time on refactoring this PR right now is pretty low value. If we decide to spend more time on this in the future, it could alleviate the maintainability burden of these two components, as long as we're sure their implementations won't diverge in the future. Given the already existing subtle differences between the two, I'd make a pretty confident bet that trying to abstract these behaviors into a shared utility would present difficulties in the future.Audio
object on the server. I tried to minimize the amount of code that was shifted into theonMounted
hook, mostly because putting everything in there seems like an organizational misstep. If we did move everything in there, however, we could probably get rid of a lot of the optional chaining on thelocalAudio
variable, but it seems like a small victory that could cause delays in mounting the component that are easily avoided (thanks to ergonomic features like optional chaining).Testing Instructions
Checkout this branch and run
pnpm dev
.Visit an audio result page like http://localhost:8443/search/audio?q=birds and play around with seeking, playing, pausing, replaying tracks, both with and without the global audio player. Also make sure to test navigation between the search results and single result pages.
Checklist
Update index.md
).main
) or a parent feature branch.Developer Certificate of Origin
Developer Certificate of Origin