如何构建返回视频字节数组的API以在SPA应用中使用pytube
基于pytube构建视频字节流API实现方案
技术栈选择
使用轻量异步Web框架FastAPI搭建后端服务,搭配pytube拉取视频资源,无需本地存储文件即可直接返回字节流供SPA调用。
需提前安装依赖:pip install fastapi uvicorn pytube
核心接口实现
from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import StreamingResponse from pytube import YouTube from io import BytesIO app = FastAPI() # 跨域配置,生产环境请将allow_origins替换为你的SPA实际域名,不要使用* app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/api/video/{video_id}") def get_video_stream(video_id: str, resolution: str = "720p"): try: yt = YouTube(f"https://www.youtube.com/watch?v={video_id}") # 优先匹配指定分辨率的MP4格式流 video_stream = yt.streams.filter(res=resolution, file_extension="mp4", progressive=True).first() if not video_stream: # 无指定分辨率时自动降级到最高可用分辨率 video_stream = yt.streams.filter(file_extension="mp4", progressive=True).order_by("resolution").desc().first() if not video_stream: raise HTTPException(status_code=404, detail="无可用视频流") # 将视频写入内存字节缓冲区,无需落盘 buffer = BytesIO() video_stream.stream_to_buffer(buffer) buffer.seek(0) return StreamingResponse( buffer, media_type="video/mp4", # 需要直接播放时将attachment改为inline headers={"Content-Disposition": f"attachment; filename={yt.title}.mp4"} ) except Exception as e: raise HTTPException(status_code=500, detail=f"拉取视频失败:{str(e)}")
服务启动
执行命令启动后端服务:uvicorn main:app --host 0.0.0.0 --port 8000
SPA调用方式
- 下载功能:直接将接口地址赋值给a标签的href属性,搭配download属性即可触发下载:
<a href="http://你的后端地址/api/video/视频ID?resolution=1080p" download>下载视频</a> - 播放功能:直接将接口地址填入video标签的src属性即可实现边加载边播放:
<video src="http://你的后端地址/api/video/视频ID?resolution=720p" controls></video>
注意事项
- 生产环境必须收紧CORS规则,禁止开放所有来源访问
- 可按需添加请求限流、视频缓存、身份校验逻辑,降低带宽消耗和接口被滥用的风险
- pytube偶尔会因为YouTube接口规则更新失效,及时更新到pytube最新版本即可修复
内容的提问来源于stack exchange,提问作者Diego Zumárraga Mera
相关产品推荐
相关产品推荐

