如何用Python以MP4格式流传输摄像头视频至Unreal Engine 4?
实现Python摄像头H.264/MP4流式传输给UE4
我来帮你搞定这个问题——UE4不支持MJPEG确实挺头疼的,不过我们可以用FFmpeg做实时H.264编码,配合Flask输出碎片化MP4流(Fragmented MP4),这种格式支持边传输边播放,刚好适配UE4的MediaPlayer组件。下面是具体的实现步骤和代码:
1. 安装依赖
首先得装好需要的库和工具:
- 用pip安装Python依赖:
pip install flask opencv-python ffmpeg-python - 确保你的系统里已经安装了FFmpeg(
ffmpeg-python是Python封装,底层还是需要FFmpeg二进制文件,Windows/macOS/Linux都可以通过包管理器或官网下载安装)。
2. Flask服务实现(实时编码MP4流)
下面是完整的Flask服务代码,核心是用FFmpeg把摄像头帧编码成可流式的MP4:
from flask import Flask, Response import cv2 import ffmpeg import numpy as np app = Flask(__name__) # 摄像头参数(根据你的设备调整) CAMERA_INDEX = 0 WIDTH = 1280 HEIGHT = 720 FPS = 30 def generate_mp4_stream(): # 初始化摄像头 cap = cv2.VideoCapture(CAMERA_INDEX) cap.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT) cap.set(cv2.CAP_PROP_FPS, FPS) if not cap.isOpened(): raise RuntimeError("无法打开摄像头") # 配置FFmpeg编码参数:生成碎片化MP4 ffmpeg_process = ( ffmpeg .input('pipe:', format='rawvideo', pix_fmt='bgr24', s=f'{WIDTH}x{HEIGHT}', r=FPS) .output('pipe:', format='mp4', vcodec='libx264', pix_fmt='yuv420p', b='2M', movflags='frag_keyframe+empty_moov+faststart') .overwrite_output() .run_async(pipe_stdin=True, pipe_stdout=True) ) try: while True: ret, frame = cap.read() if not ret: break # 把OpenCV的BGR帧传给FFmpeg ffmpeg_process.stdin.write(frame.tobytes()) # 读取FFmpeg输出的MP4片段,发给客户端 chunk = ffmpeg_process.stdout.read(1024*1024) # 按1MB块读取 if not chunk: break yield chunk finally: cap.release() ffmpeg_process.stdin.close() ffmpeg_process.wait() @app.route('/stream') def stream(): # 设置响应头:指定MIME类型为MP4,允许跨域(如果UE4和Flask不在同一机器的话) return Response( generate_mp4_stream(), mimetype='video/mp4', headers={ 'Access-Control-Allow-Origin': '*', 'Content-Type': 'video/mp4' } ) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, threaded=True)
3. 关键参数解释
movflags='frag_keyframe+empty_moov+faststart':这是实现流式MP4的核心,frag_keyframe让每个关键帧生成一个MP4片段,empty_moov把MP4的元数据放在开头,faststart确保播放器可以立即开始播放。vcodec='libx264':指定用H.264编码,UE4原生支持这个编码格式。pix_fmt='yuv420p':兼容几乎所有播放器,包括UE4的MediaPlayer。
4. UE4端配置步骤
- 在UE4中创建一个
MediaPlayer资产,然后创建对应的URL Media Source。 - 在URL Media Source中填入Flask服务的地址,比如
http://你的Flask机器IP:5000/stream。 - 把MediaPlayer的输出纹理绑定到一个材质上,再将材质应用到场景中的平面或模型上。
- 运行UE4项目,播放MediaPlayer,就能看到摄像头的实时流了。
注意事项
- 如果摄像头帧率不稳定,可以调整FFmpeg的
r参数或者OpenCV的CAP_PROP_FPS,确保两者匹配。 - 比特率
b='2M'可以根据网络情况调整,网络差的话降低比特率,反之可以提高。 - 如果UE4播放时出现卡顿,检查Flask服务的CPU占用(H.264编码比较耗CPU,低性能机器可以降低分辨率)。
内容的提问来源于stack exchange,提问作者Duncan De Weireld




