def parse(self): if not self.root: self.root = RootBox() size = self.reader.read32() type = self.reader.read32_as_str() while not self.reader.reached_eof(): if type == "ftyp": self.root.ftyp = parse_typ(self.reader, size, FileTypeBox) elif type == "styp": self.root.styp = parse_typ(self.reader, size, SegmentTypeBox) elif type == "moov": self.root.moov = parse_moov(self.reader, size) elif type == "free": self.root.free = parse_free(self.reader, size) elif type == "mdat": self.root.mdats.append(parse_mdat(self.reader, size)) elif type == "PLEP": self.root.plep = parse_plep(self.reader, size) else: raise InvalidBoxError("type %s unknown" % type, None) if self.reader.reached_eof(): break # At the end of current box parsing, the file pointer will be # ready to read the size and type of the next box size = self.reader.read32() type = self.reader.read32_as_str()
def parse_stbl(reader, my_size): box = SampleTableBox(my_size) cnt = 8 while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == 'stsd': box.stsd = parse_stsd(reader, size) elif type == 'stts': box.stts = parse_stts(reader, size) elif type == 'ctts': box.ctts = parse_ctts(reader, size) elif type == 'stss': box.stss = parse_stss(reader, size) elif type == 'stsc': box.stsc = parse_stsc(reader, size) elif type == 'stsz': box.stsz = parse_stsz(reader, size) elif type == 'stco': box.stco = parse_stco(reader, size) else: raise InvalidBoxError("type %s is unknown" % type, None) return box
def parse_dinf(reader, my_size): box = DataInformationBox(my_size) cnt = 8 while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == 'dref': box.dref = parse_dref(reader, size) else: raise InvalidBoxError('type %s unknown' % type, None) return box
def parse_edts(reader, my_size): box = EditBox(my_size) cnt = 8 while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == 'elst': box.elts = parse_elst(reader, size) else: raise InvalidBoxError("type %s unknown" % type, None) return box
def parse_avc1(reader, my_size): box = AVC1Box(my_size) reader.skip(6) # reserved box.data_ref_index = reader.read16() box.vid_enc_version = reader.read16() box.vid_enc_revision_lvl = reader.read16() box.vid_enc_vendor = reader.read32_as_str() box.vid_temporal_quality = reader.read32() box.vid_spatial_quality = reader.read32() # box.vid_frame_pixel_size = reader.read32() # box.vid_resolution = reader.read64() box.vid_width = reader.read16() box.vid_height = reader.read16() box.vid_horiz_resolution = reader.read32() box.vid_vert_resolution = reader.read32() box.vid_data_size = reader.read32() box.vid_frame_count = reader.read16() box.vid_enc_name_len = reader.read8() box.vid_enc_name = reader.readn_as_str(box.vid_enc_name_len) if box.vid_enc_name_len < 31: # if the encoder name is less than 31, then pad with 0s box.vid_enc_name = box.vid_enc_name + "0" * (31 - box.vid_enc_name_len) reader.skip(31 - box.vid_enc_name_len) box.vid_pixel_depth = reader.read16() box.vid_color_tbl_id = reader.read16() cnt = 86 # avc1 len + name + number of bytes parsed above while not reader.reached_eof(): # Encountered a problem,At the end , only 4 bytes are left, # which does not meet the fourcc standard, just skip it at this time if cnt > my_size - 8: reader.skip(my_size - cnt) break size = reader.read32() type = reader.read32_as_str() cnt += size if type == "avcC": box.avcc = parse_avcc(reader, size) elif type == "btrt": box.btrt = parse_btrt(reader, size) elif type == "colr": box.colr = parse_colr(reader, size) elif type == "pasp": box.pasp = parse_pasp(reader, size) else: raise InvalidBoxError("type %s is unknown" % type, None) return box
def parse_stsd(reader, my_size): version = reader.read32() box = SampleDescriptionBox(my_size, version, 0) box.entry_count = reader.read32() size = reader.read32() type = reader.read32_as_str() if type == "avc1": box.avc1 = parse_avc1(reader, size) elif type == "mp4a": box.mp4a = parse_mp4a(reader, size) else: raise InvalidBoxError("type %s unknown" % type, None) return box
def parse_moof(reader, my_size): box = MovieFragmentBox(my_size) cnt = 8 while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == "mfhd": box.mvhd = parse_mfhd(reader, size) elif type == "traf": box.traf = parse_traf(reader, size) else: raise InvalidBoxError("type %s unknown" % type, None) return box
def parse_traf(reader, my_size): box = TrackFragmentBox(reader, my_size) cnt = 8 while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == 'tfhd': box.tfhd = parse_tfhd(reader, size) elif type == 'tfdt': box.tfdt = parse_tfdt(reader, size) elif type == 'trun': box.trun.append(parse_trun(reader, size)) else: raise InvalidBoxError("type %s unknown" % type, None) return box
def parse_mdia(reader, my_size): box = MediaBox(my_size) cnt = 8 while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == "mdhd": box.mdhd = parse_mdhd(reader, size) elif type == "hdlr": box.hdlr = parse_hdlr(reader, size) elif type == "minf": box.minf = parse_minf(reader, size) else: raise InvalidBoxError("type %s unknown" % type, None) return box
def parse_minf(reader, my_size): box = MediaInformationBox(my_size) cnt = 8 while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == "vmhd": box.vmhd = parse_vmhd(reader, size) elif type == "dinf": box.dinf = parse_dinf(reader, size) elif type == "stbl": box.stbl = parse_stbl(reader, size) elif type == "smhd": box.smhd = parse_smhd(reader, size) else: raise InvalidBoxError("type %s unknown" % type, None) return box
def parse_moov(reader, my_size): box = MovieBox(my_size) cnt = 8 while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == "mvhd": box.mvhd = parse_mvhd(reader, size) elif type == "trak": box.traks.append(parse_trak(reader, size)) elif type == "iods": box.iods = parse_iods(reader, size) elif type == "udta": box.udta = parse_udta(reader, size) else: raise InvalidBoxError("type %s unknown" % type, None) return box
def parse_avc1(reader, my_size): box = AVC1Box(my_size) reader.skip(6) #reserved box.data_ref_index = reader.read16() box.vid_enc_version = reader.read16() box.vid_enc_revision_lvl = reader.read16() box.vid_enc_vendor = reader.read32_as_str() box.vid_temporal_quality = reader.read32() box.vid_spatial_quality = reader.read32() box.vid_frame_pixel_size = reader.read32() box.vid_resolution = reader.read64() box.vid_data_size = reader.read32() box.vid_frame_count = reader.read16() box.vid_enc_name_len = reader.read8() box.vid_enc_name = reader.readn_as_str(box.vid_enc_name_len) if box.vid_enc_name_len < 31: #if the encoder name is less than 31, then pad with 0s box.vid_enc_name = box.vid_enc_name + '0' * (31 - box.vid_enc_name_len) reader.skip(31 - box.vid_enc_name_len) box.vid_pixel_depth = reader.read16() box.vid_color_tbl_id = reader.read16() cnt = 86 #avc1 len + name + number of bytes parsed above while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == 'avcC': box.avcc = parse_avcc(reader, size) elif type == 'btrt': box.btrt = parse_btrt(reader, size) elif type == 'colr': box.colr = parse_colr(reader, size) elif type == 'pasp': box.pasp = parse_pasp(reader, size) else: raise InvalidBoxError("type %s is unknown" % type, None) return box
def parse_dref(reader, my_size): version = reader.read32() box = DataReferenceBox(my_size, version, 0) box.entry_count = reader.read32() cnt = 16 # dref len + name + version + entry_count while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == "url ": # TODO abhi: not implemented right now # box.url = parse_url() box.data_entries.append(parse_url(reader, size)) elif type == "urn ": # TODO abhi: call the parse_urn() function here raise NotImplementedError else: raise InvalidBoxError("type %s unknown" % type, None) return box
def parse_trak(reader, my_size): box = TrackBox(my_size) cnt = 8 while not reader.reached_eof() and cnt < my_size: size = reader.read32() type = reader.read32_as_str() cnt += size if type == "tkhd": box.tkhd = parse_tkhd(reader, size) box.id = box.tkhd.track_id elif type == "edts": box.edts = parse_edts(reader, size) elif type == "mdia": box.mdia = parse_mdia(reader, size) if box.mdia.minf.smhd is None: box.is_video = True else: box.is_audio = True elif type == "udta": box.udta = parse_udta(reader, size) else: raise InvalidBoxError("type %s unknown" % type, None) return box