Я пишу веб-приложение для управления и просмотра потоков с 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";
}
По-моему, похоже, что он не сможет искать файлпотому что это поток, а не статический файл.
Есть предложения для обхода проблемы?