Django Streaming Video / Audio - RangedFileResponse

Folks,

For ages I've been using RangedFileResponse to enable streaming (particularly with Safari), but to allow ranged streaming with Django. (Please note, it's been forked quite heavily, the one I've been using is from https://github.com/devmonkey22/django-ranged-fileresponse.

Now, I've been always wondering if there was a more up-to-date way to do this, since there hasn't seemed to be a better answer?

I just recently started to use django-extensions more fully, and bumped into the Werkzeug extensions (from Django-Extensions) when I enabled SSL for the Dev environment.

But I also found that Werkzeug can help with the Ranged file response.

This is what I came up with, and it seems to be faster than using the django-ranged-fileresponse. Sometimes significantly faster.


from werkzeug.http import parse_range_header
from django.http import FileResponse, HttpResponseNotAllowed, HttpResponseBadRequest


def stream_video(request, fqpn, content_type="video/mp4"):

    file_size = os.path.getsize(fqpn)
    if request.method != 'GET':
        return HttpResponseNotAllowed(['GET'])

    if request.is_secure():
        range_header = request.META.get('HTTPS_RANGE')
    else:
        range_header = request.META.get('HTTP_RANGE')

    ranges = parse_range_header(range_header)
    if not ranges:
        return FileResponse(open(fqpn, 'rb'))
    
    # For simplicity, handle only single range requests
    start, end = ranges[0]
    with open(fqpn, 'rb') as file_to_send:
        file_to_send.seek(start)
        data = file_to_send.read(end - start + 1)

    response = FileResponse(data, content_type='application/octet-stream')
    response['Content-Length'] = len(data)
    response['Content-Range'] = f'bytes {start}-{end}/{file_size}'
    response['Accept-Ranges'] = 'bytes'
    response.status_code = 206  # Partial Content
    return response

I've kicked the wheels on this, and it seems to be working as a viable replacement.

Does anyone have any suggestions for improvements?

Вернуться на верх