RTSP 流转 ffmpeg 问题
RTSP stream to ffmpeg problems
我正在编写一个 Web 应用程序来管理和查看来自 ONVIF 网络摄像机的流。
它是用 nodejs 编写的。这个想法是 运行 节点中的子进程和管道输出到节点,然后将缓冲区发送到客户端并在 canvas 上呈现它。我有一个可行的解决方案,可以使用 websockets 将数据发送到客户端并在 canvas 上呈现它,但它只适用于我的一台相机。
我有 2 个网络摄像机,它们都有 rtsp 服务器。
其中之一(我们将其命名为 camX)可以与此 ffmpeg 命令一起使用(有时它会停止,可能是由于数据包丢失):
ffmpeg -rtsp_transport tcp -re -i <rtsp_link> -f mjpeg pipe:1
但另一个 (camY) returns Nonmatching transport in server reply
并退出。
我发现 camY t运行sport 是 unicast
但 ffmpeg 不支持这个特定的 lower_transport 正如我在 ffmpeg 论坛上看到的那样。
所以我开始寻找解决方案。我的第一个想法是使用 openRTSP
这对两个流都很好。
我查看了文档并提出了这个命令:
openRTSP -4 -c <rtsp_link> | ffmpeg -re -i pipe:0 -f mjpeg pipe:1
-4
参数 returns 以 mp4 格式传输到管道
这是我 运行 遇到的另一个问题,ffmpeg returns:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x559a4b6ba900] moov atom not found
pipe:0: Invalid data found when processing input
有什么方法可以让它工作吗?
我尝试了各种找到的解决方案,但 none 有效。
编辑
正如@Gyan 建议的那样,我使用了 -i
参数而不是 -4
,但这并没有解决我的问题。
我的命令:
openRTSP -V -i -c -K <rtsp_link> | ffmpeg -loglevel debug -re -i pipe:0 -f mjpeg pipe:1
Created receiver for "video/H264" subsession (client ports 49072-49073)
Setup "video/H264" subsession (client ports 49072-49073)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
Outputting to the file: "stdout"
[avi @ 0x5612944268c0] Format avi probed with size=2048 and score=100
[avi @ 0x56129442f7a0] use odml:1
Started playing session
Receiving streamed data (signal with "kill -HUP 15028" or "kill -USR1 15028" to terminate)...
^C
[AVIOContext @ 0x56129442f640] Statistics: 16904 bytes read, 0 seeks
pipe:0: Invalid data found when processing input
如你所见,openRTSP 命令return err 29 但同时它输出一些数据到管道。
当我终止命令时,ffmpeg 显示它读取了一些数据但无法处理它。
这是产生该错误的函数:
void AVIFileSink::setWord(unsigned filePosn, unsigned size) {
do {
if (SeekFile64(fOutFid, filePosn, SEEK_SET) < 0) break;
addWord(size);
if (SeekFile64(fOutFid, 0, SEEK_END) < 0) break; // go back to where we were
return;
} while (0);
// One of the SeekFile64()s failed, probable because we're not a seekable file
envir() << "AVIFileSink::setWord(): SeekFile64 failed (err "
<< envir().getErrno() << ")\n";
}
在我看来,它似乎无法搜索文件,因为它是流而不是静态文件。
有任何解决方法的建议吗?
这里有很多东西:
Nonmatching transport in server reply
- 这很可能不是由于单播(因为单播是正常方式 - 将流发送到单个客户端)。该错误很可能来自这样一个事实,即您实际上是在使用 -rtsp_transport tcp
标志强制通过 TCP 进行 RTP。您在这里有几个选项 - 检查不工作的相机,检查它们是否仅设置为 UDP 并将它们设置为 TCP,或者更好 - 不要强制传输并让 ffmpeg 与相机协商。也许这会立即解决问题。
- 关于 OpenRTSP - 当所有需要的数据已知时,
moov
原子通常写在文件末尾,并且由于您正在管道化它,它实际上打破了这里的逻辑。我假设 OpenRTSP 实际上从不发出 moov
因为它永远不会结束流,因此 ffmpeg 永远不会得到它。我会建议简单地尝试修复 RTSP 传输,如上所述。
我正在编写一个 Web 应用程序来管理和查看来自 ONVIF 网络摄像机的流。
它是用 nodejs 编写的。这个想法是 运行 节点中的子进程和管道输出到节点,然后将缓冲区发送到客户端并在 canvas 上呈现它。我有一个可行的解决方案,可以使用 websockets 将数据发送到客户端并在 canvas 上呈现它,但它只适用于我的一台相机。
我有 2 个网络摄像机,它们都有 rtsp 服务器。
其中之一(我们将其命名为 camX)可以与此 ffmpeg 命令一起使用(有时它会停止,可能是由于数据包丢失):
ffmpeg -rtsp_transport tcp -re -i <rtsp_link> -f mjpeg pipe:1
但另一个 (camY) returns Nonmatching transport in server reply
并退出。
我发现 camY t运行sport 是 unicast
但 ffmpeg 不支持这个特定的 lower_transport 正如我在 ffmpeg 论坛上看到的那样。
所以我开始寻找解决方案。我的第一个想法是使用 openRTSP
这对两个流都很好。
我查看了文档并提出了这个命令:
openRTSP -4 -c <rtsp_link> | ffmpeg -re -i pipe:0 -f mjpeg pipe:1
-4
参数 returns 以 mp4 格式传输到管道
这是我 运行 遇到的另一个问题,ffmpeg returns:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x559a4b6ba900] moov atom not found
pipe:0: Invalid data found when processing input
有什么方法可以让它工作吗? 我尝试了各种找到的解决方案,但 none 有效。
编辑
正如@Gyan 建议的那样,我使用了 -i
参数而不是 -4
,但这并没有解决我的问题。
我的命令:
openRTSP -V -i -c -K <rtsp_link> | ffmpeg -loglevel debug -re -i pipe:0 -f mjpeg pipe:1
Created receiver for "video/H264" subsession (client ports 49072-49073)
Setup "video/H264" subsession (client ports 49072-49073)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
AVIFileSink::setWord(): SeekFile64 failed (err 29)
Outputting to the file: "stdout"
[avi @ 0x5612944268c0] Format avi probed with size=2048 and score=100
[avi @ 0x56129442f7a0] use odml:1
Started playing session
Receiving streamed data (signal with "kill -HUP 15028" or "kill -USR1 15028" to terminate)...
^C
[AVIOContext @ 0x56129442f640] Statistics: 16904 bytes read, 0 seeks
pipe:0: Invalid data found when processing input
如你所见,openRTSP 命令return err 29 但同时它输出一些数据到管道。
当我终止命令时,ffmpeg 显示它读取了一些数据但无法处理它。
这是产生该错误的函数:
void AVIFileSink::setWord(unsigned filePosn, unsigned size) {
do {
if (SeekFile64(fOutFid, filePosn, SEEK_SET) < 0) break;
addWord(size);
if (SeekFile64(fOutFid, 0, SEEK_END) < 0) break; // go back to where we were
return;
} while (0);
// One of the SeekFile64()s failed, probable because we're not a seekable file
envir() << "AVIFileSink::setWord(): SeekFile64 failed (err "
<< envir().getErrno() << ")\n";
}
在我看来,它似乎无法搜索文件,因为它是流而不是静态文件。
有任何解决方法的建议吗?
这里有很多东西:
Nonmatching transport in server reply
- 这很可能不是由于单播(因为单播是正常方式 - 将流发送到单个客户端)。该错误很可能来自这样一个事实,即您实际上是在使用-rtsp_transport tcp
标志强制通过 TCP 进行 RTP。您在这里有几个选项 - 检查不工作的相机,检查它们是否仅设置为 UDP 并将它们设置为 TCP,或者更好 - 不要强制传输并让 ffmpeg 与相机协商。也许这会立即解决问题。- 关于 OpenRTSP - 当所有需要的数据已知时,
moov
原子通常写在文件末尾,并且由于您正在管道化它,它实际上打破了这里的逻辑。我假设 OpenRTSP 实际上从不发出moov
因为它永远不会结束流,因此 ffmpeg 永远不会得到它。我会建议简单地尝试修复 RTSP 传输,如上所述。