def find_media_segments(self, reader: ByteReader) -> List[MediaSegment]: try: ebml_id, size = read_element_header(reader) assert ebml_id == 0x1A45DFA3 reader.skip(size) segment_id, _ = read_element_header(reader) assert segment_id == 0x18538067 segment_reader = RegionByteReader(reader, reader.position, size=None) segment_info = next(element for element in iter_elements(segment_reader) if element.element_id == 0x1549A966) timestamp_scale = next( (element for element in iter_elements(segment_info.reader) if element.element_id == 0x2AD7B1), None) timestamp_scale_value = read_uint( timestamp_scale.reader ) if timestamp_scale is not None else 1000000 clusters = [ Cluster(element, timestamp_scale_value) for element in iter_elements(segment_reader) if element.element_id == 0x1F43B675 ] return [ MediaSegment(offset=cluster.element.offset, size=cluster.element.full_size, time=cluster.timestamp) for cluster in clusters ] finally: reader.close()
def __init__(self, reader: ByteReader): self.offset = reader.position size = parse_big_endian_number(reader.read(4)) kind = reader.read(4) if size == 1: size = parse_big_endian_number(reader.read(8)) elif size == 0: size = reader.end - reader.position if kind == b"uuid": kind += reader.read(16) content_offset = reader.position content_size = size - (content_offset - self.offset) self.kind = kind self.full_size = size self.reader = RegionByteReader(reader, content_offset, content_size) reader.skip(content_size)
def iter_elements(reader: ByteReader): while not reader.ended: element = read_element(reader) yield element reader.skip(element.reader.size)