av01 parsing
This commit is contained in:
parent
5e38691180
commit
fd6867bc57
1 changed files with 46 additions and 9 deletions
55
mp4-tree.js
55
mp4-tree.js
|
@ -49,19 +49,21 @@ class MP4Tree {
|
|||
if (!this.parse_until('trak')) { // if no more tracks in file
|
||||
break;
|
||||
}
|
||||
const curr_track_end = this.idx + this.read_next_head().len;
|
||||
let curr_track_end = this.idx + this.read_next_head().len;
|
||||
this.idx += 8
|
||||
this.parse_into('mdia', 8);
|
||||
this.parse_into('minf', 8);
|
||||
const track_type_head = this.read_next_head().name;
|
||||
let track_type_head = this.read_next_head().name;
|
||||
if (track_type_head == 'smhd' || track_type_head == 'vmhd') {
|
||||
this.parse_into('stbl', 8);
|
||||
this.parse_into('stsd', 16);
|
||||
const media_sample = this.read_next_head().name;
|
||||
let media_sample = this.read_next_head().name;
|
||||
if (media_sample == 'avc1') {
|
||||
this.parse_avc1();
|
||||
} else if (media_sample == 'vp09') {
|
||||
this.parse_vp09();
|
||||
} else if (media_sample == 'av01') {
|
||||
this.parse_av01();
|
||||
} else if (media_sample == 'mp4a') {
|
||||
this.parse_mp4a();
|
||||
} else if (media_sample == 'Opus') {
|
||||
|
@ -80,27 +82,62 @@ class MP4Tree {
|
|||
// ex, 01 64 00 1f
|
||||
// 01 is avc version (always 1, bit-and it off)
|
||||
// rest is video codec profile, rep as hex
|
||||
const avc_profile = (this.data.getUint32(this.idx) & 0xffffff).toString(16);
|
||||
let avc_profile = (this.data.getUint32(this.idx) & 0xffffff).toString(16);
|
||||
this.codecs.push('avc1.' + avc_profile);
|
||||
}
|
||||
|
||||
parse_vp09() {
|
||||
this.parse_into('vp09', 86);
|
||||
this.parse_into('vpcC', 12);
|
||||
const profile = this.data.getUint8(this.idx).toString().padStart(2, "0");
|
||||
const level = this.data.getUint8(this.idx + 1).toString();
|
||||
const depth = (this.data.getUint8(this.idx + 2) >> 4).toString().padStart(2, "0");
|
||||
let profile = this.data.getUint8(this.idx).toString().padStart(2, "0");
|
||||
let level = this.data.getUint8(this.idx + 1).toString();
|
||||
let depth = (this.data.getUint8(this.idx + 2) >> 4).toString().padStart(2, "0");
|
||||
this.codecs.push(["vp09", profile, level, depth].join('.'));
|
||||
}
|
||||
|
||||
parse_av01() {
|
||||
this.parse_into('av01', 101);
|
||||
this.parse_into('av1C', 8);
|
||||
let tmp = this.data.getUint8(this.idx + 1);
|
||||
let profile = tmp >> 5;
|
||||
let level = tmp & 0x1f;
|
||||
let tmp = this.data.getUint8(this.idx + 2);
|
||||
switch (tmp >> 7) {
|
||||
case 0:
|
||||
let level_profile = "M";
|
||||
break;
|
||||
case 1:
|
||||
let level_profile = "H";
|
||||
break;
|
||||
default:
|
||||
let level_profile = "";
|
||||
}
|
||||
let depth_bits = (tmp >> 5) & 0x3;
|
||||
switch (depth_bits) {
|
||||
case 0:
|
||||
let bit_depth = "8";
|
||||
break;
|
||||
case 1:
|
||||
let bit_depth = "12";
|
||||
break;
|
||||
case 2:
|
||||
let bit_depth = "10";
|
||||
break;
|
||||
default:
|
||||
let bit_depth = "0";
|
||||
break;
|
||||
}
|
||||
this.codecs.push(["av01", profile, level.toString().padStart(2, "0") + level_profile, bit_depth].join('.'))
|
||||
}
|
||||
|
||||
parse_mp4a() {
|
||||
this.parse_into('mp4a', 36); // 28 bytes of subboxes with unclear offsets
|
||||
this.parse_into('esds', 12);
|
||||
// mp4a is as mp4a.40.2
|
||||
// oti has defined position, rep as hex
|
||||
// aot as a subtype is defined as 5 bits of the fetched byte, rep as dec
|
||||
const oti = this.data.getUint8(this.idx + 13).toString(16);
|
||||
const aot = (this.data.getUint8(this.idx + 31) >> 3).toString(10);
|
||||
let oti = this.data.getUint8(this.idx + 13).toString(16);
|
||||
let aot = (this.data.getUint8(this.idx + 31) >> 3).toString(10);
|
||||
this.codecs.push(["mp4a", oti, aot].join('.'));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue