def process_chapter_atom(self, atom): elements = self.process_one_level(atom) chap = core.Chapter() for elem in elements: elem_id = elem.get_id() if elem_id == MATROSKA_CHAPTER_TIME_START_ID: # Scale timecode to seconds (float) chap.pos = elem.get_value() / 1000000 / 1000.0 elif elem_id == MATROSKA_CHAPTER_FLAG_ENABLED_ID: chap.enabled = elem.get_value() elif elem_id == MATROSKA_CHAPTER_DISPLAY_ID: # Matroska supports multiple (chapter name, language) pairs for # each chapter, so chapter names can be internationalized. This # logic will only take the last one in the list. for display_elem in self.process_one_level(elem): if display_elem.get_id() == MATROSKA_CHAPTER_STRING_ID: chap.name = display_elem.get_utf8() elif elem_id == MATROSKA_CHAPTER_UID_ID: self.objects_by_uid[elem.get_value()] = chap log.debug(u'Chapter %r found', chap.name) chap.id = len(self.chapters) self.chapters.append(chap)
def __init__(self, file): core.AVContainer.__init__(self) self.samplerate = 1 self.all_streams = [] # used to add meta data to streams self.all_header = [] for i in range(MAXITERATIONS): granule, nextlen = self._parseOGGS(file) if granule == None: if i == 0: # oops, bad file raise ParseError() break elif granule > 0: # ok, file started break # seek to the end of the stream, to avoid scanning the whole file if (os.stat(file.name)[stat.ST_SIZE] > 50000): file.seek(os.stat(file.name)[stat.ST_SIZE] - 49000) # read the rest of the file into a buffer h = file.read() # find last OggS to get length info if len(h) > 200: idx = h.find('OggS') pos = -49000 + idx if idx: file.seek(os.stat(file.name)[stat.ST_SIZE] + pos) while 1: granule, nextlen = self._parseOGGS(file) if not nextlen: break # Copy metadata to the streams if len(self.all_header) == len(self.all_streams): for i in range(len(self.all_header)): # get meta info for key in self.all_streams[i].keys(): if self.all_header[i].has_key(key): self.all_streams[i][key] = self.all_header[i][key] del self.all_header[i][key] if self.all_header[i].has_key(key.upper()): asi = self.all_header[i][key.upper()] self.all_streams[i][key] = asi del self.all_header[i][key.upper()] # Chapter parser if self.all_header[i].has_key('CHAPTER01') and \ not self.chapters: while 1: s = 'CHAPTER%02d' % (len(self.chapters) + 1) if self.all_header[i].has_key(s) and \ self.all_header[i].has_key(s + 'NAME'): pos = self.all_header[i][s] try: pos = int(pos) except ValueError: new_pos = 0 for v in pos.split(':'): new_pos = new_pos * 60 + float(v) pos = int(new_pos) c = self.all_header[i][s + 'NAME'] c = core.Chapter(c, pos) del self.all_header[i][s + 'NAME'] del self.all_header[i][s] self.chapters.append(c) else: break # If there are no video streams in this ogg container, it # must be an audio file. Raise an exception to cause the # factory to fall back to audio.ogg. if len(self.video) == 0: raise ParseError # Copy Metadata from tables into the main set of attributes for header in self.all_header: self._appendtable('VORBISCOMMENT', header)