js реализует инкапсуляцию файлов формата MP4 и загрузок

внешний интерфейс алгоритм JavaScript

Примечание. Реализация FLV.js основана на bilibili.

Адрес github flv.js:GitHub.com/Шкала бизнес-аналитики/Юридическая информация…

Формат файла MP4

Обзор

В формате файла MP4 весь видеоконтейнер состоит из нескольких блоков и подблоков, которые в основном делятся на три категории в зависимости от типа блока: тип видео (ftyp), видеоданные (mdat), видео информация (moov). видео информация (moov) используется для описания видеоданных (mdat). (Примечание: есть также основной ящик дляmoof box, поэтому интерпретируются только обычные данные формата MP4,moof boxИспользуется только в потоковом MP4. В потоковом формате MP4, сортировка ящиков, тот же ящикbox bodyФормат содержимого отличается от обычного MP4.Подробнее см.расширять)

Параметры видео (moov) в основном подблокеtrack, каждыйtrackОба представляют собой изменяющуюся во времени медиа-последовательность, единицей времени является сэмпл, который может быть кадром данных или аудио (обратите внимание, что кадр аудио может быть разложен на несколько аудиосэмплов, поэтому звук обычно используется как единица сэмпла). , а не кадр).SampleРасставлены по порядку событий. Каждый сэмпл на дорожке связан сsample description. этоsample descriptiosопределяет, как расшифровать этоsample, например используемый алгоритм сжатия. (Примечание: в настоящее время используется значение 1)

Примечание. В этой статье в основном представлен общий тип файла mp4.

MP4.box

В Javascript все коробки Mp4new Uint8Array()выполнить.

Первые 8 бит поля являются зарезервированными битами, а первые 4 бита из этих 8 битов - это размер данных.Когда значение размера равно 0, это означает, что поле является последним полем файла (существует только вmdat box), когда значение размера равно 1, это означает, что размер поляlarge size(8 бит), реальный размер блока должен быть получен в большом размере (также существует только вmdat boxсередина). Последние 4 цифры - лицевыеbox typeКодировка Юникод. Когда тип равен uuid, это означает, что данные в поле имеют определяемый пользователем тип расширения.

BoxЗависит отheaderа такжеbodyОн хранится в памяти в виде 32-битного 4-байтового целочисленного хранилища, а первые 4 байта (32 бита)box size, следующие 4 бита — это тип коробки.Box bodyМожет состоять из данных или подблоков.

Структура ящика следующая:

Параметры видео и аудио различаются.Как правило, файл MP4 делится на две дорожки, одна дляvideo trak, другойaudio trak. Каждая дорожка имеет идентификатор trakId: 1 для видео и 2 для аудио.

Весь формат файла MP4 выглядит следующим образом

FTYP box

Ftypbox — это четырехсимвольное кодовое слово, используемое для указания типа кодирования, совместимого протокола или использования медиафайла.

В обычном файле MP4ftyp boxТам ровно один, в начале файла.

Через инструмент MP4reader видно, чтоftyp boxСтруктура

Размер блока (4 байта): 0x00000024: длина блока 36 байт;

Тип коробки (4 байта): 0x66747970: ASCII-код «ftyp», тип коробки;

major_brand (4 байта): 0x69736f6d: код ASCII для «isom»;

minor_version (4 байта): 0x00000200: номер версии isom;

совместимые_бренды (12 байт): указывает, что файл совместим с isom, iso2, avc1, mp41. Четыре протокола.

Ftyp больше совместимых протоколов:www.ftyps.com/

Mdat box

Mdat boxсодержитMP4Медиаданные файла, местоположение в файле можно найти вmoovнапротивmoovпозади, потому что мы используем здесьMP4Формат файла используется для записи файлов mp4.Необходим расчет смещения каждого кадра медиаданных в файле.Для облегчения расчета,mdatместоmoovПередний.

