My blog’s audio player
Since as early as 2008 (My Brother’s Minuet) I’ve included audio files in posts to this blog. One thing that always bugged me about this setup was that when those audio files are longer in duration they can trap you on a page since the audio player is embedded within the specific page. If you navigate away the audio stops.
Based on my experience using the web audio API in other projects it occurred to me I could build my own audio player into the site rather than just relying on simple <audio> tags as I had in the past. So, I switched to a model where the audio embedded in each post simply rendered as a control to start playing the audio file in the site‘s global audio player. With this approach you can start listening to an audio file on one post and continue listening as you navigate to other pages on the site.

This is enabled by Next.js’ model where intra-site navigations are handled by JavaScript (instead of as a brand new page load) and thus can retain state. The implementation consists of a React context which maintains the state of which audio file is playing and its duration, progress etc. Audio files in posts are then rendered (using a nice way of rendering markdown in React apps) as React components which check the context to see if the file is currently being played and, when clicked, tell that context to start playing the given audio file.
The main website layout includes a global audio player component at the bottom of the page which, if any audio is currently playing, shows the global player.
Inline Example #
You can try out an example here:
Code Pointers #
The audio element component embedded in pages with audio
Complications #
This approach highlighted a subtle bug in my site: in some places I had intra-site links which were using fully qualified URLs instead of internal paths. These links would, confusingly, force full page reloads which would interrupt currently playing files. To address this, I added normalization logic to my markdown renderer which ensures all internal links are rendered as paths not URLs.
Related Work #
When I turned this blog into a podcast I took these same embedded audio files and inlined them within the text-to-speech generated audio.
At some point in the future, I’d like to build upon this work by adding support for enqueuing tracks or defining playlists which let you play a series for tracks in a row.