def process_audio_track(self, elements): track = core.AudioStream() track.codec = u'Unknown' self.set_track_defaults(track) for elem in elements: elem_id = elem.get_id() if elem_id == MATROSKA_CODEC_ID: track.codec = elem.get_str() elif elem_id == MATROSKA_AUDIO_SETTINGS_ID: for settings_elem in self.process_one_level(elem): settings_elem_id = settings_elem.get_id() if settings_elem_id == MATROSKA_AUDIO_SAMPLERATE_ID: track.samplerate = settings_elem.get_float_value() elif settings_elem_id == MATROSKA_AUDIO_CHANNELS_ID: track.channels = settings_elem.get_value() else: self.process_track_common(elem, track) if track.codec in FOURCCMap: track.codec = FOURCCMap[track.codec] elif '/' in track.codec and track.codec.split( '/')[0] + '/' in FOURCCMap: track.codec = FOURCCMap[track.codec.split('/')[0] + '/'] elif track.codec.startswith('A_'): track.codec = track.codec[2:] track.id = len(self.audio) self.audio.append(track) return track
def _parseSTRF(self, t, strh): fccType = strh['fccType'] retval = {} if fccType == 'auds': ( retval['wFormatTag'], retval['nChannels'], retval['nSamplesPerSec'], retval['nAvgBytesPerSec'], retval['nBlockAlign'], retval['nBitsPerSample'], ) = struct.unpack('<HHHHHH', t[0:12]) ai = core.AudioStream() ai.samplerate = retval['nSamplesPerSec'] ai.channels = retval['nChannels'] # FIXME: Bitrate calculation is completely wrong. #ai.samplebits = retval['nBitsPerSample'] #ai.bitrate = retval['nAvgBytesPerSec'] * 8 # TODO: set code if possible # http://www.stats.uwa.edu.au/Internal/Specs/DXALL/FileSpec/\ # Languages # ai.language = strh['wLanguage'] ai.codec = retval['wFormatTag'] self.audio.append(ai) elif fccType == 'vids': v = struct.unpack('<IIIHH', t[0:16]) ( retval['biSize'], retval['biWidth'], retval['biHeight'], retval['biPlanes'], retval['biBitCount'], ) = v v = struct.unpack('IIIII', t[20:40]) ( retval['biSizeImage'], retval['biXPelsPerMeter'], retval['biYPelsPerMeter'], retval['biClrUsed'], retval['biClrImportant'], ) = v vi = core.VideoStream() vi.codec = t[16:20] vi.width = retval['biWidth'] vi.height = retval['biHeight'] # FIXME: Bitrate calculation is completely wrong. #vi.bitrate = strh['dwRate'] vi.fps = float(strh['dwRate']) / strh['dwScale'] vi.length = strh['dwLength'] / vi.fps self.video.append(vi) return retval
def _read_header(self, object_id, s): if object_id == 'PROP': prop = struct.unpack('>9IHH', s) log.debug('PROP: %r' % prop) if object_id == 'MDPR': mdpr = struct.unpack('>H7I', s[:30]) log.debug('MDPR: %r' % mdpr) self.length = mdpr[7] / 1000.0 (stream_name_size, ) = struct.unpack('>B', s[30:31]) stream_name = s[31:31 + stream_name_size] pos = 31 + stream_name_size (mime_type_size, ) = struct.unpack('>B', s[pos:pos + 1]) mime = s[pos + 1:pos + 1 + mime_type_size] pos += mime_type_size + 1 (type_specific_len, ) = struct.unpack('>I', s[pos:pos + 4]) type_specific = s[pos + 4:pos + 4 + type_specific_len] pos += 4 + type_specific_len if mime[:5] == 'audio': ai = core.AudioStream() ai.id = mdpr[0] ai.bitrate = mdpr[2] self.audio.append(ai) elif mime[:5] == 'video': vi = core.VideoStream() vi.id = mdpr[0] vi.bitrate = mdpr[2] self.video.append(vi) else: log.debug('Unknown: %r' % mime) if object_id == 'CONT': pos = 0 (title_len, ) = struct.unpack('>H', s[pos:pos + 2]) self.title = s[2:title_len + 2] pos += title_len + 2 (author_len, ) = struct.unpack('>H', s[pos:pos + 2]) self.artist = s[pos + 2:pos + author_len + 2] pos += author_len + 2 (copyright_len, ) = struct.unpack('>H', s[pos:pos + 2]) self.copyright = s[pos + 2:pos + copyright_len + 2] pos += copyright_len + 2 (comment_len, ) = struct.unpack('>H', s[pos:pos + 2]) self.comment = s[pos + 2:pos + comment_len + 2]
class MPEG4(core.AVContainer): """ Parser for the MP4 container format. This format is mostly identical to Apple Quicktime and 3GP files. It maps to mp4, mov, qt and some other extensions. """ table_mapping = {'QTUDTA': QTUDTA} def __init__(self, file): core.AVContainer.__init__(self) self._references = [] self.mime = 'video/quicktime' self.type = 'Quicktime Video' h = file.read(8) try: (size, type) = struct.unpack('>I4s', h) except struct.error: # EOF. raise ParseError() if type == 'ftyp': # file type information if size >= 12: # this should always happen if file.read(4) != 'qt ': # not a quicktime movie, it is a mpeg4 container self.mime = 'video/mp4' self.type = 'MPEG-4 Video' size -= 4 file.seek(size - 8, 1) h = file.read(8) (size, type) = struct.unpack('>I4s', h) while type in ['mdat', 'skip']: # movie data at the beginning, skip file.seek(size - 8, 1) h = file.read(8) (size, type) = struct.unpack('>I4s', h) if not type in ['moov', 'wide', 'free']: log.debug(u'invalid header: %r' % type) raise ParseError() # Extended size if size == 1: size = struct.unpack('>Q', file.read(8)) # Back over the atom header we just read, since _readatom expects the # file position to be at the start of an atom. file.seek(-8, 1) while self._readatom(file): pass if self._references: self._set('references', self._references) def _readatom(self, file): s = file.read(8) if len(s) < 8: return 0 atomsize, atomtype = struct.unpack('>I4s', s) if not str(atomtype).decode('latin1').isalnum(): # stop at nonsense data return 0 log.debug(u'%r [%X]' % (atomtype, atomsize)) if atomtype == 'udta': # Userdata (Metadata) pos = 0 tabl = {} i18ntabl = {} atomdata = file.read(atomsize - 8) while pos < atomsize - 12: (datasize, datatype) = struct.unpack('>I4s', atomdata[pos:pos + 8]) if ord(datatype[0]) == 169: # i18n Metadata... mypos = 8 + pos while mypos + 4 < datasize + pos: # first 4 Bytes are i18n header (tlen, lang) = struct.unpack('>HH', atomdata[mypos:mypos + 4]) i18ntabl[lang] = i18ntabl.get(lang, {}) l = atomdata[mypos + 4:mypos + tlen + 4] i18ntabl[lang][datatype[1:]] = l mypos += tlen + 4 elif datatype == 'WLOC': # Drop Window Location pass else: if ord(atomdata[pos + 8:pos + datasize][0]) > 1: tabl[datatype] = atomdata[pos + 8:pos + datasize] pos += datasize if len(i18ntabl.keys()) > 0: for k in i18ntabl.keys(): if QTLANGUAGES.has_key(k) and QTLANGUAGES[k] == 'en': self._appendtable('QTUDTA', i18ntabl[k]) self._appendtable('QTUDTA', tabl) else: log.debug(u'NO i18') self._appendtable('QTUDTA', tabl) elif atomtype == 'trak': atomdata = file.read(atomsize - 8) pos = 0 trackinfo = {} tracktype = None while pos < atomsize - 8: (datasize, datatype) = struct.unpack('>I4s', atomdata[pos:pos + 8]) if datatype == 'tkhd': tkhd = struct.unpack('>6I8x4H36xII', atomdata[pos + 8:pos + datasize]) trackinfo['width'] = tkhd[10] >> 16 trackinfo['height'] = tkhd[11] >> 16 trackinfo['id'] = tkhd[3] try: # XXX Timestamp of Seconds is since January 1st 1904! # XXX 2082844800 is the difference between Unix and # XXX Apple time. FIXME to work on Apple, too self.timestamp = int(tkhd[1]) - 2082844800 except Exception, e: log.exception(u'There was trouble extracting timestamp') elif datatype == 'mdia': pos += 8 datasize -= 8 log.debug(u'--> mdia information') while datasize: mdia = struct.unpack('>I4s', atomdata[pos:pos + 8]) if mdia[1] == 'mdhd': # Parse based on version of mdhd header. See # http://wiki.multimedia.cx/index.php?title=QuickTime_container#mdhd ver = ord(atomdata[pos + 8]) if ver == 0: mdhd = struct.unpack('>IIIIIhh', atomdata[pos + 8:pos + 8 + 24]) elif ver == 1: mdhd = struct.unpack('>IQQIQhh', atomdata[pos + 8:pos + 8 + 36]) else: mdhd = None if mdhd: # duration / time scale trackinfo['length'] = mdhd[4] / mdhd[3] if mdhd[5] in QTLANGUAGES: trackinfo['language'] = QTLANGUAGES[mdhd[5]] # mdhd[6] == quality self.length = max(self.length, mdhd[4] / mdhd[3]) elif mdia[1] == 'minf': # minf has only atoms inside pos -= (mdia[0] - 8) datasize += (mdia[0] - 8) elif mdia[1] == 'stbl': # stbl has only atoms inside pos -= (mdia[0] - 8) datasize += (mdia[0] - 8) elif mdia[1] == 'hdlr': hdlr = struct.unpack('>I4s4s', atomdata[pos + 8:pos + 8 + 12]) if hdlr[1] == 'mhlr': if hdlr[2] == 'vide': tracktype = 'video' if hdlr[2] == 'soun': tracktype = 'audio' elif mdia[1] == 'stsd': stsd = struct.unpack('>2I', atomdata[pos + 8:pos + 8 + 8]) if stsd[1] > 0: codec = atomdata[pos + 16:pos + 16 + 8] codec = struct.unpack('>I4s', codec) trackinfo['codec'] = codec[1] if codec[1] == 'jpeg': tracktype = 'image' elif mdia[1] == 'dinf': dref = struct.unpack('>I4s', atomdata[pos + 8:pos + 8 + 8]) log.debug(u' --> %r, %r (useless)' % mdia) if dref[1] == 'dref': num = struct.unpack('>I', atomdata[pos + 20:pos + 20 + 4])[0] rpos = pos + 20 + 4 for ref in range(num): # FIXME: do somthing if this references ref = struct.unpack('>I3s', atomdata[rpos:rpos + 7]) data = atomdata[rpos + 7:rpos + ref[0]] rpos += ref[0] else: if mdia[1].startswith('st'): log.debug(u' --> %r, %r (sample)' % mdia) elif mdia[1] == 'vmhd' and not tracktype: # indicates that this track is video tracktype = 'video' elif mdia[1] in ['vmhd', 'smhd'] and not tracktype: # indicates that this track is audio tracktype = 'audio' else: log.debug(u' --> %r, %r (unknown)' % mdia) pos += mdia[0] datasize -= mdia[0] elif datatype == 'udta': log.debug(u'udta: %r' % struct.unpack('>I4s', atomdata[:8])) else: if datatype == 'edts': log.debug(u'--> %r [%d] (edit list)' % \ (datatype, datasize)) else: log.debug(u'--> %r [%d] (unknown)' % \ (datatype, datasize)) pos += datasize info = None if tracktype == 'video': info = core.VideoStream() self.video.append(info) if tracktype == 'audio': info = core.AudioStream() self.audio.append(info) if info: for key, value in trackinfo.items(): setattr(info, key, value)
def _parseHeader(self, header, granule): headerlen = len(header) flags = ord(header[0]) if headerlen >= 30 and header[1:7] == 'vorbis': ai = core.AudioStream() ai.version, ai.channels, ai.samplerate, bitrate_max, ai.bitrate, \ bitrate_min, blocksize, framing = \ struct.unpack('<IBIiiiBB', header[7:7 + 23]) ai.codec = 'Vorbis' #ai.granule = granule #ai.length = granule / ai.samplerate self.audio.append(ai) self.all_streams.append(ai) elif headerlen >= 7 and header[1:7] == 'theora': # Theora Header # XXX Finish Me vi = core.VideoStream() vi.codec = 'theora' self.video.append(vi) self.all_streams.append(vi) elif headerlen >= 142 and \ header[1:36] == 'Direct Show Samples embedded in Ogg': # Old Directshow format # XXX Finish Me vi = core.VideoStream() vi.codec = 'dshow' self.video.append(vi) self.all_streams.append(vi) elif flags & PACKET_TYPE_BITS == PACKET_TYPE_HEADER and \ headerlen >= struct.calcsize(STREAM_HEADER_VIDEO) + 1: # New Directshow Format htype = header[1:9] if htype[:5] == 'video': sh = header[9:struct.calcsize(STREAM_HEADER_VIDEO) + 9] streamheader = struct.unpack(STREAM_HEADER_VIDEO, sh) vi = core.VideoStream() (type, ssize, timeunit, samplerate, vi.length, buffersize, \ vi.bitrate, vi.width, vi.height) = streamheader vi.width /= 65536 vi.height /= 65536 # XXX length, bitrate are very wrong vi.codec = type vi.fps = 10000000 / timeunit self.video.append(vi) self.all_streams.append(vi) elif htype[:5] == 'audio': sha = header[9:struct.calcsize(STREAM_HEADER_AUDIO) + 9] streamheader = struct.unpack(STREAM_HEADER_AUDIO, sha) ai = core.AudioStream() (type, ssize, timeunit, ai.samplerate, ai.length, buffersize, \ ai.bitrate, ai.channels, bloc, ai.bitrate) = streamheader self.samplerate = ai.samplerate log.debug(u'Samplerate %d' % self.samplerate) self.audio.append(ai) self.all_streams.append(ai) elif htype[:4] == 'text': subtitle = core.Subtitle() # FIXME: add more info self.subtitles.append(subtitle) self.all_streams.append(subtitle) else: log.debug(u'Unknown Header')
def __init__(self, file): core.AVContainer.__init__(self) self.mime = 'video/flv' self.type = 'Flash Video' data = file.read(13) if len(data) < 13 or struct.unpack('>3sBBII', data)[0] != 'FLV': raise ParseError() for _ in range(10): if self.audio and self.video: break data = file.read(11) if len(data) < 11: break chunk = struct.unpack('>BH4BI', data) size = (chunk[1] << 8) + chunk[2] if chunk[0] == FLV_TAG_TYPE_AUDIO: flags = ord(file.read(1)) if not self.audio: a = core.AudioStream() a.channels = (flags & FLV_AUDIO_CHANNEL_MASK) + 1 srate = (flags & FLV_AUDIO_SAMPLERATE_MASK) a.samplerate = ( 44100 << (srate >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3) codec = (flags & FLV_AUDIO_CODECID_MASK ) >> FLV_AUDIO_CODECID_OFFSET if codec < len(FLV_AUDIO_CODECID): a.codec = FLV_AUDIO_CODECID[codec] self.audio.append(a) file.seek(size - 1, 1) elif chunk[0] == FLV_TAG_TYPE_VIDEO: flags = ord(file.read(1)) if not self.video: v = core.VideoStream() codec = (flags & FLV_VIDEO_CODECID_MASK) - 2 if codec < len(FLV_VIDEO_CODECID): v.codec = FLV_VIDEO_CODECID[codec] # width and height are in the meta packet, but I have # no file with such a packet inside. So maybe we have # to decode some parts of the video. self.video.append(v) file.seek(size - 1, 1) elif chunk[0] == FLV_TAG_TYPE_META: log.info('metadata %r', str(chunk)) metadata = file.read(size) try: while metadata: length, value = self._parse_value(metadata) if isinstance(value, dict): log.info('metadata: %r', value) if value.get('creator'): self.copyright = value.get('creator') if value.get('width'): self.width = value.get('width') if value.get('height'): self.height = value.get('height') if value.get('duration'): self.length = value.get('duration') self._appendtable('FLVINFO', value) if not length: # parse error break metadata = metadata[length:] except (IndexError, struct.error, TypeError): pass else: log.info('unkown %r', str(chunk)) file.seek(size, 1) file.seek(4, 1)
def ReadPESHeader(self, offset, buffer, id=0): """ Parse a PES header. Since it starts with 0x00 0x00 0x01 like 'normal' mpegs, this function will return (0, None) when it is no PES header or (packet length, timestamp position (maybe None)) http://dvd.sourceforge.net/dvdinfo/pes-hdr.html """ if not buffer[0:3] == '\x00\x00\x01': return 0, None packet_length = (ord(buffer[4]) << 8) + ord(buffer[5]) + 6 align = ord(buffer[6]) & 4 header_length = ord(buffer[8]) # PES ID (starting with 001) if ord(buffer[3]) & 0xE0 == 0xC0: id = id or ord(buffer[3]) & 0x1F for a in self.audio: if a.id == id: break else: self.audio.append(core.AudioStream()) self.audio[-1]._set('id', id) elif ord(buffer[3]) & 0xF0 == 0xE0: id = id or ord(buffer[3]) & 0xF for v in self.video: if v.id == id: break else: self.video.append(core.VideoStream()) self.video[-1]._set('id', id) # new mpeg starting if buffer[header_length + 9:header_length + 13] == \ '\x00\x00\x01\xB3' and not self.sequence_header_offset: # yes, remember offset for later use self.sequence_header_offset = offset + header_length + 9 elif ord(buffer[3]) == 189 or ord(buffer[3]) == 191: # private stream. we don't know, but maybe we can guess later id = id or ord(buffer[3]) & 0xF if align and \ buffer[header_length + 9:header_length + 11] == '\x0b\x77': # AC3 stream for a in self.audio: if a.id == id: break else: self.audio.append(core.AudioStream()) self.audio[-1]._set('id', id) self.audio[-1].codec = 0x2000 # AC3 else: # unknown content pass ptsdts = ord(buffer[7]) >> 6 if ptsdts and ptsdts == ord(buffer[9]) >> 4: if ord(buffer[9]) >> 4 != ptsdts: log.warning(u'WARNING: bad PTS/DTS, please contact us') return packet_length, None # timestamp = self.ReadPTS(buffer[9:14]) high = ((ord(buffer[9]) & 0xF) >> 1) med = (ord(buffer[10]) << 7) + (ord(buffer[11]) >> 1) low = (ord(buffer[12]) << 7) + (ord(buffer[13]) >> 1) return packet_length, 9 return packet_length, None
def ReadHeader(self, buffer, offset): """ Handle MPEG header in buffer on position offset Return None on error, new offset or 0 if the new offset can't be scanned """ if buffer[offset:offset + 3] != '\x00\x00\x01': return None id = ord(buffer[offset + 3]) if id == PADDING_PKT: return offset + (ord(buffer[offset + 4]) << 8) + \ ord(buffer[offset + 5]) + 6 if id == PACK_PKT: if ord(buffer[offset + 4]) & 0xF0 == 0x20: self.type = 'MPEG-1 Video' self.get_time = self.ReadSCRMpeg1 self.mpeg_version = 1 return offset + 12 elif (ord(buffer[offset + 4]) & 0xC0) == 0x40: self.type = 'MPEG-2 Video' self.get_time = self.ReadSCRMpeg2 return offset + (ord(buffer[offset + 13]) & 0x07) + 14 else: # I have no idea what just happened, but for some DVB # recordings done with mencoder this points to a # PACK_PKT describing something odd. Returning 0 here # (let's hope there are no extensions in the header) # fixes it. return 0 if 0xC0 <= id <= 0xDF: # code for audio stream for a in self.audio: if a.id == id: break else: self.audio.append(core.AudioStream()) self.audio[-1]._set('id', id) return 0 if 0xE0 <= id <= 0xEF: # code for video stream for v in self.video: if v.id == id: break else: self.video.append(core.VideoStream()) self.video[-1]._set('id', id) return 0 if id == SEQ_HEAD: # sequence header, remember that position for later use self.sequence_header_offset = offset return 0 if id in [PRIVATE_STREAM1, PRIVATE_STREAM2]: # private stream. we don't know, but maybe we can guess later add = ord(buffer[offset + 8]) # if (ord(buffer[offset+6]) & 4) or 1: # id = ord(buffer[offset+10+add]) if buffer[offset + 11 + add:offset + 15 + add].find('\x0b\x77') != -1: # AC3 stream for a in self.audio: if a.id == id: break else: self.audio.append(core.AudioStream()) self.audio[-1]._set('id', id) self.audio[-1].codec = 0x2000 # AC3 return 0 if id == SYS_PKT: return 0 if id == EXT_START: return 0 return 0
def _getnextheader(self, s): r = struct.unpack('<16sQ', s[:24]) (guidstr, objsize) = r guid = self._parseguid(guidstr) if guid == GUIDS['ASF_File_Properties_Object']: log.debug('File Properties Object') val = struct.unpack('<16s6Q4I', s[24:24 + 80]) (fileid, size, date, packetcount, duration, senddur, preroll, flags, minpack, maxpack, maxbr) = val # FIXME: parse date to timestamp self.length = duration / 10000000.0 elif guid == GUIDS['ASF_Stream_Properties_Object']: log.debug('Stream Properties Object [%d]' % objsize) streamtype = self._parseguid(s[24:40]) errortype = self._parseguid(s[40:56]) offset, typelen, errorlen, flags = struct.unpack('<QIIH', s[56:74]) strno = flags & 0x7f encrypted = flags >> 15 if encrypted: self._set('encrypted', True) if streamtype == GUIDS['ASF_Video_Media']: vi = core.VideoStream() vi.width, vi.height, depth, codec, = struct.unpack('<4xII2xH4s', s[89:89 + 20]) vi.codec = codec vi.id = strno self.video.append(vi) elif streamtype == GUIDS['ASF_Audio_Media']: ai = core.AudioStream() twocc, ai.channels, ai.samplerate, bitrate, block, \ ai.samplebits, = struct.unpack('<HHIIHH', s[78:78 + 16]) ai.bitrate = 8 * bitrate ai.codec = twocc ai.id = strno self.audio.append(ai) self._apply_extinfo(strno) elif guid == GUIDS['ASF_Extended_Stream_Properties_Object']: streamid, langid, frametime = struct.unpack('<HHQ', s[72:84]) (bitrate,) = struct.unpack('<I', s[40:40 + 4]) if streamid not in self._extinfo: self._extinfo[streamid] = [None, None, None, {}] if frametime == 0: # Problaby VFR, report as 1000fps (which is what MPlayer does) frametime = 10000.0 self._extinfo[streamid][:3] = [bitrate, 10000000.0 / frametime, langid] self._apply_extinfo(streamid) elif guid == GUIDS['ASF_Header_Extension_Object']: log.debug('ASF_Header_Extension_Object %d' % objsize) size = struct.unpack('<I', s[42:46])[0] data = s[46:46 + size] while len(data): log.debug('Sub:') h = self._getnextheader(data) data = data[h[1]:] elif guid == GUIDS['ASF_Codec_List_Object']: log.debug('List Object') pass elif guid == GUIDS['ASF_Error_Correction_Object']: log.debug('Error Correction') pass elif guid == GUIDS['ASF_Content_Description_Object']: log.debug('Content Description Object') val = struct.unpack('<5H', s[24:24 + 10]) pos = 34 strings = [] for i in val: ss = s[pos:pos + i].replace('\0', '').lstrip().rstrip() strings.append(ss) pos += i # Set empty strings to None strings = [x or None for x in strings] self.title, self.artist, self.copyright, self.caption, rating = strings elif guid == GUIDS['ASF_Extended_Content_Description_Object']: (count,) = struct.unpack('<H', s[24:26]) pos = 26 descriptor = {} for i in range(0, count): # Read additional content descriptors d = self._parsekv(s[pos:]) pos += d[0] descriptor[d[1]] = d[2] self._appendtable('ASFDESCRIPTOR', descriptor) elif guid == GUIDS['ASF_Metadata_Object']: (count,) = struct.unpack('<H', s[24:26]) pos = 26 streams = {} for i in range(0, count): # Read additional content descriptors size, key, value, strno = self._parsekv2(s[pos:]) if strno not in streams: streams[strno] = {} streams[strno][key] = value pos += size for strno, metadata in streams.items(): if strno not in self._extinfo: self._extinfo[strno] = [None, None, None, {}] self._extinfo[strno][3].update(metadata) self._apply_extinfo(strno) elif guid == GUIDS['ASF_Language_List_Object']: count = struct.unpack('<H', s[24:26])[0] pos = 26 for i in range(0, count): idlen = struct.unpack('<B', s[pos:pos + 1])[0] idstring = s[pos + 1:pos + 1 + idlen] idstring = unicode(idstring, 'utf-16').replace('\0', '') log.debug('Language: %d/%d: %r' % (i + 1, count, idstring)) self._languages.append(idstring) pos += 1 + idlen elif guid == GUIDS['ASF_Stream_Bitrate_Properties_Object']: # This record contains stream bitrate with payload overhead. For # audio streams, we should have the average bitrate from # ASF_Stream_Properties_Object. For video streams, we get it from # ASF_Extended_Stream_Properties_Object. So this record is not # used. pass elif guid == GUIDS['ASF_Content_Encryption_Object'] or \ guid == GUIDS['ASF_Extended_Content_Encryption_Object']: self._set('encrypted', True) else: # Just print the type: for h in GUIDS.keys(): if GUIDS[h] == guid: log.debug('Unparsed %r [%d]' % (h, objsize)) break else: u = "%.8X-%.4X-%.4X-%.2X%.2X-%s" % guid log.debug('unknown: len=%d [%d]' % (len(u), objsize)) return r