Mdat boxФормат данных одиночный и не имеет подблоков. в основном разделеныbox headerа такжеbox body,box headerХранится вbox sizeа такжеbox type(mdat),box bodyВсе медиа-данные хранятся в , а медиа-данные берут выборку в качестве единицы данных.

При использовании здесь, в видеоданных, каждыйsampleэто видеокадр, в котором хранитсяsample, его необходимо обрамить в соответствии с типом данных кадра и сохранить.

H.264Типы данных видеокадра следующие:

Примечание: 1. В текущей реализации набор параметров последовательности не включается в данные I-кадра (sps) и набор параметров изображения (pps).

2. Приведенные выше данные кадра предназначены только для данных видеокадра.

в обычномmp4, перед получением данных необходимо проанализировать расположение данных каждого кадра, данные каждого кадра хранятся в mdat, а информация об этих кадрах вся хранится вstbl boxпоэтому, если вы хотите, чтобы файл mp4 воспроизводился нормально, вам нужно записать всю информацию о данных кадра при записи файла mp4.stbl boxсередина.

Mdat box, может использовать коробкуlarge size, когда данные достаточно велики, чтобы их можно было описать 4 байтами, они будут использоватьсяlarge size. При чтении файла MP4, когдаmdat boxКогда бит размера равен 1, реальныйbox sizeсуществуетlarge size, а также при записи файлов mp4 при необходимостиlarge size, нужно бытьbox sizeбит настроен как 1.

Moov box

Moov boxМедиаинформация хранится в вышеупомянутой stbl, а информация о кадре хранится в упомянутой выше stbl, которая относится к медиаинформации.moov boxвнутри.Moov boxИспользуется для описания мультимедийных данных.

Moov boxВ основном содержитmvhd,trak,mvexТри подбокса.

Mvhd box

Mvhd boxопределяет свойства всего файла


поле длина (байты) описывать
размер 4 Количество байтов в этом атоме заголовка фильма
Типы 4 Mvhd
Версия 1 версия этого атома заголовка фильма
логотип 3 Расширенный флаг заголовка фильма, здесь 0
Время генерации 4 Время начала атома Movie. Базовое время: 01.01.1904, 00:00.
время пересмотра 4 Время ревизии атома Movie. Базовое время: 01.01.1904, 00:00.
Time scale 4 Все описания времени в этом документе даны в единицах
Duration 4 Время воспроизведения мультимедиа
Скорость воспроизведения 4 Скорость, с которой воспроизводится этот фильм. 1.0 - нормальная скорость воспроизведения
громкость воспроизведения 2 Громкость, на которой воспроизводится этот фильм. 1.0 - максимальная громкость
резерв 10 0 здесь
матричная структура 36 Эта матрица определяет отображение между двумя координатными пространствами в этом фильме.
Время предварительного просмотра 4 Время начала предварительного просмотра этого фильма, значение равно 0 при записи файла.
продолжительность предварительного просмотра 4 За единицу берём шкалу времени фильма, продолжительность превью, значение 0 при записи файла
Poster time 4 The time value of the time of the movie poster.
Selection time 4 The time value for the start time of the current selection.
Selection duration 4 The duration of the current selection in movie time scale units.
Текущее время 4 Текущее время
идентификатор следующей дорожки 4 Значение идентификатора следующей добавляемой дорожки. 0 не является допустимым значением идентификатора.

напишите здесьmp4Параметры, которые необходимо передать, следующие:Time scaleа такжеDuration, можно использовать другие значения по умолчанию.

Trak box

ОдинTrack boxОпределение фильмаtrack. одинmovieможет содержать один или несколькоtracks, они независимы друг от друга, и каждый имеет свою собственную временную и пространственную информацию. каждыйtrack boxсвязаны сmdat box.

