Forums

Audio file seeking not working on Chrome

I'm working on a personal website, and one of the things on there is my music. But, on chrome, seeking to any point in the audio file except the start will just jump back to the current point. Also, the displayed length of the song is too short and increases to the full length as playback nears the end.

After playing the song to the end and reloading the page, the seeking starts working, but it breaks again when I clear my cache. Neither issue occurs on Firefox, or when I access the audio file URL directly.

I think this problem is because seeking in Chrome requires the server to respond with partial clips from the audio file, in something called a 'range request'. After playing the whole file and reloading, the whole file is buffered in the cache, and Chrome must have a special case for this where the user can seek to anywhere.

In the issue https://www.pythonanywhere.com/forums/topic/3083/ (which I would have responded to, but I don't think I can since the EU forum is separate), you say that the PythonAnywhere server doesn't support range requests. You suggest creating a custom audio player element that limits seeking to the buffered audio. Based on the article https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Audio_and_video_delivery/buffering_seeking_time_ranges I think I would be able to do this, but I'm hesitant to spend time on that, because:

  • wouldn't that mean the user is still unable to seek to later parts of the song?
  • if Chrome allowed seeking to any buffered audio, surely the user would be able to seek to previously played parts of the song without having to play the whole thing and reload first?
  • would a custom element that is explicitly able to seek to buffered audio get around this?

I think it would work if I buffered the entire audio file beforehand when using Chrome: is that possible? Or is there a response configuration the PythonAnywhere server uses when accessing the URL directly, which I could apply to my endpoint? Please advise.

The issue with range requests for static files is that the range headers are not processed by the static files system. If you implemented that yourself, then you would be delivering the parts of the file that Chrome is requesting and seeking should work.

Also, if Chrome can seek within the cached file that is downloaded, then forcing the browser to download the entire file first should ensure that it can seek within the cached file. Whether that works without requiring a reload is something that you will need to determine by experiment.

OK, thank you for your assistance. As far as I can tell, I don't have control over when the browser caches the file, only whether it does and for how long. So I might have to create an endpoint for audio files that responds to range requests.

I also found something in the documentation about Data URLs, which I could use to put the audio file into the document as Base64. Then, no range request would be required. Since I can generate the Base64 files beforehand, that might perform better too... though it would be an awful lot of text in the template, and I don't want to do anything too unconventional.

Will get back when I get something working.

Great, good luck and let us know!

After giving the project a break for a while, it was easier than I thought to set up an endpoint. I thought I'd have to parse the HTTP request manually and use pydub to get the right bytes from the audio file, but then I found that flask.send_file() has a conditional parameter, which can be set to True to automatically account for any range requests in flask.request. After setting that up, the seeking and length work fine in Chrome and Firefox, regardless of the cache.

Thank you for your help!

Excellent, thanks for sharing!