def test_mvhd_box_v1(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:64, uintbe:64, uintbe:32, uintbe:64, " "uintbe:16, uintbe:16, uintbe:8, uintbe:8, " "bits:16, bits:32, bits:32, " "uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, " "bits:32, bits:32, bits:32, bits:32, bits:32, bits:32, " "uintbe:32", 120, b"mvhd", 1, b"\x00\x00\x00", 3596199850, 3596199850, 48000, 6720608, 1, 0, 1, 0, b"\x00" * 2, b"\x00" * 4, b"\x00" * 4, 65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824, b"\x00" * 4, b"\x00" * 4, b"\x00" * 4, b"\x00" * 4, b"\x00" * 4, b"\x00" * 4, 3) box_header = FullBoxHeader() mvhd = bx_def.MVHD(box_header) mvhd.header.type = b"mvhd" mvhd.header.version = 1 mvhd.header.flags = b"\x00\x00\x00" mvhd.creation_time = 3596199850 mvhd.modification_time = 3596199850 mvhd.timescale = 48000 mvhd.duration = 6720608 mvhd.rate = [1, 0] mvhd.volume = [1, 0] mvhd.matrix = [65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] mvhd.pre_defined = [b"\x00" * 4] * 6 mvhd.next_track_id = 3 mvhd.refresh_box_size() box = mvhd assert box.header.type == b"mvhd" assert box.header.box_size == 120 assert box.header.version == 1 assert box.header.flags == b"\x00\x00\x00" assert box.creation_time == 3596199850 assert box.modification_time == 3596199850 assert box.timescale == 48000 assert box.duration == 6720608 assert box.rate == [1, 0] assert box.volume == [1, 0] assert box.matrix == [65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] assert box.pre_defined == [b"\x00" * 4] * 6 assert box.next_track_id == 3 assert bytes(next(Parser.parse(bs))) == bs.bytes assert bytes(box) == bs.bytes
def test_stsz_box(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, uintbe:32, uintbe:32", 24, b"stsz", 0, b"\x00\x00\x00", 0, 1, 1) box_header = FullBoxHeader() stsz = bx_def.STSZ(box_header) stsz.header.type = b"stsz" stsz.header.version = 0 stsz.header.flags = b"\x00\x00\x00" stsz.sample_size = 0 sample = stsz.append_and_return() sample.entry_size = 1 stsz.refresh_box_size() box = stsz assert box.header.type == b"stsz" assert box.header.box_size == 24 assert box.header.version == 0 assert box.header.flags == b"\x00\x00\x00" assert box.sample_size == 0 assert box.sample_count == 1 assert len(box.samples) == 1 assert box.samples[0].entry_size == 1 parsed_box = next(Parser.parse(bs)) parsed_box.load(bs) assert bytes(parsed_box) == bs.bytes assert bytes(box) == bs.bytes
def make_mvhd(creation_time, modification_time, samples_count): # MOOV.MVHD mvhd = bx_def.MVHD(FullBoxHeader()) mvhd.header.type = b"mvhd" mvhd.header.version = (1, ) mvhd.header.flags = (b"\x00\x00\x00", ) mvhd.creation_time = (creation_time, ) mvhd.modification_time = (modification_time, ) # TODO: 20 units / second (does not necessary means 20 img / sec) mvhd.timescale = (20, ) # total duration in the indicated timescale mvhd.duration = (20 * samples_count, ) # prefered play rate (1x, 2x, 1/2x, ...) mvhd.rate = ([1, 0], ) # prefered volume (1 is full volume) mvhd.volume = ([0, 0], ) # TODO: validate matrix (and check if those are 16.16 floats) mvhd.matrix = ([65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824], ) # TODO: check what pre_defined is mvhd.pre_defined = ([b"\x00" * 4] * 6, ) # == total number of tracks mvhd.next_track_id = (1, ) return mvhd
def test_hdlr_box(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, bytes:4, bits:32, bits:32, bits:32, bytes:19", 51, b"hdlr", 0, b"\x00\x00\x00", 0, b"vide", b"\x00" * 4, b"\x00" * 4, b"\x00" * 4, b"Vireo Eyes v2.4.22\0") box_header = FullBoxHeader() hdlr = bx_def.HDLR(box_header) hdlr.header.type = b"hdlr" hdlr.header.version = 0 hdlr.header.flags = b"\x00\x00\x00" hdlr.pre_defined = 0 hdlr.handler_type = b"vide" hdlr.name = b"Vireo Eyes v2.4.22\0" hdlr.refresh_box_size() box = hdlr assert box.header.type == b"hdlr" assert box.header.box_size == 51 assert box.header.version == 0 assert box.header.flags == b"\x00\x00\x00" assert box.pre_defined == 0 assert box.handler_type == b"vide" assert box.name == b"Vireo Eyes v2.4.22\0" assert bytes(next(Parser.parse(bs))) == bs.bytes assert bytes(box) == bs.bytes
def test_vmhd_box(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:16, uintbe:16, uintbe:16, uintbe:16", 20, b"vmhd", 0, b"\x00\x00\x01", 0, 0, 0, 0) box_header = FullBoxHeader() vmhd = bx_def.VMHD(box_header) vmhd.header.type = b"vmhd" vmhd.header.version = 0 vmhd.header.flags = b"\x00\x00\x01" vmhd.graphicsmode = 0 vmhd.opcolor = [0, 0, 0] vmhd.refresh_box_size() box = vmhd assert box.header.type == b"vmhd" assert box.header.box_size == 20 assert box.header.version == 0 assert box.header.flags == b"\x00\x00\x01" assert box.graphicsmode == 0 assert box.opcolor == [0, 0, 0] assert bytes(next(Parser.parse(bs))) == bs.bytes assert bytes(box) == bs.bytes
def test_dref_box(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, uintbe:32", 16, b"dref", 0, b"\x00\x00\x00", 1) box_header = FullBoxHeader() dref = bx_def.DREF(box_header) dref.header.type = b"dref" dref.header.version = 0 dref.header.flags = b"\x00\x00\x00" dref.entry_count = 1 dref.refresh_box_size() box = dref assert box.header.type == b"dref" assert box.header.box_size == 16 assert box.header.version == 0 assert box.header.flags == b"\x00\x00\x00" assert box.entry_count == 1 assert bytes(box) == bs.bytes
def test_stsd_box(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, uintbe:32", 16, b"stsd", 0, b"\x00\x00\x00", 1) box_header = FullBoxHeader() stsd = bx_def.STSD(box_header) stsd.header.type = b"stsd" stsd.header.version = 0 stsd.header.flags = b"\x00\x00\x00" stsd.entry_count = 1 stsd.refresh_box_size() box = stsd assert box.header.type == b"stsd" assert box.header.box_size == 16 assert box.header.version == 0 assert box.header.flags == b"\x00\x00\x00" assert box.entry_count == 1 assert bytes(box) == bs.bytes
def test_stts_box(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, uintbe:32, uintbe:32", 24, b"stts", 0, b"\x00\x00\x00", 1, 1, 1) box_header = FullBoxHeader() stts = bx_def.STTS(box_header) stts.header.type = b"stts" stts.header.version = 0 stts.header.flags = b"\x00\x00\x00" entry = stts.append_and_return() entry.sample_count = 1 entry.sample_delta = 1 stts.refresh_box_size() box = stts assert box.header.type == b"stts" assert box.header.box_size == 24 assert box.header.version == 0 assert box.header.flags == b"\x00\x00\x00" assert box.entry_count == 1 assert len(box.entries) == 1 assert box.entries[0].sample_count == 1 assert box.entries[0].sample_delta == 1 parsed_box = next(Parser.parse(bs)) parsed_box.load(bs) assert bytes(parsed_box) == bs.bytes assert bytes(box) == bs.bytes
def test_ctts_box_v1(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, uintbe:32, intbe:32", 24, b"ctts", 1, b"\x00\x00\x00", 1, 1, -1) box_header = FullBoxHeader() ctts = bx_def.CTTS(box_header) ctts.header.type = b"ctts" ctts.header.version = 1 ctts.header.flags = b"\x00\x00\x00" entry = ctts.append_and_return() entry.sample_count = 1 entry.sample_offset = (-1, "intbe:32") ctts.refresh_box_size() box = ctts assert box.header.type == b"ctts" assert box.header.box_size == 24 assert box.header.version == 1 assert box.header.flags == b"\x00\x00\x00" assert box.entry_count == 1 assert len(box.entries) == 1 assert box.entries[0].sample_count == 1 assert box.entries[0].sample_offset == -1 parsed_box = next(Parser.parse(bs)) parsed_box.load(bs) assert bytes(parsed_box) == bs.bytes assert bytes(box) == bs.bytes
def test_full_box_header(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24", 100, b"abcd", 1, b"\x00\x00\x07") box_header = Parser.parse_header(bs) full_box_header = FullBoxHeader() full_box_header.extend_header(bs, box_header) del box_header assert full_box_header.start_pos == 0 assert full_box_header.type == b"abcd" assert full_box_header.box_size == 100 assert full_box_header.header_size == 12 assert full_box_header.content_size == 88 assert full_box_header.version == 1 assert full_box_header.flags == b"\x00\x00\x07" assert bytes(full_box_header) == bs.bytes
def test_full_box_header_w_drop(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24", 100, b"abcd", 1, b"\x00\x00\x07") full_box_header = FullBoxHeader() full_box_header.flags = b"\x00\x00\x07" full_box_header.type = b"uuid:benzina\x00\x00\x00\x00\x00\x00\x00\x00" full_box_header.version = 1 full_box_header.box_size = MAX_UINT_32 + 1 full_box_header.type = b"abcd" full_box_header.box_size = 100 full_box_header.refresh_cache() assert full_box_header.type == b"abcd" assert full_box_header.box_size == 100 assert full_box_header.header_size == 12 assert full_box_header.content_size == 88 assert full_box_header.version == 1 assert full_box_header.flags == b"\x00\x00\x07" assert bytes(full_box_header) == bs.bytes
def test_mdhd_box_v1(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:64, uintbe:64, uintbe:32, uintbe:64, " "bits:1, uint:5, uint:5, uint:5, " "bits:16", 44, b"mdhd", 1, b"\x00\x00\x00", 3596199850, 3596199850, 30000, 4200196, 0x1, 21, 14, 4, b"\x00" * 2) box_header = FullBoxHeader() mdhd = bx_def.MDHD(box_header) mdhd.header.type = b"mdhd" mdhd.header.version = 1 mdhd.header.flags = b"\x00\x00\x00" mdhd.creation_time = 3596199850 mdhd.modification_time = 3596199850 mdhd.timescale = 30000 mdhd.duration = 4200196 mdhd.language = [21, 14, 4] mdhd.pre_defined = 0 mdhd.refresh_box_size() box = mdhd assert box.header.type == b"mdhd" assert box.header.box_size == 44 assert box.header.version == 1 assert box.header.flags == b"\x00\x00\x00" assert box.creation_time == 3596199850 assert box.modification_time == 3596199850 assert box.timescale == 30000 assert box.duration == 4200196 assert box.language == [21, 14, 4] assert box.pre_defined == 0 assert bytes(next(Parser.parse(bs))) == bs.bytes assert bytes(box) == bs.bytes
def make_text_trak(creation_time, modification_time, name, samples_sizes, samples_offsets): trak = make_trak(creation_time, modification_time, samples_sizes, samples_offsets) # MOOV.TRAK.MDIA mdia = trak.boxes[-1] # MOOV.TRAK.MDIA.HDLR hdlr = mdia.boxes[1] hdlr.handler_type = (b"text", ) hdlr.name = (name, ) # MOOV.TRAK.MDIA.MINF minf = mdia.boxes[-1] # MOOV.TRAK.MDIA.MINF.NMHD nmhd = bx_def.NMHD(FullBoxHeader()) minf.boxes[0] = nmhd nmhd.header.type = b"nmhd" nmhd.header.version = (0, ) nmhd.header.flags = (b"\x00\x00\x00", ) # MOOV.TRAK.MDIA.MINF.STBL stbl = minf.boxes[-1] # MOOV.TRAK.MDIA.MINF.STBL.STSD stsd = stbl.boxes[0] # MOOV.TRAK.MDIA.MINF.STBL.STSD.STXT stxt = bx_def.STXT(BoxHeader()) stxt.header.type = b"stxt" stxt.data_reference_index = (1, ) stxt.content_encoding = (b'\0', ) stxt.mime_format = (b'text/plain\0', ) stsd.append(stxt) return trak
def test_nmhd_box(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24", 12, b"nmhd", 0, b"\x00\x00\x00") box_header = FullBoxHeader() nmhd = bx_def.NMHD(box_header) nmhd.header.type = b"nmhd" nmhd.header.version = 0 nmhd.header.flags = b"\x00\x00\x00" nmhd.refresh_box_size() box = nmhd assert box.header.type == b"nmhd" assert box.header.box_size == 12 assert box.header.version == 0 assert box.header.flags == b"\x00\x00\x00" assert bytes(next(Parser.parse(bs))) == bs.bytes assert bytes(box) == bs.bytes
def test_co64_box(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, uintbe:64, uintbe:64, uintbe:64", 40, b"co64", 0, b"\x00\x00\x00", 3, 0, 1, 2) box_header = FullBoxHeader() stco = bx_def.CO64(box_header) stco.header.type = b"co64" stco.header.version = 0 stco.header.flags = b"\x00\x00\x00" entry = stco.append_and_return() entry.chunk_offset = 0 entry = stco.append_and_return() entry.chunk_offset = 1 entry = stco.append_and_return() entry.chunk_offset = 2 stco.refresh_box_size() box = stco assert box.header.type == b"co64" assert box.header.box_size == 40 assert box.header.version == 0 assert box.header.flags == b"\x00\x00\x00" assert box.entry_count == 3 assert len(box.entries) == 3 assert box.entries[0].chunk_offset == 0 assert box.entries[1].chunk_offset == 1 assert box.entries[2].chunk_offset == 2 parsed_box = next(Parser.parse(bs)) parsed_box.load(bs) assert bytes(parsed_box) == bs.bytes assert bytes(box) == bs.bytes
def test_elst_box_v1(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, uintbe:64, uintbe:64, uintbe:16, uintbe:16", 36, b"elst", 1, b"\x00\x00\x00", 1, 3000, 0, 1, 0) box_header = FullBoxHeader() elst = bx_def.ELST(box_header) elst.header.type = b"elst" elst.header.version = 1 elst.header.flags = b"\x00\x00\x00" entry = elst.append_and_return() entry.segment_duration = 3000 entry.media_time = 0 entry.media_rate_integer = 1 entry.media_rate_fraction = 0 elst.refresh_box_size() box = elst assert box.header.type == b"elst" assert box.header.box_size == 36 assert box.header.version == 1 assert box.header.flags == b"\x00\x00\x00" assert box.entry_count == 1 assert len(box.entries) == 1 assert box.entries[0].segment_duration == 3000 assert box.entries[0].media_time == 0 assert box.entries[0].media_rate_integer == 1 assert box.entries[0].media_rate_fraction == 0 parsed_box = next(Parser.parse(bs)) parsed_box.load(bs) assert bytes(parsed_box) == bs.bytes assert bytes(box) == bs.bytes
def test_stsc_box(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, uintbe:32, uintbe:32, uintbe:32", 28, b"stsc", 0, b"\x00\x00\x00", 1, 1, 1, 1) box_header = FullBoxHeader() stsc = bx_def.STSC(box_header) stsc.header.type = b"stsc" stsc.header.version = 0 stsc.header.flags = b"\x00\x00\x00" entry = stsc.append_and_return() entry.first_chunk = 1 entry.samples_per_chunk = 1 entry.sample_description_index = 1 stsc.refresh_box_size() box = stsc assert box.header.type == b"stsc" assert box.header.box_size == 28 assert box.header.version == 0 assert box.header.flags == b"\x00\x00\x00" assert box.entry_count == 1 assert len(box.entries) == 1 assert box.entries[0].first_chunk == 1 assert box.entries[0].samples_per_chunk == 1 assert box.entries[0].sample_description_index == 1 parsed_box = next(Parser.parse(bs)) parsed_box.load(bs) assert bytes(parsed_box) == bs.bytes assert bytes(box) == bs.bytes
def test_url__box(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24", 12, b"url ", 0, b"\x00\x00\x01") box_header = FullBoxHeader() url_ = bx_def.URL_(box_header) url_.header.type = b"url " url_.header.version = 0 url_.header.flags = b"\x00\x00\x01" url_.refresh_box_size() box = url_ assert box.header.type == b"url " assert box.header.box_size == 12 assert box.header.version == 0 assert box.header.flags == b"\x00\x00\x01" assert box.location is None assert bytes(next(Parser.parse(bs))) == bs.bytes assert bytes(box) == bs.bytes
def test_tkhd_box_v1(): bs = pack("uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:64, uintbe:64, uintbe:32, " "bits:32, " "uintbe:64, " "bits:32, bits:32, " "uintbe:16, uintbe:16, uintbe:8, uintbe:8, " "bits:16, " "uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, " "uintbe:16, uintbe:16, uintbe:16, uintbe:16", 104, b"tkhd", 1, b"\x00\x00\x07", 3596199850, 3596199850, 1, b"\x00" * 4, 6720313, b"\x00" * 4, b"\x00" * 4, 0, 0, 0, 0, b"\x00" * 2, 65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824, 318, 0, 180, 0) box_header = FullBoxHeader() tkhd = bx_def.TKHD(box_header) tkhd.header.type = b"tkhd" tkhd.header.version = 1 tkhd.header.flags = b"\x00\x00\x07" tkhd.creation_time = 3596199850 tkhd.modification_time = 3596199850 tkhd.track_id = 1 tkhd.duration = 6720313 tkhd.layer = 0 tkhd.alternate_group = 0 tkhd.volume = [0, 0] tkhd.matrix = [65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] tkhd.width = [318, 0] tkhd.height = [180, 0] tkhd.refresh_box_size() box = tkhd assert box.header.type == b"tkhd" assert box.header.box_size == 104 assert box.header.version == 1 assert box.header.flags == b"\x00\x00\x07" assert box.creation_time == 3596199850 assert box.modification_time == 3596199850 assert box.track_id == 1 assert box.duration == 6720313 assert box.layer == 0 assert box.alternate_group == 0 assert box.volume == [0, 0] assert box.matrix == [65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] assert box.width == 318 assert box.height == 180 assert box.is_audio is False assert bytes(next(Parser.parse(bs))) == bs.bytes assert bytes(box) == bs.bytes
def make_trak(creation_time, modification_time, samples_sizes, samples_offsets): # MOOV.TRAK trak = bx_def.TRAK(BoxHeader()) trak.header.type = b"trak" # MOOV.TRAK.TKHD tkhd = bx_def.TKHD(FullBoxHeader()) tkhd.header.type = b"tkhd" tkhd.header.version = (1, ) tkhd.header.flags = (b"\x00\x00\x00", ) tkhd.creation_time = (creation_time, ) tkhd.modification_time = (modification_time, ) tkhd.track_id = (-1, ) tkhd.duration = (20 * len(samples_sizes), ) tkhd.layer = (0, ) tkhd.alternate_group = (0, ) tkhd.volume = ([0, 0], ) # TODO: validate matrix (and check if those are 16.16 floats) tkhd.matrix = ([65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824], ) # TODO: make sure that this is the canvas size tkhd.width = ([-1, 0], ) tkhd.height = ([-1, 0], ) trak.append(tkhd) # # MOOV.TRAK.EDTS # edts = bx_def.EDTS(BoxHeader()) # edts.header.type = b"edts" # # # MOOV.TRAK.EDTS.ELST # elst = bx_def.ELST(FullBoxHeader()) # # elst.header.type = b"elst" # elst.header.version = (1,) # elst.header.flags = (b"\x00\x00\x00",) # # entry = elst.append_and_return() # entry.segment_duration = (60,) # entry.media_time = (0,) # entry.media_rate_integer = (1,) # entry.media_rate_fraction = (0,) # # edts.append(elst) # # trak.append(edts) # MOOV.TRAK.MDIA mdia = bx_def.MDIA(BoxHeader()) mdia.header.type = b"mdia" # MOOV.TRAK.MDIA.MDHD mdhd = bx_def.MDHD(FullBoxHeader()) mdhd.header.type = b"mdhd" mdhd.header.version = (1, ) mdhd.header.flags = (b"\x00\x00\x00", ) mdhd.creation_time = (creation_time, ) mdhd.modification_time = (modification_time, ) mdhd.timescale = (20, ) mdhd.duration = (20 * len(samples_sizes), ) # TODO: check the language code mdhd.language = ([21, 14, 4], ) mdhd.pre_defined = (0, ) mdia.append(mdhd) # MOOV.TRAK.MDIA.HDLR hdlr = bx_def.HDLR(FullBoxHeader()) hdlr.header.type = b"hdlr" hdlr.header.version = (0, ) hdlr.header.flags = (b"\x00\x00\x00", ) hdlr.pre_defined = (0, ) hdlr.handler_type = (b"____", ) hdlr.name = (b"\0", ) mdia.append(hdlr) # MOOV.TRAK.MDIA.MINF minf = bx_def.MINF(BoxHeader()) minf.header.type = b"minf" # MOOV.TRAK.MDIA.MINF._MHD (placeholder) _mhd = bx_def.UnknownBox(BoxHeader()) _mhd.header.type = b"_mhd" minf.append(_mhd) # MOOV.TRAK.MDIA.MINF.DINF dinf = bx_def.DINF(BoxHeader()) dinf.header.type = b"dinf" # MOOV.TRAK.MDIA.MINF.DINF.DREF dref = bx_def.DREF(FullBoxHeader()) dref.header.type = b"dref" dref.header.version = (0, ) dref.header.flags = (b"\x00\x00\x00", ) # MOOV.TRAK.MDIA.MINF.DINF.DREF.URL_ url_ = bx_def.URL_(FullBoxHeader()) url_.header.type = b"url " url_.header.version = (0, ) # TODO: validate that this flags means that the data is in the same file url_.header.flags = (b"\x00\x00\x01", ) dref.append(url_) dinf.append(dref) minf.append(dinf) # MOOV.TRAK.MDIA.MINF.STBL stbl = bx_def.STBL(BoxHeader()) stbl.header.type = b"stbl" # MOOV.TRAK.MDIA.MINF.STBL.STSD stsd = bx_def.STSD(FullBoxHeader()) stsd.header.type = b"stsd" stsd.header.version = (0, ) stsd.header.flags = (b"\x00\x00\x00", ) stbl.append(stsd) # MOOV.TRAK.MDIA.MINF.STBL.STTS stts = bx_def.STTS(FullBoxHeader()) stts.header.type = b"stts" stts.header.version = (0, ) stts.header.flags = (b"\x00\x00\x00", ) entry = stts.append_and_return() # imges count entry.sample_count = (len(samples_sizes), ) # 1 img / sec entry.sample_delta = (20, ) stbl.append(stts) # MOOV.TRAK.MDIA.MINF.STBL.STSZ stsz = bx_def.STSZ(FullBoxHeader()) stsz.header.type = b"stsz" stsz.header.version = (0, ) stsz.header.flags = (b"\x00\x00\x00", ) stsz.sample_size = (0, ) for samples_size in samples_sizes: sample = stsz.append_and_return() sample.entry_size = (samples_size, ) stbl.append(stsz) # MOOV.TRAK.MDIA.MINF.STBL.STSC stsc = bx_def.STSC(FullBoxHeader()) stsc.header.type = b"stsc" stsc.header.version = (0, ) stsc.header.flags = (b"\x00\x00\x00", ) entry = stsc.append_and_return() entry.first_chunk = (1, ) entry.samples_per_chunk = (1, ) entry.sample_description_index = (1, ) stbl.append(stsc) # MOOV.TRAK.MDIA.MINF.STBL.STCO co = bx_def.STCO(FullBoxHeader()) co.header.type = b"stco" co.header.version = (0, ) co.header.flags = (b"\x00\x00\x00", ) for offset in gen_sample_offsets(samples_sizes, samples_offsets): # If the offset gets bigger than 2^32-1, use the 64 bits implementation if offset > MAX_UINT_32: # MOOV.TRAK.MDIA.MINF.STBL.CO64 co = bx_def.CO64(FullBoxHeader()) co.header.type = b"co64" co.header.version = (0, ) co.header.flags = (b"\x00\x00\x00", ) break entry = co.append_and_return() entry.chunk_offset = (offset, ) # If the offset gets bigger than 2^32-1, add again using co64 if isinstance(co, bx_def.CO64): for offset in gen_sample_offsets(samples_sizes, samples_offsets): entry = co.append_and_return() entry.chunk_offset = (offset, ) stbl.append(co) minf.append(stbl) mdia.append(minf) trak.append(mdia) return trak
def parse_box(cls, bstr, header): full_box_header = FullBoxHeader() full_box_header.extend_header(bstr, header) del header return super().parse_box(bstr, full_box_header)
def make_vide_trak(creation_time, modification_time, name, samples_sizes, samples_offsets): trak = make_trak(creation_time, modification_time, samples_sizes, samples_offsets) # MOOV.TRAK.MDIA mdia = trak.boxes[-1] # MOOV.TRAK.MDIA.HDLR hdlr = mdia.boxes[1] hdlr.handler_type = (b"vide", ) hdlr.name = (name, ) # MOOV.TRAK.MDIA.MINF minf = mdia.boxes[-1] # MOOV.TRAK.MDIA.MINF.VMHD vmhd = bx_def.VMHD(FullBoxHeader()) minf.boxes[0] = vmhd vmhd.header.type = b"vmhd" vmhd.header.version = (0, ) # flag is 1 vmhd.header.flags = (b"\x00\x00\x01", ) vmhd.graphicsmode = (0, ) vmhd.opcolor = ([0, 0, 0], ) # MOOV.TRAK.MDIA.MINF stbl = minf.boxes[-1] # MOOV.TRAK.MDIA.MINF.STBL.STSD stsd = stbl.boxes[0] # MOOV.TRAK.MDIA.MINF.STBL.STSD.AVC1 avc1 = bx_def.AVC1(BoxHeader()) avc1.header.type = b"avc1" avc1.data_reference_index = (1, ) avc1.width = (-1, ) avc1.height = (-1, ) avc1.horizresolution = ([72, 0], ) avc1.vertresolution = ([72, 0], ) avc1.frame_count = (1, ) avc1.compressorname = (b'\0' * 32, ) avc1.depth = (24, ) # TODO: implement MOOV.TRAK.MDIA.MINF.STBL.STSD.AVC1.AVCC avcC = bx_def.UnknownBox(BoxHeader()) avcC.header.type = b"avcC" avcC.payload = b'\x01d\x10\x16\xff\xe1\x00\x1bgd\x10\x16\xac\xb8\x10\x02' \ b'\r\xff\x80K\x00N\xb6\xa5\x00\x00\x03\x00\x01\x00\x00\x03' \ b'\x00\x02\x04\x01\x00\x07h\xee\x01\x9cL\x84\xc0' avc1.append(avcC) # MOOV.TRAK.MDIA.MINF.STBL.STSD.AVC1.PASP pasp = bx_def.PASP(BoxHeader()) pasp.header.type = b"pasp" pasp.h_spacing = (1, ) pasp.v_spacing = (1, ) avc1.append(pasp) stsd.append(avc1) return trak