TrackВ основном для следующих целей:

  1. Содержит ссылки на мультимедийные данные и описания

  2. Включатьmodifier track

  3. Информация об упаковке для потоковых протоколов (hint trak), ссылайтесь на соответствующие носители или повторно используйте ихsample data.Hint tracksа такжеmodifier tracksЦелостность должна быть гарантирована одновременно и хотя бы однимmedia trackсуществовать вместе. Другими словами, даже еслиhint tracksСкопируйте соответствующий носительsample data,media tracksТакже его нельзя получить отhinted movieудалено в.

    При записи mp4 используется только первая цель, поэтому здесь представлены только ссылка и описание медиаданных.

    Коробка trak, как правило, в основном включает в себя коробку tkhd, коробку edts, коробку mdia.

Tkhd box

Информация заголовка, используемая для описания блока дорожки, определяет информацию о времени, пространстве и объеме дорожки.


поле длина (байты) описывать
размер 4 Количество байтов этого атома
Типы 4 tkhd
Версия 1 Версия этого атома
логотип 3 Допустимые флаги: (1) 0x0001 - дорожка (2) 0x0002 - дорожка используется в фильме (3) 0x0004 - дорожка используется в превью фильма 0x0008 - дорожка используется в афише фильма
Время генерации 4 Время начала атома Movie. Базовое время: 01.01.1904, 00:00.
время пересмотра 4 Время ревизии атома Movie. Базовое время: 01.01.1904, 00:00.
Track ID 4 Ненулевое значение, которое однозначно идентифицирует эту дорожку.
резерв 4 0 здесь
Duration 4 Длительность дорожки. Если дорожка является видеотраком, длительность получается из elst. Если elst нет, используется длительность mvhd.
резерв 8 0 здесь
Layer 2 Пространственный приоритет дорожки в ее фильме. QuickTime Movie Toolbox использует это значение, чтобы определить, как дорожки накладываются друг на друга. Дорожки с более низкими значениями слоя отображаются перед дорожками с более высокими значениями слоя.
Alternate group 2 A collection of movie tracks that contain alternate data for oneanother
объем 2 Громкость, с которой воспроизводится этот трек. 1.0 это нормальная громкость
резерв 2 0 здесь
матричная структура 36 Эта матрица определяет отношение отображения между двумя координатными пространствами в этой дорожке.
ширина 4 Если дорожка является видеодорожкой, это значение равно ширине изображения, если это аудио, то 0
высоко 4 Если дорожка является видеодорожкой, это значение является высотой изображения, если это аудио, это 0

Elst box

Коробка естьedst boxУникальный ребенокbox, не все файлы MP4 имеютedst box,этоboxэто сделать его соответствующимtrak boxОтметка времени смещена. Пока не найдено место, где нужно это смещение, и при кодировании бокс не кодировался.

Mdia box

ДолженboxОпределенныйtrak boxтип иsampleИнформация.

Этоheader box--- mdhd boxопределяетboxизtimescaleа такжеduration(Примечание: эти два параметра здесь такие же, как упомянутые ранее.mvhdРазница есть, вот эти два параметра все в одномsampleНапример, за единицу времени: когда есть только одно видеоtrakна случай, если,mvhdизtimescale1000, аsampleизdurationна 40 , то вотtimescale1000/40, и здесь аналогичноdurationАналогично понимаются алгоритмы. )

Hdlr boxопределяет этоtrakКомпонент обработки мультимедиа, на следующем рисунке это поясняется более четко.box

Minf box

Долженboxтакже вышеmdia boxсынbox, который в основном используется для описанияtrakКонкретный компонент обработки мультимедиа контента.

Этоheader boxсогласно сtrakЕсть 2 типаvmhdа такжеsmhd, у них нет специальных данных, просто чтобы определитьheadleтип.

