如何通过Python Flask与JS实现视频流源切换?
实现客户端切换视频流的方案
1. 修改服务端路由,支持指定视频源
现有服务端代码固定返回movies_list[0]的视频,需要修改路由,让它能接收客户端传来的视频标识,比如视频索引或者文件名,然后返回对应视频的流。
修改后的服务端代码:
import os import re from flask import request, current_app movies_list = ['./mov1.mp4', './mov2.mp4', './mov3.mp4'] @app.route("/video", methods=["GET"]) def video(): headers = request.headers if not "range" in headers: return current_app.response_class(status=400) # 获取客户端传来的视频索引参数,默认用0 movie_idx = request.args.get("idx", default=0, type=int) # 校验索引是否合法 if movie_idx < 0 or movie_idx >= len(movies_list): return current_app.response_class("Invalid video index", status=404) video_path = os.path.abspath(os.path.join("media", movies_list[movie_idx])) # 校验文件是否存在 if not os.path.exists(video_path): return current_app.response_class("Video not found", status=404) size = os.stat(video_path).st_size chunk_size = 3 * 10**6 # 3MB 分片大小 start = int(re.sub("\D", "", headers["range"])) end = min(start + chunk_size, size - 1) content_length = end - start + 1 def get_chunk(video_path, start, chunk_size): with open(video_path, "rb") as f: f.seek(start) return f.read(chunk_size) response_headers = { "Content-Range": f"bytes {start}-{end}/{size}", "Accept-Ranges": "bytes", "Content-Length": content_length, "Content-Type": "video/mp4", } return current_app.response_class( get_chunk(video_path, start, chunk_size), status=206, headers=response_headers )
说明:
- 添加了
idx查询参数,客户端可以通过/video?idx=0、/video?idx=1指定要播放的视频 - 增加了索引合法性校验和文件存在校验,避免无效请求
2. 修改客户端HTML,添加切换按钮并实现切换逻辑
在客户端页面添加切换按钮,点击时修改video元素的src属性,带上对应的视频索引参数,然后重新加载并播放视频。
修改后的客户端代码:
<video id="videoPlayer" width="720" controls> <source src="/video?idx=0" type="video/mp4"> </video> <div> <button onclick="switchVideo(0)">播放视频1</button> <button onclick="switchVideo(1)">播放视频2</button> <button onclick="switchVideo(2)">播放视频3</button> </div> <script> function switchVideo(idx) { const videoPlayer = document.getElementById('videoPlayer'); // 修改source的src属性,带上视频索引参数 const source = videoPlayer.querySelector('source'); source.src = `/video?idx=${idx}`; // 重新加载视频并播放 videoPlayer.load(); videoPlayer.play(); } </script>
说明:
- 给video元素添加了id,方便JS获取
- 添加了三个切换按钮,分别对应movies_list里的三个视频
switchVideo函数负责修改source的src,调用load()重新加载资源,play()自动开始播放
3. 其他可选方案(按文件名切换)
如果不想用索引,也可以通过文件名指定视频,修改服务端逻辑如下:
服务端修改部分:
@app.route("/video", methods=["GET"]) def video(): headers = request.headers if not "range" in headers: return current_app.response_class(status=400) # 获取文件名参数 movie_name = request.args.get("name") if not movie_name or movie_name not in movies_list: return current_app.response_class("Invalid video name", status=404) video_path = os.path.abspath(os.path.join("media", movie_name)) if not os.path.exists(video_path): return current_app.response_class("Video not found", status=404) # 后续逻辑和之前一致...
客户端切换函数修改:
function switchVideoByName(name) { const videoPlayer = document.getElementById('videoPlayer'); const source = videoPlayer.querySelector('source'); source.src = `/video?name=${name}`; videoPlayer.load(); videoPlayer.play(); }
对应的按钮:
<button onclick="switchVideoByName('mov1.mp4')">播放视频1</button> <button onclick="switchVideoByName('mov2.mp4')">播放视频2</button>
内容的提问来源于stack exchange,提问作者Oleksandr
相关产品推荐
相关产品推荐

