Flask转推MP4视频在Windows正常,移动端(iOS/Android)无法播放求助
Flask转推MP4视频移动端无法播放的解决方案
问题分析
你的代码仅添加了Accept-Ranges头,但未处理移动端浏览器强制要求的字节范围请求(Range Requests)。移动端浏览器为实现流量优化、进度条控制,会发送Range头请求视频分段数据,而当前代码直接返回完整视频流,未响应这类请求,导致移动端播放器无法正常初始化。
修复后的后端代码
from flask import request, Response import requests from werkzeug.datastructures import Headers # 摄像头与对应MP4流地址映射 camera_mp4_streams = { "Camera 1": "https://www.w3schools.com/html/movie.mp4", } @app.route('/video_feed/<camera>') @login_required def video_feed(camera): mp4_stream_url = camera_mp4_streams.get(camera) if not mp4_stream_url: return "Camera not found", 404 # 获取客户端发送的Range请求头 range_header = request.headers.get('Range', None) req_headers = {} if range_header: req_headers['Range'] = range_header # 向源服务器请求对应范围的视频数据 source_response = requests.get(mp4_stream_url, headers=req_headers, stream=True) resp_headers = Headers() # 复制源服务器关键响应头(仅保留视频播放必需字段) for key, value in source_response.headers.items(): lower_key = key.lower() if lower_key in ['content-type', 'content-range', 'content-length', 'accept-ranges']: resp_headers[key] = value # 使用源服务器返回的状态码(206表示分段响应,200表示完整响应) status_code = source_response.status_code return Response( source_response.iter_content(chunk_size=4096), status=status_code, headers=dict(resp_headers), direct_passthrough=True )
关键修复点
- 响应Range请求:读取客户端发送的
Range头并转发给源服务器,获取指定字节范围的视频数据 - 传递必要响应头:将源服务器返回的
Content-Range、Content-Length等核心头透传给客户端,让移动端播放器能正确解析分段视频 - 遵循HTTP状态码规范:分段请求时返回
206 Partial Content,完整请求时返回200 OK,符合浏览器的播放逻辑要求 - 启用直接流传递:通过
direct_passthrough=True让Flask直接转发源服务器的响应流,避免额外处理导致的兼容性问题
验证方法
可使用curl测试Range请求是否正常响应:
curl -H "Range: bytes=0-1023" http://你的Flask域名/video_feed/Camera1 -I
正常情况下会返回206 Partial Content状态码,且响应头包含Content-Range字段。
(附:Windows与iPhone端显示效果对比图:
)
内容的提问来源于stack exchange,提问作者EDE
相关产品推荐
相关产品推荐

