RTSP поток к проблемам ffmpeg - PullRequest
       100

RTSP поток к проблемам ffmpeg

0 голосов
/ 20 февраля 2019

Я пишу веб-приложение для управления и просмотра потоков с ip-камер ONVIF.
Написано в nodejs.Идея состоит в том, чтобы запустить дочерний процесс на выходе узла и канала на узел, затем отправить буфер клиенту и отобразить его на холсте.У меня есть рабочее решение для отправки данных клиенту и рендеринга их на холсте с помощью веб-сокетов, но оно работает только на одной из моих камер.

У меня 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

Есть ли способ заставить эту работу?Я пробовал различные решения, которые нашел, но ни одно из них не сработало.

EDIT

Как и предположил @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 возвращает 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";
}

По-моему, похоже, что он не сможет искать файлпотому что это поток, а не статический файл.
Есть предложения для обхода проблемы?

1 Ответ

0 голосов
/ 22 февраля 2019

Здесь есть несколько вещей:

  1. Nonmatching transport in server reply - это, скорее всего, не из-за одноадресной передачи (потому что одноадресная передача является обычным способом - отправка потока одному клиенту).Скорее всего, ошибка связана с тем, что вы на самом деле форсируете RTP через TCP с флагом -rtsp_transport tcp.У вас есть несколько вариантов здесь - проверить камеры, которые не работают, проверить, установлены ли они только на UDP и установить их на TCP или, что еще лучше, - не форсировать транспорт и позволить ffmpeg договориться с камерой.Возможно, это решает проблему сразу.
  2. Относительно OpenRTSP - атом moov обычно записывается в конец файла, когда все необходимые данные известны, и, поскольку вы передаете его по конвейеру, он фактически нарушаетлогика тут.Я бы предположил, что OpenRTSP на самом деле никогда не испускает moov, так как он никогда не завершает поток и, следовательно, ffmpeg никогда не получает его.Я бы посоветовал просто попытаться исправить транспорт RTSP, как указано выше.
...