RTSP流到ffmpeg问题

问题描述 投票:0回答:1

我正在编写一个用于管理和查看来自ONVIF ip-cameras的流的Web应用程序。 它是用nodejs编写的。我们的想法是在节点和管道输出中运行子进程到节点,然后将缓冲区发送到客户端并在画布上呈现它。我有一个工作解决方案,用于将数据发送到客户端并使用websockets在画布上呈现它,但它只适用于我的一个相机。

我拥有2台IP摄像机,它们都有rtsp服务器。 其中一个(让它命名为camX)与这个ffmpeg命令一起工作(有时它会停止,可能是由于数据包丢失):

ffmpeg -rtsp_transport tcp -re -i <rtsp_link> -f mjpeg pipe:1

但另一个(camY)返回Nonmatching transport in server reply并退出。

我发现camY传输是unicast但是ffmpeg不支持这个特定的lower_transport,正如我在ffmpeg论坛上看到的那样。

所以我开始寻找解决方案。我的第一个想法是使用openRTSP与两个流都可以正常工作。我查看了文档并提出了这个命令: openRTSP -4 -c <rtsp_link> | ffmpeg -re -i pipe:0 -f mjpeg pipe:1 -4参数以mp4格式将流返回到管道 这是我遇到的另一个问题,ffmpeg返回:

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x559a4b6ba900] moov atom not found  
pipe:0: Invalid data found when processing input

有没有办法让这项工作?我尝试了各种解决方案,但是没有一个能够工作。

编辑

正如@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命令返回错误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";
}

在我看来,它似乎无法寻找文件,因为它是一个流而不是静态文件。 有关解决方法的任何建议吗?

linux ffmpeg rtsp ip-camera openrtsp
1个回答
0
投票

这里有很多东西:

  1. Nonmatching transport in server reply - 这很可能不是由于单播(因为单播是正常的方式 - 将流发送到单个客户端)。这个错误很可能来自这样一个事实:你实际上是用-rtsp_transport tcp标志强制RTP通过TCP。这里有几个选项 - 检查不工作的摄像机,检查它们是否只设置为UDP并将它们设置为TCP,甚至更好 - 不要强制传输并让ffmpeg与摄像机协商。也许这会马上解决问题。
  2. 关于OpenRTSP - 当所有需要的数据都已知时,moov原子通常写在文件的末尾,并且由于你正在管道它,它实际上打破了这里的逻辑。我认为OpenRTSP实际上从不发出moov,因为它永远不会结束流,因此ffm​​peg永远不会得到它。我建议只是尝试修复RTSP传输,如上所述。
© www.soinside.com 2019 - 2024. All rights reserved.