Мне наконец-то удалось передать фрагментированный MP4 в расширения MSE для браузера.
Если вы начнете кормить расширения MSE пакетами moof и mdat , которые не пришли сразу после оригинальных ftyp и moov тогда ..
.. самый первый пакет moof , который входит в расширение MSE, должен быть пакетом moof , для которого установлен специальный флаг first_sample_flags_preset (см. Спецификации ISO / IEC 14496-12: 2012 (E) для получения дополнительной информации)
.. в противном случае MSE во всех популярных браузерах зависают и воспроизведение видео не происходит (кстати, moof порядковые номера, начинающиеся с> 1, не создают никаких проблем).
Этот пакет на python был очень полезен для анализа: https://github.com/beardypig/pymp4
Чтобы установить этот флаг, в этом ответе предусмотрены функции JavaScript на стороне клиента.
Используйте функцию getBox , чтобы узнать тип коробки ( ftyp , moov , moof и т. Д.).
Для блоков moof примените функцию findFirstSampleFlag , чтобы увидеть, имеет ли поле moof first_sample_flags_preset .
function toInt(arr, index) { // From bytes to big-endian 32-bit integer. Input: Uint8Array, index
var dv = new DataView(arr.buffer, 0);
return dv.getInt32(index, false); // big endian
}
function toString(arr, fr, to) { // From bytes to string. Input: Uint8Array, start index, stop index.
return String.fromCharCode.apply(null, arr.slice(fr,to));
}
function getBox(arr, i) { // input Uint8Array, start index
return [toInt(arr, i), toString(arr, i+4, i+8)]
}
function getSubBox(arr, box_name) { // input Uint8Array, box name
var i = 0;
res = getBox(arr, i);
main_length = res[0]; name = res[1]; // this boxes length and name
i = i + 8;
var sub_box = null;
while (i < main_length) {
res = getBox(arr, i);
l = res[0]; name = res[1];
if (box_name == name) {
sub_box = arr.slice(i, i+l)
}
i = i + l;
}
return sub_box;
}
function findFirstSampleFlag(arr) { // input Uint8Array
// [moof [mfhd] [traf [tfhd] [tfdt] [trun]]]
var traf = getSubBox(arr, "traf");
if (traf==null) { return false; }
var trun = getSubBox(traf, "trun");
if (trun==null) { return false; }
// ISO/IEC 14496-12:2012(E) .. pages 5 and 57
// bytes: (size 4), (name 4), (version 1 + tr_flags 3)
var flags = trun.slice(10,13); // console.log(flags);
f = flags[1] & 4; // console.log(f);
return f == 4;
}