Как настроить время запуска mpeg 2 ts с помощью ffmpeg?

Я пишу простой Java-сервер HLS (Http Live Streaming) для прямой трансляции (действительно вживую, не по запросу), скриншота + голос. Я постоянно получаю куски кадров изображений и аудиосэмплов в качестве входных данных для своего сервиса и вырабатываю mpeg 2 ts files + m3u8 playlist в качестве выходных данных. Рабочий процесс следующий:

  1. Собирать (буферизовать) исходные видеокадры и аудио за определенный период времени
  2. Конвертировать серию видеокадров в видеофайл в формате h.264
  3. Конвертировать аудио образцы в аудио файл mp3
  4. Объединить их .ts файл с командой ffmpeg

    ffmpeg -i audio.mp3 -i video.mp4 -f mpegts -c:a copy -c:v copy -vprofile main -level:v 4.0 -vbsf h264_mp4toannexb -flags -global_header segment.ts
    
  5. Опубликовать несколько .ts файлы в плейлисте m3u8.

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

freetype error: Breaking unbreakable line
ts error: libdvbpsi (PSI decoder): TS discontinuity (received 0, expected 4) for PID 17
ts error: libdvbpsi (PSI decoder): TS duplicate (received 0, expected 1) for PID 0
ts error: libdvbpsi (PSI decoder): TS duplicate (received 0, expected 1) for PID 4096
core error: ES_OUT_SET_(GROUP_)PCR is called too late (pts_delay increased to 1000 ms)
core error: ES_OUT_RESET_PCR called
core error: Could not convert timestamp 185529572000
ts error: libdvbpsi (PSI decoder): TS discontinuity (received 0, expected 4) for PID 17
ts error: libdvbpsi (PSI decoder): TS duplicate (received 0, expected 1) for PID 0
ts error: libdvbpsi (PSI decoder): TS duplicate (received 0, expected 1) for PID 4096
core error: ES_OUT_SET_(GROUP_)PCR is called too late (jitter of 8653 ms ignored)
core error: Could not get display date for timestamp 0
core error: Could not convert timestamp 185538017000
core error: Could not convert timestamp 185538267000
core error: Could not convert timestamp 185539295977
...

Я думаю, причина в том, что время начала сегментов не принадлежит одному потоку, но невозможно объединить и повторно сегментировать (с ffmepg -f segment) весь поток после добавления нового чанка. Пробовал добавлять #EXT-X-DISCONTINUITY отметьте плейлист, как предложено здесь, но это не помогло. Когда я ffprobe их я получаю

Input #0, mpegts, from '26.ts':
Duration: 00:00:10.02, start: 1.876978, bitrate: 105 kb/s
Program 1
Metadata:
  service_name    : Service01
  service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p, 640x640, 4 fps, 4 tbr, 90k tbn, 8 tbc
Stream #0:1[0x101]: Audio: mp3 ([3][0][0][0] / 0x0003), 48000 Hz, mono, s16p, 64 kb/s   

Где начальное значение в строке Duration: 00:00:10.02, start: 1.876978, bitrate: 105 kb/s более или менее одинаков для всех сегментов. Когда я проверяю сегменты из доступных проверенных плейлистов (например, http://vevoplaylist-live.hls.adaptive.level3.net/vevo/ch1/appleman.m3u8), все они имеют начальные значения diffrenet для каждого сегмента, например:

Input #0, mpegts, from 'segm150518140104572-424570.ts':
Duration: 00:00:06.17, start: 65884.808689, bitrate: 479 kb/s
Program 257
Stream #0:0[0x20]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x180 [SAR 1:1 DAR 16:9], 30 fps, 29.97 tbr, 90k tbn, 60 tbc
Stream #0:1[0x21]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 115 kb/s
Stream #0:2[0x22]: Data: timed_id3 (ID3  / 0x20334449)

и следующий за ним

Input #0, mpegts, from 'segm150518140104572-424571.ts':
Duration: 00:00:06.22, start: 65890.814689, bitrate: 468 kb/s
Program 257
Stream #0:0[0x20]: Video: h264 (Constrained Baseline) ([27][0][0][0] / 0x001B), yuv420p, 320x180 [SAR 1:1 DAR 16:9], 30 fps, 29.97 tbr, 90k tbn, 60 tbc
Stream #0:1[0x21]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 124 kb/s
Stream #0:2[0x22]: Data: timed_id3 (ID3  / 0x20334449)

отличаются тем, что время начала segm150518140104572-424571.ts равно времени начала + продолжительность segm150518140104572-424570.ts,

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

2 ответа

Я ответил на свой вопрос с подходом, описанным здесь. Отметка времени может быть скорректирована с помощью -initial_offset параметр -f segment формат:

ffmpeg -i in.ts -vcodec copy -acodec copy -f segment -initial_offset 10 -segment_format mpegts out%d.ts

Для каждого нового сегмента я рассчитываю необходимое -initial_offset как сумма длины всех предыдущих сегментов.

Это больше, чем просто временные метки, это также показатели непрерывности. Таким образом, установка времени начала не решит вашу проблему. Вы должны кодировать как один поток.

Вы можете установить "-segment_time 20", чтобы выводить только один ts файл

fmpeg.exe -i 0.mp3 -c copy -bsf:v aac_adtstoasc -f segment -segment_time 20 -initial_offset 10 -segment_format mpegts out%d.ts
Другие вопросы по тегам