def make_mkvb(self): import mcio_matroska from mcio_matroska import MatroskaBuilder tracks = self.find_subboxes('trak') td_gcd = reduce(gcd, (t.get_sample_delta_gcd() for t in tracks)) ts_base = max(t.get_mdhd().time_scale for t in tracks) dur = max(t.get_mdhd().get_dur() for t in tracks) mvhd = self.find_subbox('mvhd') dur = max(dur, mvhd.get_dur()) (tcs, elmult, _tcs_err) = MatroskaBuilder.tcs_from_secdiv(ts_base, td_gcd) mb = MatroskaBuilder(tcs, dur) for track in tracks: mdhd = track.get_mdhd() se = track.get_sample_entry() htype = track.find_subbox(b'mdia').find_subbox(b'hdlr').handler_type if (htype == self._HTYPE_VIDE): ttype = mcio_matroska.TRACKTYPE_VIDEO at_args = (se.width, se.height) elif (htype == self._HTYPE_SOUN): ttype = mcio_matroska.TRACKTYPE_AUDIO at_args = (round(se.sample_rate), se.channel_count) else: continue codec_id = se.get_codec() ts_fact = (ts_base / mdhd.time_scale) mcd = track._get_most_common_dur() mb.add_track(track.get_sample_data(elmult*ts_fact, mcd), ttype, codec_id, se.get_codec_init_data(), not (track.stts is None), default_dur=round(10**9*mcd/mdhd.time_scale), *at_args) return mb
def make_mkvb(self): from collections import deque import mcio_matroska from mcio_matroska import MatroskaBuilder video_init = None audio_init = None vd = {} ad = {} for d in (ad, vd): d['data'] = deque() d['init_data'] = None avtmap = {8:ad, 9: vd} md = { 'duration':None, 'width':None, 'height':None, 'codec':None } prev_vn = None #vfbuf = [] for tag in self.parse_tags(): try: d = avtmap[tag.type] except KeyError: if (tag.type == 18): md_add = tag.get_metadata() if not (md_add is None): md.update(md_add) continue try: tag_last = d['data'][-1] except IndexError: d['codec'] = tag.codec if (isinstance(tag, FLVAudioData)): d['sfreq'] = tag.sample_freq d['channel_count'] = tag.channels else: if not (tag_last.check_stream_consistency(tag)): raise FLVParserError('Stream metadata inconsistency between {0} and {1}.'.format(tag_prev, tag)) if (tag.is_header()): d['init_data'] = tag.data_r.get_data() else: d['data'].append(tag) #if ((tag.type == 9) and (tag.codec == 7)): ## H264 data ... try reordering. #if (tag.is_header()): #vid_id = H264InitData(d['init_data']) #else: #(nalu,) = _h264_nalu_seq_read(tag.data_r, vid_id) #nalu.compute_po(prev_vn) #prev_vn = nalu #if (tag.is_keyframe): #self._v_reorder(vfbuf) #del(vfbuf[:]) #vfbuf.append(tag) mb = MatroskaBuilder(1000000, md['duration']) try: vc_id = self.CODEC2ID_V[vd['codec']] except KeyError: raise FLVParserError('Unknown video codec {0}.'.format(vd['codec'])) width = md['width'] height = md['height'] if not (width is None): width = int(width) if not (height is None): height = int(height) mb.add_track((t.get_framedata() for t in vd['data']), mcio_matroska.TRACKTYPE_VIDEO, vc_id, vd['init_data'], True, width, height) try: ac_id = self.CODEC2ID_A[ad['codec']] except KeyError: raise FLVParserError('Unknown audio codec {0}.'.format(ad['codec'])) mb.add_track((t.get_framedata() for t in ad['data']), mcio_matroska.TRACKTYPE_AUDIO, ac_id, ad['init_data'], False, ad['sfreq'], ad['channel_count']) return mb