1

I'm trying to provide audio to the HTML Django template, originally I tried like this:

<audio id="audio" src="{{audio_path}}" controls></audio>

This was sufficient to get audio playing on the website with pause/play, speed up/down, volume up/down but the user was not able to move the progress bar at all, it either froze, or returned to the starting position.

I did lots of searching and found many things that claimed to enable seeking/scrubbing, but none of them have worked. Currently my code is as follows, first the audio API view:

class AudioFetchView(View):
    def get(self, request, audio_id, *args, **kwargs):
        audio_file = UploadAudio.objects.get(pk=audio_id)

        response = StreamingHttpResponse(content_type='audio/mpeg')
        response['Content-Disposition'] = 'attachment; filename=%s' % audio_file.path
        response['Accept-Ranges'] = 'bytes'
        response['X-Sendfile'] = audio_file.path
        return response

audio_fetch = AudioFetchView.as_view()

Then the HTML:

<audio id="audio" crossOrigin="anonymous" preload="auto" src="{{audio_fetch_url}}"></audio>

Now the audio is not able to be played at all, the error message is: "Uncaught (in promise) DOMException: The element has no supported sources."

Does anyone know how to correctly provide an .mp3 file to the frontend in a way that allows scrubbing/seeking?

Josh
  • 257
  • 1
  • 13
  • 1
    What do you see if you open the network inspector? Some people are saying they've had similar issues and it was related to CORS. https://stackoverflow.com/a/43434754/2896976 – Jessie Jan 04 '22 at 05:58
  • I've set crossOriginn="anonymous", it seems like that's all the link is saying to do – Josh Jan 04 '22 at 16:44

1 Answers1

1

I have no idea why this worked, but my code is now working like this:

class AudioFetchView(View):
def get(self, request, audio_id, *args, **kwargs):
    audio_file = UploadAudio.objects.get(pk=audio_id)

    with open(audio_file.absolute_path, 'rb') as fh:
        response = HttpResponse(fh.read(), content_type='audio/mpeg')
        response['Content-Disposition'] = 'attachment; filename=%s' % audio_file.path
        response['Accept-Ranges'] = 'bytes'
        response['X-Sendfile'] = audio_file.path
        response['Content-Length'] = os.path.getsize(audio_file.absolute_path)
    return response

audio_fetch = AudioFetchView.as_view()

HTML:

<audio id="audio" src={{audio_fetch_url}} type="audio/mpeg"> </audio>

Figured I'd post in case anyone finds this in the future.

Josh
  • 257
  • 1
  • 13