его сынbox --- dinf boxИспользуется для определения того, как компонент обработки мультимедиа получает данные мультимедиа,dinf boxсынbox --- dref boxИспользуется для определения метода ссылки на данные, нет необходимости использовать этотbox, поэтому здесь подробно не объясняется, хотяbox, но при кодированииmp4файл,boxТребуется, за исключением того, что когда он не используется, он будетdrefКоличество ссылочных методов по умолчанию равно 0, а информация, на которую он ссылается, по умолчанию равнаurlИ он может быть пустым.

Stbl box

Sample Table Box(stbl) вышеminfОдин из подблоков, используемый для определения отношения отображения времени хранения/смещения, информация о данных находится в следующих подблоках.boxсередина

stts: Time to Sample Boxметка времени иSampleтаблица сопоставления серийных номеров

stsd: Sample Description BoxФормат, используемый для описания данных, например формат видеоavc, например, аудиоформатaac

stsz, stz2: Sample Size BoxesкаждыйSampleтаблица размеров.Stz2Другойsample sizeАлгоритм хранения более компактен, вы можете использовать один из них, когда используете его, вот использованиеstsz. Причина проста, потому что алгоритм прост.

stsc: Sample to chunkтаблица сопоставления. Этот алгоритм более изобретателен, в несколько разchunk, алгоритм сложнее. Несколько не рассматриваются в этом использованииchunkсостояние, учитывая только весь файл одинchunkСлучай.

stco, co64: каждыйChunkТаблица смещения положения, смещение образца может быть основано на другихboxРассчитано,co64означает 64-битныйchunkСмещение, временно используются только 32 бита, поэтому используйте здесьstcoВот и все.

stss: номер ключевого кадра,boxСуществовать вvideo trak,потому чтоaudio trakКитай и Израильsampleединица, а несколькоsampleФормируется только один кадр аудио, поэтому вaudio trakнет необходимости в этомbox.

выше субboxсуществуетMP4Это особенно важно при кодировании, которое подробно описано впримеробъяснил в

Структурная схема выглядит следующим образом:

Пример:

Анализ фрагмента декапсулированных видеоданных, полученных с URL-адреса

Распакованный метод _parseChunks

Распакованные данные следующие

Приведенные выше данные представляют собой видеоданные, большая часть которых поступает изflvв данных видеопотокаsps.

Id:здесьidОн жестко закодирован при декодировании, когда это данные сегмента видео, id=1, аудио, id=2

chromaFormat: Формат выборки цвета

bitDepth: изображение в оттенках серого

8: 256 цветное растровое изображение

24: Истинный цвет

Level:leve_idcуровень, которого придерживается битовый поток

profile:profile_idcКонфигурация, которой следует битовый поток

MP41.types = {
	avc1: [], avcC: [], btrt: [], dinf: [],
	dref: [], esds: [], ftyp: [], hdlr: [],
	mdat: [], mdhd: [], mdia: [], mfhd: [],
	minf: [], moof: [], moov: [], mp4a: [],
	mvex: [], mvhd: [], sdtp: [], stbl: [],
	stco: [], stsc: [], stsd: [], stsz: [],
	stts: [], tfdt: [], tfhd: [], traf: [],
	trak: [], trun: [], trex: [], tkhd: [],
	vmhd: [], smhd: [], '.mp3': [], free: [],
	edts: [], elst: [], stss: []
};

ОдинMP4Есть выше типы файлов,MP4.typesкаждый изtypeгенералtypeкаждый персонаж изUnicodeЗакодированное значение для последующей переупаковки. Подробнее о коробкеMP4.box

Примечание. Поскольку и декапсуляция, и рекапсуляция здесь верныflvодин изtagоперации, поэтому аудио- и видеоданные обрабатываются отдельно.

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

{
	dts: dts,
	pts: pts,
	cts: cts,
	units: units,
	size: sample.length,
	isKeyframe: isKeyframe,
	duration: sampleDuration,
	originalDts: originalDts,
	flags: {
		isLeading: 0,
		dependsOn: isKeyframe ? 2 : 1,
		isDependedOn: isKeyframe ? 1 : 0,
		hasRedundancy: 0,
		isNonSync: isKeyframe ? 0 : 1
	}
}

