Linux RTSP流到ffmpeg问题

Linux RTSP流到ffmpeg问题,linux,ffmpeg,rtsp,ip-camera,openrtsp,Linux,Ffmpeg,Rtsp,Ip Camera,Openrtsp,我正在编写一个web应用程序,用于管理和查看来自ONVIF ip摄像头的流。 它是用nodejs写的。其思想是在节点中运行一个子进程,并将输出输送到节点,然后将缓冲区发送到客户端并在画布上渲染。我有一个可行的解决方案,可以将数据发送到客户端,并使用websockets在画布上渲染数据,但它只在我的一台相机上工作 我有2台IP摄像机,它们都有rtsp服务器。 其中一个(我们称之为camX)可以使用这个ffmpeg命令(有时它只是停止,可能是由于数据包丢失): 有什么办法可以让这一切顺利进行吗? 我

我正在编写一个web应用程序,用于管理和查看来自ONVIF ip摄像头的流。
它是用nodejs写的。其思想是在节点中运行一个子进程,并将输出输送到节点,然后将缓冲区发送到客户端并在画布上渲染。我有一个可行的解决方案,可以将数据发送到客户端,并使用websockets在画布上渲染数据,但它只在我的一台相机上工作

我有2台IP摄像机,它们都有rtsp服务器。
其中一个(我们称之为camX)可以使用这个ffmpeg命令(有时它只是停止,可能是由于数据包丢失):

有什么办法可以让这一切顺利进行吗? 我尝试了我找到的各种解决方案,但都不奏效

编辑

正如@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-V-i-c-K | ffmpeg-logleveldebug-re-i管道:0-f mjpeg管道:1
为“视频/H264”子会话创建接收器(客户端端口49072-49073)
设置“视频/H264”子会话(客户端端口49072-49073)
AviFileLink::setWord():SeekFile64失败(错误29)
AviFileLink::setWord():SeekFile64失败(错误29)
AviFileLink::setWord():SeekFile64失败(错误29)
AviFileLink::setWord():SeekFile64失败(错误29)
AviFileLink::setWord():SeekFile64失败(错误29)
AviFileLink::setWord():SeekFile64失败(错误29)
AviFileLink::setWord():SeekFile64失败(错误29)
AviFileLink::setWord():SeekFile64失败(错误29)
AviFileLink::setWord():SeekFile64失败(错误29)
输出到文件:“标准输出”
[avi@0x5612944268c0]格式avi探测,大小=2048,分数=100
[avi@0x56129442f7a0]使用odml:1
开始播放会话
接收流数据(终止带有“kill-HUP 15028”或“kill-USR1 15028”的信号)。。。
^C
[AVIOContext@0x56129442f640]统计信息:读取16904字节,0
管道:0:处理输入时发现无效数据
正如您所看到的,openRTSP命令返回err 29,但同时它将一些数据输出到管道。
当我终止命令时,ffmpeg显示它读取了一些数据,但无法处理它

下面是产生该错误的函数:

void AVIFileSink::setWord(无符号filePosn,无符号大小){
做{
如果(参见文件64(fOutFid、filePosn、SEEK_SET)<0)中断;
addWord(大小);
如果(SeekFile64(fOutFid,0,SEEK_END)<0)中断;//返回到我们原来的位置
返回;
}而(0);
//其中一个SeekFile64()失败,可能是因为我们不是可查找的文件

envir()这里有很多东西:

  • 服务器应答中的非匹配传输
    -这很可能不是由于单播造成的(因为单播是正常的方式-将流发送到单个客户端)。错误最有可能来自这样一个事实,即您实际上正在使用
    -rtsp_transport TCP
    标志通过TCP强制RTP。这里有几个选项-检查不工作的摄像头,检查是否将其设置为仅UDP并将其设置为TCP,甚至更好-不要强制传输,让ffmpeg与摄像头协商。也许这个问题马上就解决了
  • 关于OpenRTSP,
    moov
    atom通常在所有需要的数据都已知的情况下写在文件的末尾,由于您正在对其进行管道传输,它实际上破坏了这里的逻辑。我假设OpenRTSP实际上从未发出
    moov
    ,因为它从未结束流,因此ffmpeg永远不会得到它。我建议您只需如上所述,安装并固定RTSP传输

  • ffmpeg需要MOOV头来解析数据,此头通常在处理完所有媒体数据后写入。请尝试在OpenRTSP中输出到AVI。它可能会帮助您解决ffmpeg相关的问题
    [mov,mp4,m4a,3gp,3g2,mj2 @ 0x559a4b6ba900] moov atom not found  
    pipe:0: Invalid data found when processing input
    
    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
    
    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";
    }