Fix Choppy streaming
This commit is contained in:
1 parent
676a52199c
commit
1d447fdba4
1 file changed
+44
-2
@@ -1,9 +1,10 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from flask import Flask, abort, render_template, send_file
|
||||
from flask import Flask, Response, abort, render_template, request
|
||||
|
||||
load_dotenv()
|
||||
|
||||
@@ -51,7 +52,48 @@ def play(path):
|
||||
@app.route("/video/<path:path>")
|
||||
def serve_video(path):
|
||||
full = _validate_path(path)
|
||||
return send_file(full, mimetype="video/mp4")
|
||||
file_size = full.stat().st_size
|
||||
range_header = request.headers.get("Range")
|
||||
|
||||
if not range_header:
|
||||
return _stream_file(full, 0, file_size - 1, file_size, 200)
|
||||
|
||||
match = re.match(r"bytes=(\d+)-(\d*)", range_header)
|
||||
if not match:
|
||||
abort(416)
|
||||
|
||||
start = int(match.group(1))
|
||||
end_str = match.group(2)
|
||||
end = int(end_str) if end_str else file_size - 1
|
||||
|
||||
if start >= file_size or end >= file_size or start > end:
|
||||
abort(416)
|
||||
|
||||
content_length = end - start + 1
|
||||
return _stream_file(full, start, end, content_length, 206)
|
||||
|
||||
|
||||
def _stream_file(path, start, end, content_length, status):
|
||||
def generate():
|
||||
with open(path, "rb") as f:
|
||||
f.seek(start)
|
||||
remaining = content_length
|
||||
while remaining > 0:
|
||||
chunk_size = min(8192, remaining)
|
||||
data = f.read(chunk_size)
|
||||
if not data:
|
||||
break
|
||||
remaining -= len(data)
|
||||
yield data
|
||||
|
||||
file_size = path.stat().st_size
|
||||
headers = {
|
||||
"Content-Range": f"bytes {start}-{end}/{file_size}",
|
||||
"Accept-Ranges": "bytes",
|
||||
"Content-Length": str(content_length),
|
||||
"Content-Type": "video/mp4",
|
||||
}
|
||||
return Response(generate(), status=status, headers=headers)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in new issue
Block a user