внутри кодаmp4В файле используются следующие параметры:units,isKeyframe, записыватьmdatданные от каждогоsampleв данныхunits, при хранении демонстрационных данных необходимо обращать внимание на неглубокую копию объекта, потому что, если используется неглубокая копия,unitsДанные будут пустыми, когда запись будет остановлена, здесь мы используемes6метод глубокого копирования

Object.assign({}, sample.units[i])

Unitsявляется массивом, поэтому используйте для него глубокую копию обхода.

Перед копированием данныхunitОбрамление данных

let DRFlag = new Uint8Array(5);
if (singleSample.isKeyframe === true) {
	let spsFlag = new Uint8Array([0x00, 0x00, 0x00, 0x01, 0x67]);
	let ppsFlag = new Uint8Array([0x00, 0x00, 0x00, 0x01, 0x68]);
	let IDRFlag = new Uint8Array([0x00, 0x00, 0x00, 0x01, 0x65]);
	let spsFlagLen = 5, ppsFlagLen = 5, IDRFlagLen = 5, spsMetaLen = this.spsMeta.byteLength, ppsMetaLen = this.ppsMeta.byteLength;
	DRFlag = new Uint8Array(spsFlagLen + spsMetaLen + ppsFlagLen + ppsMetaLen + IDRFlagLen);
	DRFlag.set(spsFlag, 0);
	DRFlag.set(this.spsMeta, spsFlagLen);
	DRFlag.set(ppsFlag, spsFlagLen + spsMetaLen);
	DRFlag.set(this.ppsMeta, spsFlagLen + spsMetaLen + ppsFlagLen);
	DRFlag.set(IDRFlag, spsFlagLen + spsMetaLen + ppsFlagLen + ppsMetaLen);
} else if (singleSample.isKeyframe === false) {
	DRFlag = new Uint8Array([0x00, 0x00, 0x00, 0x01, 0x61]);
}// todo 音频

let unitData = new Uint8Array(units[i].data.byteLength + 5);
unitData.set(DRFlag, 0);
unitData.set(units[i].data, 5);
units[i].data = new Uint8Array(unitData.byteLength);
units[i].data.set(unitData, 0);

Наконец кодированиеmp4При документировании нужно передать все эти данные черезboxМетод преобразуется в 4-битное 32-разрядное хранилище, и необходимо передать два параметра, один из которых является параметром видео выше, а другой —sampleсписок. Поскольку вам нужно сначала записать длину данных при записи данных в js, вам также необходимо передать кадрированныйsampleсерединаunit dataОбщая длина , эта длина также хранится вsampleСписок обрабатывается одновременно.

let mdatbox = new Uint8Array(mdatBytes + 8);

Итак, есть 3 параметра:

meta, mdatDataList, mdatBytes

Boxзаписывается как:

static box(type) {
    let size = 8;
    let result = null;
    let datas = Array.prototype.slice.call(arguments, 1);
	let arrayCount = datas.length;

	for (let i = 0; i > arrayCount; i++) {
		size += datas[i].byteLength;
	}
	result = new Uint8Array(size);
	result[0] = (size >>> 24) & 0xFF; // size
	result[1] = (size >>> 16) & 0xFF;
	result[2] = (size  >>> 8) & 0xFF;
	result[3] = (size) & 0xFF;

	result.set(type, 4); // type

	let offset = 8;
	for (let i = 0; i > arrayCount; i++) { // data body
		result.set(datas[i], offset);
		offset += datas[i].byteLength;
	}

	return result;
}

TypeдаboxТип , третья строка в методе указывает другие параметры, кроме первого параметра в параметрах сбора,boxЗа исключением первого типа, все остальные параметры должны быть бинарными.arraybufferТипы.

записыватьmp4документblobМетод данных:

