You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flask中流式传输10分钟视频?实现无需全量下载即可播放

嘿,这个需求我之前做项目的时候刚好碰到过,其实核心就是让你的Flask应用支持HTTP范围请求(Range Requests)——这是浏览器实现流式播放的关键,而Flask自带的开发服务器默认不处理这个逻辑,所以换WSGI服务器是必要的,下面给你一步步捋清楚怎么做:

核心原理:为什么开发服务器不行?

浏览器要实现“边看边加载”,会向服务器发送带Range头的请求,指定要获取视频的某一段内容(比如从第1000字节到第5000字节)。但Flask的开发服务器只是用来调试的轻量服务,它会直接返回整个视频文件,不会处理Range请求,所以用户必须等完整视频下载完才能播放。

而生产级的WSGI服务器(比如Gunicorn、uWSGI)本身支持HTTP标准的范围请求处理,再配合我们在Flask里的逻辑,就能实现流式播放。

第一步:让Flask支持范围请求

你可以手动实现范围请求的处理逻辑,也可以用现成的扩展,这里给你一个手动实现的示例(更灵活,不用依赖额外包):

from flask import Flask, request, Response
import os

app = Flask(__name__)

# 替换成你的视频文件路径
VIDEO_FILE = "./static/videos/your_10min_video.mp4"

def parse_range_header(range_header, file_size):
    """解析Range请求头,计算要返回的字节范围"""
    if not range_header:
        return 0, file_size - 1
    
    # 拆分Range头(格式类似:bytes=0-1024)
    range_part = range_header.strip().split("=")[1]
    start_str, end_str = range_part.split("-")
    
    start = int(start_str) if start_str else 0
    end = int(end_str) if end_str else file_size - 1
    
    # 处理超出文件大小的情况
    if end >= file_size:
        end = file_size - 1
    
    return start, end

@app.route("/stream-video")
def stream_video():
    file_size = os.path.getsize(VIDEO_FILE)
    range_header = request.headers.get("Range")
    start, end = parse_range_header(range_header, file_size)
    content_length = end - start + 1

    # 读取视频对应片段
    with open(VIDEO_FILE, "rb") as f:
        f.seek(start)
        video_segment = f.read(content_length)

    # 设置响应头,告诉浏览器这是分段内容
    headers = {
        "Content-Range": f"bytes {start}-{end}/{file_size}",
        "Accept-Ranges": "bytes",
        "Content-Length": str(content_length),
        "Content-Type": "video/mp4",
    }

    # 返回206 Partial Content响应
    return Response(video_segment, status=206, headers=headers)

if __name__ == "__main__":
    # 开发服务器仅用于测试,生产环境别用!
    app.run(debug=True)
第二步:部署到WSGI服务器

推荐用Gunicorn,它简单易用,是Flask生产部署的常用选择:

  1. 安装Gunicorn:
pip install gunicorn
  1. 启动服务(假设你的Flask app文件名为app.py):
# 4个工作进程,绑定到5000端口
gunicorn --workers 4 --bind 0.0.0.0:5000 app:app

如果你的视频访问量比较大,建议再配合Nginx做反向代理,Nginx处理静态文件的效率比Flask高很多,甚至可以让Nginx直接托管视频文件,Flask只处理动态逻辑。给你一个简单的Nginx配置示例:

server {
    listen 80;
    server_name your-domain.com;

    # 动态请求转发给Gunicorn
    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    # 让Nginx直接托管视频文件,自动处理范围请求
    location /videos {
        root /path/to/your/static/folder;
        add_header Accept-Ranges bytes;
        add_header Content-Type video/mp4;
    }
}
额外注意事项
  • 视频格式:确保你的视频是MP4(H.264编码)这种支持流式播放的格式,AVI等格式不支持分段加载。
  • 文件权限:确保WSGI服务器进程(比如Gunicorn的运行用户)有读取视频文件的权限。
  • 测试验证:部署后用浏览器访问/stream-video,拖动进度条,如果能直接跳转到对应位置播放,就说明成功了。

内容的提问来源于stack exchange,提问作者cubecubed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:11:19