mv 文件和直接写入同一文件名有什么区别

mv 文件和直接写入同一文件名有什么区别

我正在研究一些 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.pngffmpeg则看不到更改的图像。当我使用中间文件时,mv overlayimage2.png overlayimage.png它工作正常。

我只是好奇为什么它mv比就地更新更好。


为了帮助那些在 Google 上搜索“ffmpeg 图像未更新”或“ffmpeg 覆盖图像在实时流上居中并缩放”的人。

答案1

输入的更新必须是原子的。基本上,当 ffmpeg 读取文件时,文件大小不应为 0、被阻塞或丢失。如果是,ffmpeg 图像读取器会以 EOF 中止。mv速度更快,并且通常会成功。

相关内容