我已经用头撞这堵墙很长时间了。希望大家能帮我渡过难关。
我有一个从 IP 摄像机发送到我的计算机的实时流。
Nginx 发布到 YouTube 和 FFmpeg 流,每分钟获取一帧用于静态网络摄像头图像。
这是带有 exec_push 的代码,我尝试使用但没有成功。 YouTube 流和帧捕获工作正常。我已经安装了 FFmpeg 和 freetype。这一切都在安装了自制 FFmpeg --HEAD 的 MacOS X 10.15.4 Catalina 上。
更新:我还应该说我已经尝试使用命令行 FFmpeg 输出覆盖,并且它与此命令配合得很好:
/usr/local/bin/ffmpeg -i rtmp://localhost:1935/live/68.1. -vf drawtext="fontfile=/System/Library/Fonts/Supplemental/Arial.ttf:text='Stack Overflow': fontcolor=white: fontsize=24: box=1: <a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f1939e89929e9d9e83cc939d90929ab1c1dfc4" rel="noreferrer noopener nofollow">[email protected]</a>: boxborderw=5: x=(w-text_w)/2: y=(h-text_h)/2" /Users/user/Desktop/test.mp4
看来 Nginx.conf 中的输出部分是 FFmpeg 不喜欢的部分
我的想法是我应该将覆盖的 FFmpeg 流传递到“覆盖”应用程序,并将流发布到 Youtube 并从那里捕获帧。 (也可能被记录)。
更新:当我尝试指向 sh 文件来运行命令而不是直接 FFmpeg exec_push 时,我得到:
[alert] 56849#0: kevent() error on 15 filter:-1 flags:4002 (2: No such file or directory)
非常感谢!
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
exec_push /usr/local/bin/ffmpeg -i rtmp://localhost:1935/live/68.1. -vf drawtext="fontfile=/System/Library/Fonts/Supplemental/Arial.ttf:textfile=/Users/Shared/overlayescaped.txt: reload=1: fontcolor=white: fontsize=20: box=1: boxcolor=black@1: boxborderw=75: x=70: y=925" -c:v libx264 -maxrate 6000k -bufsize 4000k -c:a aac -b:a 160k -ar 44100 -b:a 128k -f mp4 rtmp://localhost:1935/overlay/test;
#push rtmp://localhost:1935/overlay;
}
application overlay {
live on;
record off;
push rtmp://a.rtmp.youtube.com app=live2 playpath=yourstreamkey;
exec_push /usr/local/bin/ffmpeg -i rtmp://localhost:1935/overlay/$name -vf fps=1/60 /Users/Shared/stream/netcam.jpg;
}
}
}
最佳答案
答案是:
a) 我必须通过文件调用 Ffmpeg 命令才能使其工作。我不完全确定为什么,但事实就是如此。
b) 我之前无法从 Ffmpeg 获取日志信息。这是因为我登录到了错误的位置。由于 Nginx 使用非特权(nobody)用户,我需要登录到/tmp/。有道理。
c)此时,一旦命令从文件中运行,我就可以看到 Ffmpeg 抛出的实际错误并可以对其进行故障排除。这与选项放置、间距以及确保它是 flv 容器而不是 mp4 容器有很大关系。
这是我最终得到的 Nginx rtmp 配置:
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
meta copy;
exec /Users/Shared/ffmpegcommand.sh $name;
}
application overlay {
live on;
record off;
meta copy;
push rtmp://a.rtmp.youtube.com app=live2 playpath=stream-key;
exec_push /usr/local/bin/ffmpeg -i rtmp://localhost:1935/overlay/$name -vf fps=1/60 /Users/Shared/stream/netcam.jpg;
}
}
}
这是我在命令文件中用于文本叠加的 Ffmpeg 命令(现在使用 -filter_complex,因为 -vf 在本例中不是正确的选项)。
/usr/local/bin/ffmpeg -i rtmp://localhost:1935/live/68.1. -filter_complex drawtext="fontfile=/System/Library/Fonts/Supplemental/Verdana.ttf: textfile=/Users/Shared/overlayescaped.txt: reload=1: fontcolor=white: fontsize=17: box=1: boxcolor=black@1: boxborderw=80: x=80: y=935" -c:v libx264 -level 4.1 -maxrate 6000k -bufsize 4000k -c:a copy -f flv rtmp://localhost:1935/overlay/newlive 2>>/tmp/ffmpeg.error
我还修改了音频选项,以便它们直接从源复制,而不需要编码。
最后,我从已有的文本文件创建了覆盖文本文件。现有的覆盖层有一个表示湿度的 % 符号,因此我必须在 bash 脚本中使用 sed 转义该字符。
escovlfiletmp='/Users/Shared/overlayescapedtmp.txt'
escovlfile='/Users/Shared/overlayescaped.txt'
overlaysearch="% B:"
overlayreplace="\\\\\\% B:"
sed -e "s/${overlaysearch}/${overlayreplace}/g" ${overlayfile} > ${escovlfile}
我已附上最终视频流结果的屏幕截图。整个黑色区域是覆盖层。
很高兴。
感谢您在本网站和其他地方提供的所有资源。我花了 4 天和很多个小时不断地搜索,终于把所有的东西拼凑起来。
关于NGinx RTMP 直播流文本叠加并推送到多个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61413193/