【发布时间】:2020-04-15 12:21:03
【问题描述】:
我正在使用 ffmpeg 处理来自远程摄像机的传入 MPEGTS 流,并使用我的应用将其传送给多个客户端。
从技术上讲,我使用 ffmpeg 将传入流转换为 MJPEG 输出,并将数据块(来自 ffmpeg 进程标准输出)通过管道传输到客户端 http 响应上的可写流。
但是,我面临一个问题 - 并非所有数据块都代表一个完整的“完整”帧。因此,在浏览器中连续显示它们会导致随机播放带有半完整帧的闪烁视频。 我知道这一点是因为在打印每个块长度时,大部分时间都会产生一个很大的值(X),但是我时不时地得到 2 个长度为(2/5X)的连续块,然后是(3/5X)例如。
所以问题 - 有没有办法强制 ffmpeg 进程只输出整个帧?如果没有,我有没有办法“手动”检查每个数据块并查找标头/元数据/标志来指示帧开始/结束?
我输出 MJPEG 的 ffmpeg 命令是:
ffmpeg -i - -c:v mjpeg -f mjpeg -
解释:
"-i -" :(输入)是进程的标准输入(而不是静态文件)
"-c:v mjpeg" : 使用 mjpeg 编解码器
"-f mjpeg" : 输出为 mjpeg 格式
"-" : 未指定输出(文件或 url) - 将是进程标准输出
编辑: 以下是一些用于可视化问题的 console.log 打印:
%%% FFMPEG Info %%%
frame= 832 fps= 39 q=24.8 q=29.0 size= 49399kB time=00:00:27.76 bitrate=14577.1kbits/s speed=1.29x
data.length: 60376
data.length: 60411
data.length: 60465
data.length: 32768
data.length: 27688
data.length: 32768
data.length: 27689
data.length: 60495
data.length: 60510
data.length: 60457
data.length: 59811
data.length: 59953
data.length: 59889
data.length: 59856
data.length: 59936
data.length: 60049
data.length: 60091
data.length: 60012
%%% FFMPEG Info %%%
frame= 848 fps= 38 q=24.8 q=29.0 size= 50340kB time=00:00:28.29 bitrate=14574.4kbits/s speed=1.28x
data.length: 60025
data.length: 60064
data.length: 60122
data.length: 60202
data.length: 60113
data.length: 60211
data.length: 60201
data.length: 60195
data.length: 60116
data.length: 60167
data.length: 60273
data.length: 60222
data.length: 60223
data.length: 60267
data.length: 60329
%%% FFMPEG Info %%%
frame= 863 fps= 38 q=24.8 q=29.0 size= 51221kB time=00:00:28.79 bitrate=14571.9kbits/s speed=1.27x
如您所见,整个帧约为 60k(我的指示是我在浏览器上查看的干净视频流),但输出时不时包含 2 个连续的块,加起来约为 60k .当传送到浏览器时,这些是“半帧”。
【问题讨论】:
-
添加
-thread_type frame并检查。 -
我实际上将传入流映射到 2 个输出 - 1 用于以 30 秒的块在本地磁盘上写入文件(所有文件都播放完美),另一个用于 mjpeg 输出流.那么我应该在哪里添加你的建议?在整个命令的乞求上,还是在 mjpeg 的“-map”上具体?
-
分享你的完整命令。
-
ffmpeg -i - -map 0:v -c:v mjpeg -f mjpeg - -map 0:v -c:v libx264 -f 段 -reset_timestamps 1 -segment_time 30 -segment_format mp4 -strftime 1 "${dir}/${cameraId}_recording_%d-%m-%Y_%H:%M:%S.mp4"
-
在
-c:v mjpeg之后直接添加
标签: node.js ffmpeg video-streaming mjpeg