我正在研究一些 ffmpeg+nginx 项目,有一种行为几乎是有意义的,但我仍然不明白。
ffmpeg 正在使用文件overlay.png
来给视频流添加水印。
当我将新图像写入该位置时,ffmpeg 看不到更改的图像,并且我的流水印保持不变。
当我将新图像写入overlay2.png
然后时mv overlay2.png overlay.png
,ffmpeg 会看到新图像并几乎立即更新。
将新图像写入现有文件与将图像移动到现有名称之间有什么区别。
通过 nginx exec 运行,运行正常
- 从 OBS 流式传输到 nginx
- nginx 将 RTMP 传递给 ffmpeg
- ffmpeg 位于
overlay.png
视频顶部的中心 - ffmpeg 将覆盖缩放到与视频相同的分辨率(尚未计算纵横比)
- ffmpeg 仅在使用以下方式更新图像时才能正确更新图像
mv
ffmpeg -i rtmp://localhost:1935/stream/$name
-f image2 -loop 1 -re -i /opt/images/overlayimage.png
-filter_complex "[1][0]scale2ref[logo][video];[video][logo]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2,split=1[overlayimage]"
-map '[overlayimage]' -map 0:a -c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 2500k -f flv -g 30 -preset veryfast rtmp://localhost:1935/hls/$name_wm
-c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 2500k -f flv -g 30 -preset veryfast -profile:v baseline rtmp://localhost:1935/hls/$name;
循环生成图像并更新 RTMP
while true
do
convert -background transparent -fill red -font Nimbus-Sans-L-Bold -size 1024x768 -gravity center label:"$(date)" temp.png
sleep 1 && mv -f temp.png overlayimage.png
convert -background transparent -fill blue -font Nimbus-Sans-L-Bold -size 1024x768 -gravity center label:"$(date)" temp.png
sleep 1 && mv -f temp.png overlayimage.png
convert -background transparent -fill green -font Nimbus-Sans-L-Bold -size 1024x768 -gravity center label:"$(date)" temp.png
sleep 1 && mv -f temp.png overlayimage.png
convert -background transparent -fill purple -font Nimbus-Sans-L-Bold -size 1024x768 -gravity center label:"$(date)" temp.png
sleep 1 && mv -f temp.png overlayimage.png
done
问题/疑问
如果我使用convert .... overlayimage.png
,ffmpeg
则看不到更改的图像。当我使用中间文件时,mv overlayimage2.png overlayimage.png
它工作正常。
我只是好奇为什么它mv
比就地更新更好。
为了帮助那些在 Google 上搜索“ffmpeg 图像未更新”或“ffmpeg 覆盖图像在实时流上居中并缩放”的人。
答案1
输入的更新必须是原子的。基本上,当 ffmpeg 读取文件时,文件大小不应为 0、被阻塞或丢失。如果是,ffmpeg 图像读取器会以 EOF 中止。mv
速度更快,并且通常会成功。