如何在 Flask 中流式传输大视频
How do I stream large videos in Flask
我有 10 分钟的视频,我希望能够从我的 Flask 网站流式传输。我该怎么做才能让用户不必下载整个视频就可以播放?我目前通过开发服务器 运行 应用程序,因为它仅用于个人项目。但是,如果 运行 通过实际的 WSGI 可以解决问题,那么我愿意这样做。
如果是摄像头,则必须使用 generator-based code taking into consideration efficiency as in this demo. Here is the for streaming demo improved from here:
首先你需要使用生成器(yield 语句)以块的形式给出视频文件
def get_chunk(filename, byte1=None, byte2=None):
filesize = os.path.getsize(filename)
yielded = 0
yield_size = 1024 * 1024
if byte1 is not None:
if not byte2:
byte2 = filesize
yielded = byte1
filesize = byte2
with open(filename, 'rb') as f:
content = f.read()
while True:
remaining = filesize - yielded
if yielded == filesize:
break
if remaining >= yield_size:
yield content[yielded:yielded+yield_size]
yielded += yield_size
else:
yield content[yielded:yielded+remaining]
yielded += remaining
然后根据要求流式传输文件:
@app.route('/')
def get_file():
filename = 'try2.mp4'
filesize = os.path.getsize(filename)
range_header = flask_request.headers.get('Range', None)
if range_header:
byte1, byte2 = None, None
match = re.search(r'(\d+)-(\d*)', range_header)
groups = match.groups()
if groups[0]:
byte1 = int(groups[0])
if groups[1]:
byte2 = int(groups[1])
if not byte2:
byte2 = byte1 + 1024 * 1024
if byte2 > filesize:
byte2 = filesize
length = byte2 + 1 - byte1
resp = Response(
get_chunk(filename, byte1, byte2),
status=206, mimetype='video/mp4',
content_type='video/mp4',
direct_passthrough=True
)
resp.headers.add('Content-Range',
'bytes {0}-{1}/{2}'
.format(byte1,
length,
filesize))
return resp
return Response(
get_chunk(),
status=200, mimetype='video/mp4'
)
添加所需的 headers
@app.after_request
def after_request(response):
response.headers.add('Accept-Ranges', 'bytes')
return response
您需要将视频处理成自适应比特率格式(如 Apple HLS),然后像托管任何其他静态资产一样托管它们。像 S3 之类的东西。 FFMPEG 或 AWS MediaConvert 可用于处理。然后使用 video.js 之类的视频播放器并将其指向您的 .m3u8 清单和您的集合。
免责声明 - 我受雇于提供上述部分服务的 AWS
我有 10 分钟的视频,我希望能够从我的 Flask 网站流式传输。我该怎么做才能让用户不必下载整个视频就可以播放?我目前通过开发服务器 运行 应用程序,因为它仅用于个人项目。但是,如果 运行 通过实际的 WSGI 可以解决问题,那么我愿意这样做。
如果是摄像头,则必须使用 generator-based code taking into consideration efficiency as in this demo. Here is the for streaming demo improved from here:
首先你需要使用生成器(yield 语句)以块的形式给出视频文件
def get_chunk(filename, byte1=None, byte2=None):
filesize = os.path.getsize(filename)
yielded = 0
yield_size = 1024 * 1024
if byte1 is not None:
if not byte2:
byte2 = filesize
yielded = byte1
filesize = byte2
with open(filename, 'rb') as f:
content = f.read()
while True:
remaining = filesize - yielded
if yielded == filesize:
break
if remaining >= yield_size:
yield content[yielded:yielded+yield_size]
yielded += yield_size
else:
yield content[yielded:yielded+remaining]
yielded += remaining
然后根据要求流式传输文件:
@app.route('/')
def get_file():
filename = 'try2.mp4'
filesize = os.path.getsize(filename)
range_header = flask_request.headers.get('Range', None)
if range_header:
byte1, byte2 = None, None
match = re.search(r'(\d+)-(\d*)', range_header)
groups = match.groups()
if groups[0]:
byte1 = int(groups[0])
if groups[1]:
byte2 = int(groups[1])
if not byte2:
byte2 = byte1 + 1024 * 1024
if byte2 > filesize:
byte2 = filesize
length = byte2 + 1 - byte1
resp = Response(
get_chunk(filename, byte1, byte2),
status=206, mimetype='video/mp4',
content_type='video/mp4',
direct_passthrough=True
)
resp.headers.add('Content-Range',
'bytes {0}-{1}/{2}'
.format(byte1,
length,
filesize))
return resp
return Response(
get_chunk(),
status=200, mimetype='video/mp4'
)
添加所需的 headers
@app.after_request
def after_request(response):
response.headers.add('Accept-Ranges', 'bytes')
return response
您需要将视频处理成自适应比特率格式(如 Apple HLS),然后像托管任何其他静态资产一样托管它们。像 S3 之类的东西。 FFMPEG 或 AWS MediaConvert 可用于处理。然后使用 video.js 之类的视频播放器并将其指向您的 .m3u8 清单和您的集合。
免责声明 - 我受雇于提供上述部分服务的 AWS