2015-06-16 25 views
8

Я создаю фрагментарный mp4 для html5 потоковой передачи, используя следующую команду:Flush & Задержка Проблемы с разобщенным Созданием MP4 в FFMPEG

-i rtsp://172.20.28.52:554/h264 -vcodec copy -an -f mp4 -reset_timestamps 1 -movflags empty_moov+default_base_moof+frag_keyframe -loglevel quiet - 
  1. «-i RTSP: //172.20.28.52: 554/h264 ", потому что источник h264 в потоке rtp-пакетов с ip-камеры. Для тестирования камера установлена ​​с GOP 1 (то есть все кадры являются ключевыми кадрами)
  2. «-vcodec copy», потому что мне не требуется перекодировка, только пересылка на mp4.
  3. "-movflags empty_moov + default_base_moof + frag_keyframe" для создания фрагментированного mp4 в соответствии со спецификацией расширения источников мультимедиа.
  4. «-» в конце, чтобы вывести mp4 в стандартный вывод. Я захватываю вывод и отправляю его веб-клиенту через веб-сокеты.

Все работает хорошо, ожидайте задержки, которую я пытаюсь решить. Если я входе каждый раз, когда данные, поступающие из стандартного вывода, с отметкой времени прибытия, я получаю этот выход:

16/06/2015 15: 40: 45,239 получили размер данных = 24

16/06/2015 15: 40: 45,240 получили размер данных = 7197

16/06/2015 15: 40: 45,241 получили размер данных = 32768

16/06/2015 15: 40: 45.241 полученные данные = 4941

16/06/2015 15 : 40: 45,241 получили данные размера = 12606

16/06/2015 15: 40: 45,241 получили размер данных = 6345

16/06/2015 15: 40: 45,241 получили размер данных = 6339

16/06/2015 15: 40: 45,242 получили размер данных = 6336

16/06/2015 15: 40: 45,242 получили размер данных = 6361

16/06/2015 15: 40: 45,242 получили размер данных = 6337

16/06/2015 15: 40: 45,242 получили размер данных = 6331

16/06/2015 15: 40: 45,242 получили размер данных = 6359

16/06/2015 15: 40: 45,243 получили размер данных = 6346

16/06/2015 15: 40: 45,243 получили размер данных = 6336

16/06/2015 15: 40: 45,243 получили размер данных = 6338

16/06/2015 15: 40: 45.243 полученные данные = 6357

16/06/20 15 15: 40: 45,243 получили размер данных = 6357

16/06/2015 15: 40: 45,243 получили размер данных = 6322

16/06/2015 15:40:45.243 получили размер данных = 6359

16/06/2015 15: 40: 45,244 получили размер данных = 6349

16/06/2015 15: 40: 45,244 получили размер данных = 6353

16/06/2015 15: 40: 45,244 получили размер данных = 6382

16/06/2015 15: 40: 45,244 получили размер данных = 6403

16/06/2015 15: 40: 45,304 получили размер данных = 6393

16/06/2015 15: 40: 4 5,371 получили размер данных = 6372

16/06/2015 15: 40: 45,437 получили размер данных = 6345

16/06/2015 15: 40: 45,504 получили размер данных = 6352

16/06/2015 15: 40: 45,571 получили размер данных = 6340

16/06/2015 15: 40: 45,637 получили размер данных = 6331

16/06/2015 15: 40: 45,704 получили размер данных = 6326

16/06/2015 15:40 : 45,771 получили размер данных = 6360

16/06/2015 15: 40: 45,838 получили размер данных = 6294

16/06/2015 15: 40: 45,904 получили размер данных = 6328

16/06/2015 15: 40: 45,971 получили размер данных = 6326

16/06/2015 15: 40: 46,038 получил размер = 6326

16/06/2015 15 данных: 40: 46,105 получили размер данных = 6340

16/06/2015 15: 40: 46,171 получили размер данных = 6341

16/06/2015 15: 40: 46,238 получил размер = 6332

данных Как вы можете видеть, первые 23 строк (которые содержат данные о 1,5 секунды видео) прибывают почти мгновенно, а затем задержка между каждыми двумя последовательными линиями составляет ~ 70 мс, что имеет смысл, потому что видео составляет 15 кадров в секунду. Такое поведение вводит латентность около 1,5 секунд.

Это похоже на проблему с промывкой, потому что я не вижу причин, по которым ffmpeg должен содержать первые 23 кадра в памяти, тем более, что каждый кадр является его собственным фрагментом внутри mp4. Я не мог, однако, найти какой-либо метод, который заставит ffmpeg быстрее очистить эти данные.

У кого-нибудь есть предложение?

Я хотел бы отметить, что это является продолжение вопроса к этому: Live streaming dash content using mp4box

+0

Мне пришло в голову, что у вас есть контроль над 'blockize', используемым для буферизации вывода. Проверьте http://www.ffmpeg.org/ffmpeg-all.html#toc-pipe и посмотрите, поможет ли вам эта настройка. –

+0

@PabloMontilla Я попытался сыграть с некоторыми разными значениями блочности и, хотя это каким-то образом произвело выход, не решило начальную задержку. – galbarm

+0

Здравствуйте, @galbarm! Я не могу запустить видео на странице с параметрами 'ffmpeg', всегда получая' Пропуск нераспознанного окна верхнего уровня: ftyp'. (h264 ip cam). Я также попытался изменить '-vcodec' на' libx264', в этом случае я получаю 'Пропуск нераспознанного окна верхнего уровня: mdat'. Не могли бы вы охарактеризовать ваш код больше или судить его где-нибудь? Наиболее интересной частью является параметр .addSourceBuffer, т. Е. Строка кодека. Заранее спасибо! – zarkone

ответ

4

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

probesize целое (вход)

Набор зондирующего размер в байтах, т.е. размер данных к анализировать, чтобы получить информацию о потоке. Более высокое значение будет , позволяющее обнаруживать больше информации, если оно рассеивается в поток , но увеличит задержку. Должно быть целое число не менее 32. По умолчанию это 5000000.

По умолчанию значение равно 5 000 000 байт, что эквивалентно ~ 1,5 с видео. Я смог почти полностью устранить задержку, уменьшив значение до 200 000.

0

Я решил латентную проблему, используя опцию -g, чтобы установить количество кадров в группе. В моем случае я использовал -g 2.Я подозреваю, что если вы не сделаете его явным, фрагмент либо ожидает, что источник предоставит ключевой кадр, либо использует действительно большое значение по умолчанию, чтобы сгенерировать ключевой кадр перед закрытием фрагмента и сбросом его на stdout.

+0

Я предполагаю, что вы перекодируете видео, чтобы контролировать размер выходного GOP. Я использую ffmpeg в режиме «vcodec copy», таким образом, только перемножая его на фрагментированный mp4.Я попытался установить источник моего видео (ip-камеры) для предоставления ключевых кадров, но это не помогло с начальной задержкой. – galbarm

0

Обычно буферизация для stdout отключается в случае выхода консоли. Если вы запустите ffmpeg из кода, буферизация включена, поэтому вы получите свои данные только тогда, когда буфер заполнен или команда завершена.

Вы должны устранить буферизацию stdout ваших os. На окнах его невозможно imo, но на ubuntu для ex. Существует http://manpages.ubuntu.com/manpages/maverick/man1/stdbuf.1.html

Смежные вопросы