Как свести к минимуму задержку в потоковой передаче с помощью ffmpeg

У меня проблема. Я бы сделал потоковое видео с ffmpeg с моей веб-камеры.

  • Я запускаю ffserver, и он работает.
  • С другого терминала я запускаю ffmpeg для потока с помощью этой команды и он работает:

    sudo ffmpeg -re -f video4linux2 -i /dev/video0 -fflags nobuffer -an http://localhost:8090/feed1.ffm
    
  • В моем файле конфигурации у меня есть этот поток:

    <Stream test.webm>
    Feed feed1.ffm
    Format webm
     NoAudio
     VideoCodec libvpx
     VideoSize 720x576
     VideoFrameRate 25
     # Video settings
        VideoCodec libvpx
        VideoSize 720x576           # Video resolution
        VideoFrameRate 25           # Video FPS
        AVOptionVideo flags +global_header  # Parameters passed to encoder 
                                        # (same as ffmpeg command-line parameters)
        AVOptionVideo cpu-used 0
        AVOptionVideo qmin 10
        AVOptionVideo qmax 42
        #AVOptionVideo quality good
        PreRoll 5
         StartSendOnKey
        VideoBitRate 400            # Video bitrate
     </Stream>
    
  • Я запускаю поток с помощью

    ffplay http:// 192.168.1.2: 8090/test.webm Он работает, но у меня есть задержка в 4 секунды, и я бы минимизировал эту задержку, потому что это важно для моего приложения. Благодаря

Ответы

Ответ 1

В руководстве по потоку FFMpeg есть специальный раздел о том, как уменьшить задержку. Я еще не пробовал все свои предложения. http://ffmpeg.org/trac/ffmpeg/wiki/StreamingGuide#Latency

Они делают особую заметку о задержке ffplay:

По умолчанию ffplay вводит небольшую задержку. Также полезно mplayer со своим -nocache для проверки задержки (или -benchmark). Использование SDL out также считается для просмотра кадров с минимальной задержкой: ffmpeg ... -f sdl -

Ответ 2

Я нашел три команды, которые помогли мне уменьшить задержку прямых трансляций. Первая команда очень проста и понятна, вторая объединена с другими опциями, которые могут работать по-разному в каждой среде, и последняя команда - хакерская версия, которую я нашел в документации. Она была полезна в начале, но теперь Первый вариант более стабильный.

1. Базовое использование -fflags nobuffer

Этот флаг формата уменьшает задержку, вносимую буферизацией во время анализа исходных входных потоков. Эта команда уменьшит заметную задержку и не вызовет глюков звука.

ffplay -fflags nobuffer -rtsp_transport tcp rtsp://<host>:<port>

2. Дополнительно -flags low_delay и другие параметры.

Мы можем объединить предыдущий флаг формата -fflags nobuffer с другими общими параметрами и дополнительными параметрами для более сложной команды:

  • -flags low_delay этот универсальный флаг кодека вызовет низкую задержку.
  • -framedrop: сбросить видеокадры, если видео не синхронизировано. Включено по умолчанию, если на главных часах не установлено видео. Используйте эту опцию, чтобы включить сброс кадров для всех источников тактовых импульсов
  • -strict experimental, наконец, -strict определяет, как строго следовать стандартам, а опция experimental допускает нестандартизированные экспериментальные вещи, экспериментальные (незавершенные/незавершенные/плохо проверенные) декодеры и кодеры. Эта опция является необязательной, и помните, что экспериментальные декодеры могут представлять угрозу безопасности, не используйте ее для декодирования ненадежного ввода.
ffplay -fflags nobuffer -flags low_delay -framedrop \
-strict experimental -rtsp_transport tcp rtsp://<host>:<port>

Эта команда может вносить некоторые глюки звука, но редко.

Также вы можете попробовать добавить:  * -avioflags direct для уменьшения буферизации и  * -fflags discardcorrupt отбрасывать поврежденные пакеты, но я думаю, что это очень агрессивный подход. Это может нарушить синхронизацию аудио-видео

ffplay -fflags nobuffer -fflags discardcorrupt -flags low_delay \ 
-framedrop -avioflags direct -rtsp_transport tcp rtsp://<host>:<port>

3. Хакерский вариант (найден в старой документации)

Это решение для отладки, основанное на установке низких значений для -probesize и -analyzeduration, чтобы ускорить запуск вашего потока.

  • -probesize 32 устанавливает размер измерения в байтах (то есть размер данных для анализа, чтобы получить информацию о потоке). Более высокое значение позволит обнаружить больше информации в случае ее распространения в потоке, но увеличит задержку. Должно быть целым числом не меньше 32. По умолчанию это 5000000.
  • analyzeduration 0 указывает, сколько микросекунд анализируется для проверки входных данных. Более высокое значение позволит обнаружить более точную информацию, но увеличит задержку. По умолчанию это 5000000 микросекунд (5 секунд).
  • -sync ext устанавливает главные часы на внешний источник, чтобы попытаться остаться в реальном времени. По умолчанию аудио. Основные часы используются для управления аудио-видео синхронизацией. Это означает, что этот параметр устанавливает тип синхронизации аудио-видео (то есть type = audio/video/ext).
ffplay -probesize 32 -analyzeduration 0 -sync ext -rtsp_transport tcp rtsp://<host>:<port>

Эта команда может иногда приводить к некоторым глюкам звука.

-rtsp_transport может быть настроен как udp или tcp в соответствии с вашей потоковой передачей. Для этого примера я использую tcp.

Ответ 3

Попробуйте установить flags AVFormatContext в AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS

AVFormatContext *ctx;
...
ctx->flags = AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS;

Затем попытайтесь установить поток декодера в 1. Кажется, что больше потока вызовет большую задержку.

AVCodecContext *ctx;
...
ctx->thread_count = 1;