Переключение входов ffmpeg / отображение на лету / во время записи - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть видеоисточник rtsp stream1 и аудиоисточник, который я в настоящее время объединяю и отправляю на rtmp-сервер, используя:

stream1="rtsp://streamurl1"

/usr/bin/ffmpeg                    \
    [...]
    -i "$stream1"                  \
    [...]
    -itsoffset $AUDIOVIDEOOFFSET   \
    -f pulse                       \
    -i default                     \
    [...]
    -vcodec copy                   \
    -map 0:v -map 1:a              \
    [...]
    -f flv "rtmp://streamingserver"

Я хотел бы добавить второе видео источник stream2 и переключаться между stream1 и stream2 вперед и назад, не прерывая звук. Оба потока идентичны / поступают с одинаковых камер.

Есть ли какой-нибудь вменяемый способ сделать это с ffmpeg? Или как бы вы порекомендовали это сделать?

Простая остановка процесса и его перезапуск с использованием stream2 вместо stream1 работает, но приводит к отключению потока на несколько секунд и является текущим наихудшим сценарием, который я бы хотел улучшить.

1 Ответ

0 голосов
/ 28 апреля 2020

Я не смог заставить его работать с чистым ffmpeg за разумное время, но модуль nginx -rtmp работал из коробки.

Это в основном apt install libnginx-mod-rtmp nginx, добавьте ..

rtmp {
        server {
                listen 1935;
                chunk_size 4096;

                application live {
                        live on;
                        record off;
            allow publish 127.0.0.1;
                        deny publish all;
                }
        }
}

.. к nginx .conf, systemctl restart nginx и nginx действует как локальное устройство l oop -back на rtmp://localhost/live.

Если теперь у вас есть n потоков для мультиплексирования, вы можете создать n системных служб camera_i.service

[Unit]
Description=Send stream i to local nginx loopback device
# List all other
Conflicts=camera_1.service, camera_2.service, [...]

[Service]
ExecStart=/usr/bin/ffmpeg -i rtsp://mystreamurl_i -c copy -f flv rtmp://localhost/live
Type=simple
Restart=on-failure
KillSignal=SIGINT
SuccessExitStatus=255

[Install]
WantedBy=xsession.target

и переключиться на поток i путем запуска camera_i.service:

systemctl --user start camera_i.service

Все другие службы, перечисленные в опции Conflicts=, автоматически завершаются с помощью systemd, эффективно мультиплексируя потоки камеры.

В результате Поток можно затем использовать для записи, используя что-то вроде следующего:

/usr/bin/ffmpeg                    \
    [...]
    -use_wallclock_as_timestamps 1 \
    -fflags +genpts                \
    -i "rtmp://localhost/live"     \
    [...]
    -itsoffset $AUDIOVIDEOOFFSET   \
    -f pulse                       \
    -i default                     \
    [...]
    -vcodec copy                   \
    -map 0:v -map 1:a              \
    [...]
    OUTPUT

В результате получается довольно плавный переход с непрерывным звуком.

-use_wallclock_as_timestamps 1 -fflags +genpts может быть ненужным, если вы не используете -vsync 0. Но я еще не проверял это.


Приложение

Как было предложено в списке рассылки ffmpeg, существует фильтр zmq, который предположительно может менять настройки фильтров на лету. Идея состоит в том, чтобы наложить два потока и переключить непрозрачность верхнего потока, эффективно переключая поток.

Я не мог заставить его работать, но любой мог попробовать:

# compiled with --enable-libzmq
ffmpeg -i INPUT -filter_complex 'null[main];movie=INPUT2,zmq,lumakey@toggle=tolerance=1,[main]overlay,realtime' OUTPUT
echo lumakey@toggle tolerance 0 | zmqsend

где zmqsend получается из:

git clone https://github.com/FFmpeg/FFmpeg
cd FFmpeg/
./configure
cd tools/
gcc zmqsend.c -o zmqsend -I.. `pkg-config --libs --cflags libzmq libavutil`
...