Создайте действительный h264 из частичного потока видеоданных h264 и оберните как Mp4

avatar
Zevrant
1 июля 2021 в 20:13
225
1
0

Допустим, что я читаю из потока данных, и этот поток отправляет содержимое видеоканала h264. Учитывая, что я читаю из этого потока, и у меня есть некоторый объем данных, состоящий из неопределенного количества кадров (NAL?). Учитывая, что я знаю частоту кадров и размер исходного видео, как мне преобразовать этот фрагмент в mp4, который я мог бы просмотреть? Видео не содержит звука.

Я хочу сделать это с помощью nodejs? Мои попытки сделать это не дали ничего похожего на действительный файл h264 для преобразования в mp4. Мои мысли до сих пор заключались в том, чтобы удалить все данные, предшествующие первому найденному стартовому коду в данных, передать их в файл и использовать ffmpeg (в настоящее время просто тестирование в командной строке) для преобразования файла в mp4.

Как правильно это сделать?

т.е. что-то вроде этого (это на машинописном языке, но то же самое)

//We assume here that when this while loop exist at least one full frame of data will have been read and written to disk
let stream: WriteStream = fs.createWriteStream("./test.h264")
while(someDataStream.available()) { //just an example not real code
    let data: Buffer = someDataStream.readSomeData() //just an example not a real method call
    let file = null;
    try {
        file = fs.statSync("./test.h264");
    } catch (error) {
        console.error(error)
    }

    if(!stream.writable) {
        console.error("stream not writable")
    } else if(file == null || file.size <= 0) {
      

        let index = data.indexOf(0x7C)
        console.log("index: " + index)
        if(index > 0) {
            console.log("index2: " + data.slice(index).indexOf(0x7c))
            stream.write(data.slice(index))
        }
    } else {
        stream.write(data)
    }
}
Источник
Zevrant
4 июля 2021 в 16:29
0

Вопрос вполне очевиден, я спрашиваю, как сделать то, что описано выше

Ответы (1)

avatar
O. Jones
4 июля 2021 в 17:58
1

Для обработки потока данных вам потребуется создать фрагментированный MP4. Как и все MP4, потоки fMP4 начинаются с преамбулы, содержащей поля ftyp, moov и styp. Затем каждый кадр кодируется парой блоков moof/mdat.

Чтобы сгенерировать полезную преамбулу из вашего битового потока H.264, вам необходимо найти пару SPS/PPS NALU в данных H264, чтобы настроить блок avc1 в блоке moov. За этими двумя NALU часто сразу следует I-кадр (ключевой кадр). Первый кадр в потоке должен быть I-кадром, а последующие могут быть P- или B-кадрами. Е

Это довольно сложная задача, включающая в себя множество битовых ударов и перетасовку буферов (это технические термины ;-).

Я работал над фрагментом js-кода, чтобы извлечь H.264 из webm и поместить его в fmp4. Он еще не завершен. Он подкреплен другим фрагментом кода для декодирования частей потока H264, необходимых для его правильной упаковки в fMP4.

Я бы хотел написать: "Вот десять строк кода, которые вам нужны", но эти форматы (fMP4 и H264) недостаточно просты, чтобы сделать это возможным.

Zevrant
9 июля 2021 в 18:50
0

Как вы думаете, было бы проще, если бы исходник был предварительно упакован в MP4?

O. Jones
9 июля 2021 в 19:09
0

Если у вас уже есть начало потока fMP4, вы можете пропустить последовательности кадров, если первая сохраненная последовательность кадров начинается с I-кадра (ключевого кадра). Но если у вас нет преамбулы fMP4 (ftyp, moov, styp), вам придется их реконструировать. Вот где кодирование становится сложным.

Zevrant
21 июля 2021 в 19:07
0

может быть немного съедобно, но в итоге я удалил пару SPS / PPS NALU в данных H264 из другого файла (сделанного с использованием точно такого же аппаратного/программного обеспечения, поэтому они должны быть идентичны) и добавил их к первому действительному NALU. я смог найти в потоке, а затем преобразовал его в mp4