通过Flask+FFmpeg的方式,将视频流对外发布为HLS流(windows)
FFmpeg介绍
FFmpeg 是一个用于处理视频、音频等多媒体文件的开源工具包。它支持几乎所有的多媒体格式转换、剪辑和编辑,是开发者和多媒体工作者必备的工具。
FFmpeg安装教程(参考:FFmpeg 超级详细安装与配置教程(Windows 系统)_windows安装ffmpeg-CSDN博客)
1. 打开 Dpwnload FFmpeg 官网

2.下滑找到release bulids部分,选择ffmpeg-essentials_build.zip

3. 配置环境变量
进入 bin 目录,可以看到 FFmpeg 的三个核心可执行文件:ffmpeg.exe、ffplay.exe、ffprobe.exe

找到“系统变量”中的 Path 条目并点击“编辑”,输入 FFmpeg 的 bin 文件夹路径

4. 测试安装是否成功
在cmd命令行中输入以下命令查看 FFmpeg 版本,ffmpeg -version

通过opencv读取视频流
import cv2 video_path = r"./pedestrian.mp4" # 初始化视频捕获对象 cap = cv2.VideoCapture(video_path) # 检查视频是否成功打开 if not cap.isOpened(): print(f"Error: 无法打开视频文件 {video_path}") exit() # 获取视频属性 fps = cap.get(cv2.CAP_PROP_FPS) delay = int(1000 / fps) if fps > 0 else 1 # 计算每帧显示延迟时间 try: while True: # 读取视频帧 ret, frame = cap.read() if not ret: # 视频读取结束或发生错误 break # 显示当前帧 cv2.imshow("frame", frame) # 按键检测与退出逻辑 if cv2.waitKey(delay) & 0xFF == ord('q'): break finally: # 确保资源正确释放 cap.release() cv2.destroyAllWindows()
通过flask+ffmpeg将视频流发布为hls流
import cv2 import os import subprocess import threading from flask import Flask, send_from_directory from flask_cors import CORS import time # ================== 配置参数 ================== VIDEO_PATH = "./pedestrian.mp4" # VIDEO_PATH = "rtsp://admin:zdhb2323@192.1.181.191:554/h264/ch1/main/av_stream" HLS_DIR = "hls" FLASK_PORT = 9090 ffmpeg_path = "C:/Software/FFmpeg/ffmpeg-7.0.2-essentials_build/bin/ffmpeg.exe" os.environ["PATH"] += os.pathsep + os.path.dirname(ffmpeg_path) # ================== Flask 静态文件服务 ================== def run_flask_static_server(): app = Flask(__name__) CORS(app) @app.route('/hls/<path:filename>') def serve_hls(filename): if filename.endswith('.m3u8'): return send_from_directory(HLS_DIR, filename, mimetype='application/vnd.apple.mpegurl') elif filename.endswith('.ts'): return send_from_directory(HLS_DIR, filename, mimetype='video/mp2t') else: return send_from_directory(HLS_DIR, filename) @app.route('/') def index(): return 'HLS Streaming Server is Running...' app.run(host='0.0.0.0', port=FLASK_PORT) # ================== 主程序 ================== def main(): os.makedirs(HLS_DIR, exist_ok=True) cap = cv2.VideoCapture(VIDEO_PATH) if not cap.isOpened(): print(f"[错误] 无法打开视频文件: {VIDEO_PATH}") return width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps = str(int(cap.get(cv2.CAP_PROP_FPS) or 25)) # 启动 Flask 静态服务器 threading.Thread(target=run_flask_static_server, daemon=True).start() time.sleep(1) # 启动 FFmpeg 推流进程 hls_output = os.path.join(HLS_DIR, "stream.m3u8") ffmpeg_cmd = [ ffmpeg_path, "-y", "-f", "rawvideo", "-pixel_format", "bgr24", "-video_size", f"{width}x{height}", "-framerate", fps, "-i", "-", "-c:v", "libx264", "-preset", "veryfast", "-f", "hls", "-hls_time", "1", "-hls_list_size", "5", "-hls_flags", "delete_segments", hls_output ] ffmpeg_process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE) try: while True: ret, frame = cap.read() if not ret: print("[警告] 视频读取失败,尝试重新打开视频") cap = cv2.VideoCapture(VIDEO_PATH) continue # 将帧数据写入 FFmpeg 进程的标准输入 ffmpeg_process.stdin.write(frame.tobytes()) except Exception as e: print(f"[错误]: {e}") finally: print("[清理] 正在关闭资源...") cap.release() cv2.destroyAllWindows() ffmpeg_process.stdin.close() ffmpeg_process.wait() if __name__ == "__main__": main()

发布的HLS流地址为:http://192.168.31.164:9090/hls/stream.m3u8(通过PotPlayer打开)


浙公网安备 33010602011771号