[레트로플릭스] 스트리밍..?

seonghyeon·2022년 2월 8일
0

프로젝트가 끝나기 하루전 결국 어째저째 스트리밍을 구현했다.
원리만 간단히 보자면 전달 받은 데이터를 쪼개서 장고에 StreamingHttpResponse로 전달 해주는 것이다.
구글링을통해 각종 소스 코드들을 모아봤고 결국 다 똑같아서 채용해서 사용해보기로했다.

Class RangeFileWrapper(object):

	#blksize = 데이터를 쪼갤 block사이즈
    #offset = 파일을 읽는 시작점
    def __init__(self, filelike, blksize=10240, offset=0, length=None):
        self.filelike = filelike
        #python seek를 이용하여서 파일을 쪼개 읽는다(라고한다 seek에대한 공부 필요)
        self.filelike.seek(offset, os.SEEK_SET)
        self.remaining = length
        self.blksize = blksize

    def close(self):
        if hasattr(self.filelike, 'close'):
            self.filelike.close()

    def __iter__(self):
        return self

    def __next__(self):
        if self.remaining is None:
            # If remaining is None, we're reading the entire file.
            data = self.filelike.read(self.blksize)
            if data:
                return data
            raise StopIteration()
        else:
            if self.remaining <= 0:
                raise StopIteration()
            data = self.filelike.read(min(self.remaining, self.blksize))
            if not data:
                raise StopIteration()
            self.remaining -= len(data)
            return data


def stream(request):
    range_header = request.META.get('HTTP_RANGE', '').strip()
    range_match = range_re.match(range_header)
    size = os.path.getsize('movie/video1.mp4')
    content_type, encoding = mimetypes.guess_type('movie/video1.mp4')
    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 = int(last_byte) if last_byte else size - 1
        if last_byte >= size:
            last_byte = size - 1
        length = last_byte - first_byte + 1
        resp = StreamingHttpResponse(RangeFileWrapper(open('movie/video1.mp4', 'rb'), 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('movie/video1.mp4', 'rb')), content_type=content_type)
        resp['Content-Length'] = str(size)
    resp['Accept-Ranges'] = 'bytes'
    return resp

seek와 iteration을 얼른 공부해서 추가적으로 이해가 필요할거같다

결과적으로 급한대로 쓰긴했지만 추가적으로 공부를하여 완벽하게 이해를 하지못하면
의미가 없을거같아서 따로 또 공부해볼 필요가있는 기능인거 같아 보인다
영상뿐아니라 큰 사이즈의 csv 파일이나 음악 스트리밍역시 이기능을 사용한다면 꼭
알고 넘어가야할 중요한 기능이라 생각함

0개의 댓글