def test_find_headers_at(): creation_time = utils.to_mp4_time(datetime(2019, 9, 15, 0, 0, 0)) modification_time = utils.to_mp4_time(datetime(2019, 9, 16, 0, 0, 0)) samples_sizes = [198297, 127477, 192476] samples_offset = 10 trak = utils.make_trak(creation_time, modification_time, samples_sizes, samples_offset) # MOOV.TRAK.TKHD tkhd = trak.boxes[0] tkhd.track_id = 1 tkhd.width = [512, 0] tkhd.height = [512, 0] trak.refresh_box_size() buffer = io.BytesIO(bytes(trak)) for (pos, box_size, box_type, header_size), \ box in zip(mp4.find_headers_at(buffer, {b'tkhd', b'mdia'}, offset=trak.header.header_size), utils.find_boxes(trak.boxes, {b'tkhd', b'mdia'})): assert pos < buffer.tell() assert box_size == box.header.box_size assert box_type == box.header.type if isinstance(box.header, headers.FullBoxHeader): assert header_size + 4 == box.header.header_size else: assert header_size == box.header.header_size
def test_get_shape_at(): creation_time = utils.to_mp4_time(datetime(2019, 9, 15, 0, 0, 0)) modification_time = utils.to_mp4_time(datetime(2019, 9, 16, 0, 0, 0)) samples_sizes = [198297, 127477, 192476] samples_offset = 10 trak = utils.make_trak(creation_time, modification_time, samples_sizes, samples_offset) # MOOV.TRAK.TKHD tkhd = trak.boxes[0] tkhd.track_id = 1 tkhd.width = [512, 0] tkhd.height = [512, 0] trak.refresh_box_size() buffer = io.BytesIO(bytes(trak)) assert mp4.get_shape_at(buffer, 0) == utils.get_shape(trak)
def test_make_trak_co64_explicit_offset(): creation_time = utils.to_mp4_time(datetime(2019, 9, 15, 0, 0, 0)) modification_time = utils.to_mp4_time(datetime(2019, 9, 16, 0, 0, 0)) samples_sizes = [198297, 127477, 192476] samples_offsets = [ utils.MAX_UINT_32, utils.MAX_UINT_32 + 300000, utils.MAX_UINT_32 + 2 * 300000 ] trak = utils.make_trak(creation_time, modification_time, samples_sizes, samples_offsets) # MOOV.TRAK.MDIA mdia = trak.boxes[1] # MOOV.TRAK.MDIA.MINF minf = mdia.boxes[2] # MOOV.TRAK.MDIA.MINF.STBL stbl = minf.boxes[2] # MOOV.TRAK.MDIA.MINF.STBL.CO64 stco = stbl.boxes[4] stco.refresh_box_size() assert stco.header.type == b"co64" assert stco.header.box_size == 40 assert stco.header.version == 0 assert stco.header.flags == b"\x00\x00\x00" assert stco.entry_count == 3 assert len(stco.entries) == 3 assert stco.entries[0].chunk_offset == utils.MAX_UINT_32 assert stco.entries[1].chunk_offset == utils.MAX_UINT_32 + 300000 assert stco.entries[2].chunk_offset == utils.MAX_UINT_32 + 2 * 300000 assert bytes(stco) == 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, utils.MAX_UINT_32, utils.MAX_UINT_32 + 300000, utils.MAX_UINT_32 + 2 * 300000)
def test_get_sample_size_at(): creation_time = utils.to_mp4_time(datetime(2019, 9, 15, 0, 0, 0)) modification_time = utils.to_mp4_time(datetime(2019, 9, 16, 0, 0, 0)) samples_sizes = [198297, 127477, 192476] samples_offset = 10 trak = utils.make_trak(creation_time, modification_time, samples_sizes, samples_offset) # MOOV.TRAK.TKHD tkhd = trak.boxes[0] tkhd.track_id = 1 tkhd.width = [512, 0] tkhd.height = [512, 0] trak.refresh_box_size() buffer = io.BytesIO(bytes(trak)) stbl_pos, _, _, _ = mp4.find_sample_table_at(buffer, 0) sz, _ = mp4.get_sample_size_at(buffer, stbl_pos) stbl = utils.get_sample_table(trak) stsz = next(utils.find_boxes(stbl.boxes, {b"stsz"})) assert (sz == [e.entry_size for e in stsz.samples]).all()
def test_find_sample_table_at(): creation_time = utils.to_mp4_time(datetime(2019, 9, 15, 0, 0, 0)) modification_time = utils.to_mp4_time(datetime(2019, 9, 16, 0, 0, 0)) samples_sizes = [198297, 127477, 192476] samples_offset = 10 trak = utils.make_trak(creation_time, modification_time, samples_sizes, samples_offset) # MOOV.TRAK.TKHD tkhd = trak.boxes[0] tkhd.track_id = 1 tkhd.width = [512, 0] tkhd.height = [512, 0] trak.refresh_box_size() buffer = io.BytesIO(bytes(trak)) _, box_size, box_type, header_size = mp4.find_sample_table_at(buffer, 0) stbl = utils.get_sample_table(trak) assert box_size == stbl.header.box_size assert box_type == stbl.header.type assert header_size == stbl.header.header_size
def test_make_trak(): creation_time = utils.to_mp4_time(datetime(2019, 9, 15, 0, 0, 0)) modification_time = utils.to_mp4_time(datetime(2019, 9, 16, 0, 0, 0)) samples_sizes = [198297, 127477, 192476] samples_offset = 10 trak = utils.make_trak(creation_time, modification_time, samples_sizes, samples_offset) assert trak.header.type == b"trak" assert len(trak.boxes) == 2 # MOOV.TRAK.TKHD tkhd = trak.boxes[0] assert tkhd.header.type == b"tkhd" assert tkhd.header.version == 1 assert tkhd.header.flags == b"\x00\x00\x00" assert tkhd.creation_time == creation_time assert tkhd.modification_time == modification_time assert tkhd.track_id == -1 assert tkhd.duration == 60 assert tkhd.layer == 0 assert tkhd.alternate_group == 0 assert tkhd.volume == [0, 0] assert tkhd.matrix == [65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] assert tkhd.width == -1 assert tkhd.height == -1 assert tkhd.is_audio is False # MOOV.TRAK.MDIA mdia = trak.boxes[1] assert mdia.header.type == b"mdia" assert len(mdia.boxes) == 3 # MOOV.TRAK.MDIA.MDHD mdhd = mdia.boxes[0] mdhd.refresh_box_size() assert mdhd.header.type == b"mdhd" assert mdhd.header.box_size == 44 assert mdhd.header.version == 1 assert mdhd.header.flags == b"\x00\x00\x00" assert mdhd.creation_time == creation_time assert mdhd.modification_time == modification_time assert mdhd.timescale == 20 assert mdhd.duration == 60 assert mdhd.language == [21, 14, 4] assert mdhd.pre_defined == 0 assert bytes(mdhd) == \ 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", creation_time, modification_time, 20, 60, 0x1, 21, 14, 4, b"\x00" * 2) # MOOV.TRAK.MDIA.HDLR hdlr = mdia.boxes[1] hdlr.refresh_box_size() assert hdlr.header.type == b"hdlr" assert hdlr.header.box_size == 33 assert hdlr.header.version == 0 assert hdlr.header.flags == b"\x00\x00\x00" assert hdlr.pre_defined == 0 assert hdlr.handler_type == b"____" # TODO: validate the use of the name assert hdlr.name == b"\0" assert bytes(hdlr) == pack( "uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, bytes:4, " "bits:32, bits:32, bits:32, " "bytes:1", 33, b"hdlr", 0, b"\x00\x00\x00", 0, b"____", b"\x00" * 4, b"\x00" * 4, b"\x00" * 4, b"\0") # MOOV.TRAK.MDIA.MINF minf = mdia.boxes[2] assert minf.header.type == b"minf" assert len(minf.boxes) == 3 # MOOV.TRAK.MDIA.MINF._MHD (placeholder) _mhd = minf.boxes[0] _mhd.refresh_box_size() assert _mhd.header.type == b"_mhd" assert _mhd.header.box_size == 8 assert bytes(_mhd) == pack("uintbe:32, bytes:4", 8, b"_mhd") # MOOV.TRAK.MDIA.MINF.DINF dinf = minf.boxes[1] assert dinf.header.type == b"dinf" assert len(dinf.boxes) == 1 # MOOV.TRAK.MDIA.MINF.DINF.DREF dref = dinf.boxes[0] assert dref.header.type == b"dref" assert dref.header.version == 0 assert dref.header.flags == b"\x00\x00\x00" assert dref.entry_count == 1 assert len(dref.boxes) == 1 # MOOV.TRAK.MDIA.MINF.DINF.DREF.URL_ url_ = dref.boxes[0] url_.refresh_box_size() assert url_.header.type == b"url " assert url_.header.box_size == 12 assert url_.header.version == 0 assert url_.header.flags == b"\x00\x00\x01" assert url_.location is None assert bytes(url_) == pack("uintbe:32, bytes:4, uintbe:8, bits:24", 12, b"url ", 0, b"\x00\x00\x01") # MOOV.TRAK.MDIA.MINF.STBL stbl = minf.boxes[2] assert stbl.header.type == b"stbl" assert len(stbl.boxes) == 5 # MOOV.TRAK.MDIA.MINF.STBL.STSD stsd = stbl.boxes[0] stsd.refresh_box_size() assert stsd.header.type == b"stsd" assert stsd.header.box_size == 16 assert stsd.header.version == 0 assert stsd.header.flags == b"\x00\x00\x00" assert stsd.entry_count == 0 assert bytes(stsd) == pack( "uintbe:32, bytes:4, uintbe:8, bits:24, uintbe:32", 16, b"stsd", 0, b"\x00\x00\x00", 0) # MOOV.TRAK.MDIA.MINF.STBL.STTS stts = stbl.boxes[1] stts.refresh_box_size() assert stts.header.type == b"stts" assert stts.header.box_size == 24 assert stts.header.version == 0 assert stts.header.flags == b"\x00\x00\x00" assert stts.entry_count == 1 assert len(stts.entries) == 1 assert stts.entries[0].sample_count == 3 assert stts.entries[0].sample_delta == 20 assert bytes(stts) == pack( "uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, uintbe:32, uintbe:32", 24, b"stts", 0, b"\x00\x00\x00", 1, 3, 20) # MOOV.TRAK.MDIA.MINF.STBL.STSZ stsz = stbl.boxes[2] stsz.refresh_box_size() assert stsz.header.type == b"stsz" assert stsz.header.box_size == 32 assert stsz.header.version == 0 assert stsz.header.flags == b"\x00\x00\x00" assert stsz.sample_size == 0 assert stsz.sample_count == 3 assert len(stsz.samples) == 3 assert stsz.samples[0].entry_size == samples_sizes[0] assert stsz.samples[1].entry_size == samples_sizes[1] assert stsz.samples[2].entry_size == samples_sizes[2] assert bytes(stsz) == pack( "uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32", 32, b"stsz", 0, b"\x00\x00\x00", 0, 3, samples_sizes[0], samples_sizes[1], samples_sizes[2]) # MOOV.TRAK.MDIA.MINF.STBL.STSC stsc = stbl.boxes[3] stsc.refresh_box_size() assert stsc.header.type == b"stsc" assert stsc.header.box_size == 28 assert stsc.header.version == 0 assert stsc.header.flags == b"\x00\x00\x00" assert stsc.entry_count == 1 assert len(stsc.entries) == 1 assert stsc.entries[0].first_chunk == 1 assert stsc.entries[0].samples_per_chunk == 1 assert stsc.entries[0].sample_description_index == 1 assert bytes(stsc) == 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) # MOOV.TRAK.MDIA.MINF.STBL.STCO stco = stbl.boxes[4] stco.refresh_box_size() assert stco.header.type == b"stco" assert stco.header.box_size == 28 assert stco.header.version == 0 assert stco.header.flags == b"\x00\x00\x00" assert stco.entry_count == 3 assert len(stco.entries) == 3 assert stco.entries[0].chunk_offset == samples_offset assert stco.entries[1].chunk_offset == samples_offset + sum( samples_sizes[0:1]) assert stco.entries[2].chunk_offset == samples_offset + sum( samples_sizes[0:2]) assert bytes(stco) == pack( "uintbe:32, bytes:4, uintbe:8, bits:24, " "uintbe:32, " "uintbe:32, uintbe:32, uintbe:32", 28, b"stco", 0, b"\x00\x00\x00", 3, samples_offset, samples_offset + sum(samples_sizes[0:1]), samples_offset + sum(samples_sizes[0:2]))