Я работаю над расширением Node Media Server , чтобы сохранить входящие потоки на диск в формате MP4.Для этого преобразования в MP4 я в значительной степени опираюсь на спецификацию Apple QuickTime Movie , в спецификации ISO / IEC 14496-14 (которую я обнаружил в репозитории Rust-MP4 GitHub бесплатно) и Исходный код HLS.js
В данный момент я тестирую одно видео.Как только это сработает, я начну экспериментировать с другими видео.Для моего случая использования мне нужно только поддерживать видео H.264 и аудио AAC.
В настоящее время, когда установлено соединение RTMP, первые 3 пакета, которые я получаю, последовательно:
- 1
AMF metadata
пакет (RTMP cid = 6), содержащий такую информацию, как ширина видео, высота видео, битрейт, частота дискретизации аудио и т. Д. - 1
audio
пакет (RMTP cid = 4), содержащий 7 байтов данных.Я предполагаю, что это пакет конфигурации AAC - 1
video
(RTMP cid = 5), содержащий 46 байтов данных.Я предполагаю, что это пакет конфигурации AVC
При записи атома MP4 moov
, есть два места, где мне нужно использовать дополнительную информацию, которая не находится в метаданных AMF (и предположительно расположена в этих двухпакеты конфигурации):
- В атоме
esds
, Источник HLS.js добавляет данные "config".Я предполагаю, что я просто добавляю всю 7-байтовую полезную нагрузку из пакета аудиоконфигурации здесь - В
avcC
атоме, Источник HLS.js добавляет "sps" и "pps"данные.Это корень моей проблемы
Что касается анализа этих 46 байтов, я нашел код в Узел Медиа-сервер и HLS.js , который, кажется,разбирать те же данные.Разница между этими двумя частями кода заключается в том, что Node Media Server ожидает дополнительные 13 байтов данных в начале пакета.Кажется, что пакет, который я получаю, содержит эти дополнительные 13 байтов, поэтому я просто следую их примеру в извлечении width
, height
, profile
, compat
и level
информации.В частности, 46 байтов:
[0x17, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0xc0, 0x1f, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x42, 0xc0, 0x1f, 0xa6, 0x11, 0x02, 0x80, 0xbf, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xc2, 0x3c, 0x60, 0xc8, 0x46, 0x01, 0x00, 0x05, 0x68, 0xc8, 0x42, 0x32, 0xc8]
Разбить это на байты, которые я могу легко разобрать (до использования экспоненциального кодирования Голомба):
[
0x17, // "frame type", specifies H.264 or HVEC
0x00, 0x00, 0x00, 0x00, 0x01, // ignored. Reserved?
0x42, // profile
0xc0, // compat
0x1f, // level
0xff, // "info.nalu" (per Node Media Server source)
0xe1, // "info.nb_sps" (per Node Media Server source)
0x00, 0x19, // "nal size"
// Above here are the bits exclusively seen by Node Media Server (specific to RTMP?)
// Below here are the bits passed to HLS.js as "unit.data" (common to all AVC1 streams?):
0x67, // "nal type"
0x42, // profile (again?)
0xc0, // compat (again?)
0x1f, // level (again?)
// Below here, data is not necessarily byte-aligned as Exponential Golomb encoding is used
// ...
]
Теперь проблема, с которой я сталкиваюсь, заключается в том, что при создании атома moov
(и атома avcC
, в частности) мне нужно знать как sps
, так и pps
байт. Из источника HLS.js похоже, что sps
может быть просто этим видео-конфигурационным пакетом минус первые 13 байтов.Однако, как мне найти pps
?Является ли pps
последними байтами этого пакета, и я должен его где-то разделить?Будет ли это доставлено в другом пакете?Если нужно ожидать два видеопакета, есть ли какой-то способ, которым я должен их дифференцировать, чтобы я знал, какой из них sps
, а какой pps
?
Если я смогу выяснить этот последний маленький кусочек,тогда я должен полностью закончить написание пакета moov
(после чего мне просто нужно выяснить правильный формат для пакета mdat
и у меня должен быть рабочий код)
Обновление: Для записи, я только что проверил четвертый пакет, который был доставлен, чтобы увидеть, может ли он содержать pps
данных.После повторного подключения к потоку ~ 20 раз четвертый пакет был последовательно video
пакетом (RTMP cid = 5), но размер пакета варьировался от 16000 байтов до 21000 байтов.Я подозреваю, что это допустимые видеоданные.
Второе обновление: Я только что проверил, какое смещение было в пакете конфигурации видео, когда я закончил анализ SPS, и я был на байте 23 (0x84
).Поэтому вполне вероятно, что PPS на самом деле равен в конце этого байтового массива, но я не уверен, сколько байтов являются разделителями / заголовками (тип NAL, длина NAL и т. Д.) И сколько байтовфактический PPS.