低功耗嵌入式设备:如何用API获取的JPEG截图生成MPEG/MJPEG视频流?
当然可以!这其实是低功耗嵌入式设备没法跑VNC这类重型桌面共享服务时的常用解决方案,我给你梳理下具体实现思路和避坑要点:
核心思路拆解
本质就是把连续的截图帧,通过工具拼接成可播放的视频流——核心分两步:持续拉取截图,再把帧转成流。
1. 写个轻量的截图拉取脚本
你需要一个运行在客户端的小脚本,定时调用设备的截图API。比如用Python写就很简单,兼顾跨平台和易维护性:
import requests import time from requests.exceptions import RequestException API_URL = "http://你的设备IP/截图接口路径" FRAME_RATE = 3 # 和设备API的输出频率匹配,2-3帧/秒 while True: try: # 拉取截图,确保获取到完整的图片数据 resp = requests.get(API_URL, timeout=2) resp.raise_for_status() # 这里可以直接把图片数据传给视频编码工具,或者先临时存到本地 with open(f"temp_frame_{int(time.time()*1000)}.jpg", "wb") as f: f.write(resp.content) time.sleep(1/FRAME_RATE) # 控制请求间隔,别给设备加额外负担 except RequestException as e: print(f"拉取截图失败:{e},1秒后重试") time.sleep(1)
如果是Linux客户端,用bash+curl循环也能搞定,适合轻量场景。
2. 用FFmpeg把截图转成视频流
FFmpeg是处理这类帧转流场景的神器,支持实时转流和事后合成两种模式:
模式一:实时生成直播流(比如HLS/RTSP)
适合需要实时观看的场景,直接把拉取到的截图帧喂给FFmpeg编码:
import requests import subprocess import time API_URL = "http://你的设备IP/截图接口路径" FRAME_RATE = 3 # FFmpeg命令:从标准输入读取图片帧,转成HLS直播流 ffmpeg_cmd = [ "ffmpeg", "-f", "image2pipe", "-r", str(FRAME_RATE), "-i", "-", # 从标准输入读取数据 "-c:v", "libx264", "-preset", "ultrafast", # 优先低延迟,适合实时场景 "-tune", "zerolatency", "-f", "hls", "-hls_time", "2", # 每个切片的时长 "-hls_list_size", "5", # 保留最近5个切片 "./live_stream.m3u8" ] # 启动FFmpeg进程 proc = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE) try: while True: resp = requests.get(API_URL, timeout=2) resp.raise_for_status() # 把图片数据写入FFmpeg的标准输入 proc.stdin.write(resp.content) proc.stdin.flush() time.sleep(1/FRAME_RATE) except KeyboardInterrupt: proc.stdin.close() proc.wait()
生成的live_stream.m3u8可以用浏览器或者播放器直接打开观看。
模式二:事后合成本地视频
如果不需要实时观看,先把所有截图按顺序保存到目录,再用FFmpeg批量合成:
# 假设截图命名为frame_0001.jpg、frame_0002.jpg... ffmpeg -framerate 3 -i frame_%04d.jpg -c:v libx264 -r 30 -crf 23 output.mp4
-crf 23是视频质量参数,数值越小质量越高,23是默认的平衡值。
3. 针对低功耗设备的优化要点
毕竟是低功耗设备,别给它加额外负担:
- 让API返回压缩后的JPG格式(别用PNG,体积大),质量设为70-80即可,兼顾清晰度和传输量
- 严格控制请求频率,就按设备能承受的2-3帧/秒来,别多请求
- 所有编码、压缩工作都交给客户端/流媒体服务器,设备只负责生成原始截图并通过API返回
常见坑点规避
- 帧率不稳定:如果API响应有波动,用FFmpeg的
-vsync cfr参数强制恒定帧率,避免播放时卡顿 - 图片格式/分辨率不一致:确保设备每次返回的截图分辨率、格式完全一致,不然FFmpeg会报错
- 网络波动:客户端一定要加重试机制,遇到请求失败时别直接崩溃,等几秒再重试
内容的提问来源于stack exchange,提问作者OneRandomCoder
相关产品推荐
相关产品推荐

