Django 에서 스 트림 응답 으로 동 영상 을 처리 하 는 방법

시작 하 다
html 5 의<video>탭 을 이용 하여 재생 할 수 있 습 니 다.

<video width="320" height="240" controls>
 <source src="/static/video/demo.mp4" type="video/mp4">
         Video  。
</video>
그러나 이러한 방식 으로 는 동 영상 에 있 는 진도 바 를 사용 할 수 없고 정적 파일 로 돌아 가면 배경 프로그램 이 많은 메모 리 를 차지 합 니 다.
응답 흐름 방식 을 사용 하면 이 두 문 제 를 잘 해결 할 수 있다.
StreamingHttpResponse
대부분의 Django 응답 사용HttpResponse.이것 은 응답 하 는 주체 가 메모리 에 내장 되 어 있 고 단일 형식 으로 HTTP 클 라 이언 트 에 보 내 는 것 을 의미한다.반면StreamingHttpResponse방식 으로chunks(일부 블록)방식 으로 되 돌아 갈 수 있다.아주 간단 한 예 는:

from django.http import StreamingHttpResponse

def hello():
  yield 'Hello,'
  yield 'there!'

def test(request):
  return StreamingHttpResponse(hello)
WSGI프로 토 콜 에 따 르 면 서버 가 호출 될 때 응용 프로그램 대상 은 교체 가능 한 0 개 이상 의 바이트 문자열 을 만들어 야 합 니 다.따라서 우 리 는 서버 에 생 성 기 를 제공 함으로써 흐름 응답 기능 을 완성 할 수 있다.
흔히 볼 수 있 는 사용StreamingHttpResponse은 일부 큰 파일 의 다운로드 등 으로 정지점 전송 기능 도 완성 할 수 있다.
비디오 스 트림
비디오 스 트림 을 사용 할 때 요청 머리 에서 시작 바이트 수 를 얻 을 수 있 습 니 다.

이 필드 는 브 라 우 저가 자동 으로 제공 하 는 것 같 습 니 다.html 코드 에서 저 는 동 영상src의 정적 주소 에서 경로 방식 으로 바 꾸 기만 하면 됩 니 다.응답 체 에 대해 서도 응답 체 가 되 돌아 오 는 블록의 범 위 를 제공 해 야 합 니 다.
Content-Range는 각각 - / 을 표 시 했 고 이 응답 체 의 내용 은 파일 의 해당 범위 내의 내용 을 포함 했다.비디오 스 트림 을 처리 하 는 코드 는 다음 과 같 습 니 다.

import re
import os
from wsgiref.util import FileWrapper
from django.http import StreamingHttpResponse

def file_iterator(file_name, chunk_size=8192, offset=0, length=None):
  with open(file_name, "rb") as f:
    f.seek(offset, os.SEEK_SET)
    remaining = length
    while True:
      bytes_length = chunk_size if remaining is None else min(remaining, chunk_size)
      data = f.read(bytes_length)
      if not data:
        break
      if remaining:
        remaining -= len(data)
      yield data

def stream_video(request, path):
  """              """
  range_header = request.META.get('HTTP_RANGE', '').strip()
  range_re = re.compile(r'bytes\s*=\s*(\d+)\s*-\s*(\d*)', re.I)
  range_match = range_re.match(range_header)
  size = os.path.getsize(path)
  content_type, encoding = mimetypes.guess_type(path)
  content_type = content_type or 'application/octet-stream'
  if range_match:
    first_byte, last_byte = range_match.groups()
    first_byte = int(first_byte) if first_byte else 0
    last_byte = first_byte + 1024 * 1024 * 8    # 8M   ,       
    if last_byte >= size:
      last_byte = size - 1
    length = last_byte - first_byte + 1
    resp = StreamingHttpResponse(file_iterator(path, offset=first_byte, length=length), status=206, content_type=content_type)
    resp['Content-Length'] = str(length)
    resp['Content-Range'] = 'bytes %s-%s/%s' % (first_byte, last_byte, size)
  else:
    #             ,            ,    
    resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
    resp['Content-Length'] = str(size)
  resp['Accept-Ranges'] = 'bytes'
  return resp
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기