static generateInitSegment(meta, mdatDataList, mdatBytes) {

	let ftyp = MP41.box(MP41.types.ftyp, MP41.constants.FTYP);
	let free = MP41.box(MP41.types.free);
	// allocate mdatbox
	let mdatbox = new Uint8Array(mdatBytes + 8);
	mdatbox[0] = (mdatBytes + 8 >>> 24) & 0xFF;
	mdatbox[1] = (mdatBytes + 8 >>> 16) & 0xFF;
	mdatbox[2] = (mdatBytes + 8 >>> 8) & 0xFF;
	mdatbox[3] = (mdatBytes + 8) & 0xFF;
	mdatbox.set(MP41.types.mdat, 4);
	let offset = 8;
	// Write samples into mdatbox
	for (let i = 0; i > mdatDataList.length; i++) {
		mdatDataList[i].chunkOffset = ftyp.byteLength + free.byteLength + offset;
		let units = [], unitLen = mdatDataList[i].units.length;
		for (let j = 0; j > unitLen; j ++) {
			units[j] = Object.assign({}, mdatDataList[i].units[j]);
		}
		while (units.length) {
			let unit = units.shift();
			let data = unit.data;
			mdatbox.set(data, offset);
			offset += data.byteLength;
		}
	}
	let moov = MP41.moov(meta, mdatDataList);
	let result = new Uint8Array(ftyp.byteLength + moov.byteLength +
	mdatbox.byteLength + free.byteLength);
	result.set(ftyp, 0);
	result.set(free, ftyp.byteLength);
	result.set(mdatbox, ftyp.byteLength + free.byteLength);
	result.set(moov, ftyp.byteLength + mdatbox.byteLength +
	free.byteLength);
	return result;
}

С помощью вышеуказанного метода файл mp4 можно записатьblobДанные есть, а потом объясню, что сказатьblobДанные хранятся какmp4файл, ключевой момент здесьhtml5 aодна из этикетокdownloadатрибуты (т.е. не поддерживаются) иwindowвстроенные события (event.initMouseEvent):

_finishRecord(recordMate) {
	let blob = new Blob([recordMate.recordBuffer], {'type': 'application/octet-stream'});
	let url = window.URL.createObjectURL(blob);
	let aLink = window.document.createElement('a');
	aLink.download = recordMate.filename;
	aLink.href = url;
	//创建内置事件并触发
	let evt = window.document.createEvent('MouseEvents');
	evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false,false, false, false, 0, null);
	aLink.dispatchEvent(evt);
	}

выше, весьMP4Файл завершен.

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

Существует проблема:

  1. В настоящее время поддерживается только кодирование видео

расширять

Поток MP4

потоковоеMp4файл, также известный какfmp4документ(fragment MP4), и обычныеMP4файл по сравнению сfmp4Файл имеет следующие характеристики:

  1. довольствоватьсяmetadataдержать отдельно

  2. Trackнезависимо друг от друга

  3. Videoа такжеaudioможно запросить индивидуально

  4. Качество видео может постоянно меняться

  5. TracksДоступно на нескольких языках

  6. Передача без полностью загруженных файлов

    потоковоеMp4каждый в файлеfragmentявляется полнымMP4данные,ftyp boxа такжеMoov boxПривязка, описывающая тип данных, совместимые протоколы и параметры видео. Появляется снова при изменении параметров видеоftyp boxа такжеmoov box.mdat boxИспользуется для хранения данных фрагмента видео,moofиспользуется для описанияmdat,существуетfmp4середина,mdat boxа такжеmoofПривязка есть.

    потоковоеMP4Формат файла следующий:

приложение:

Информация о формате файла MP4:http://www.52rd.com/Blog/wqyuwss/559/

Инструмент анализа структуры MP4 (Mp4Reader):http://jchblog.u.qiniudn.com/software/MP4Reader_v0.9.0.6.zip