from dvb_charset_tables import conv_8859_table def str2hex ( s, n = None ): r = '' i = 0 for c in s: r = r + ('%02X ' % ord(c)) i = i + 1 if n is not None and i % n == 0: r = r + '\n' return r def dvb_convert_date ( data ): return 0 convert_iso_8859 = [ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, 13 ] def encode_utf8 ( c ): if c <= 0x7f: return chr(c) elif c <= 0x7ff: return unichr((c >> 6 & 0x1f) | 0xc0) + unichr((c & 0x3f) | 0x80) return '' def conv_8859 ( tnum, data ): r = u'' print 'TBL %d' % tnum tbl = conv_8859_table[tnum] for c in data: if ord(c) <= 0x7f: r = r + c elif ord(c) <= 0x9f: r = r + ' ' else: uc = tbl[ord(c) - 0xa0] if uc: r = r + encode_utf8(uc) return r def dvb_convert_string ( data, conv ): print 'convert(%d)' % conv print repr(data) if not conv: return data return conv_8859(conv, data) class TsPacket: def __init__ ( self, data ): #print 'TS Packet:' #print str2hex(data, 16) hdr = map(ord, data[:4]) if hdr[0] != 0x47: raise Exception('not valid TS packet') self.tx_err = (hdr[1] & 0x80) == 0x80 self.pl_init = (hdr[1] & 0x40) == 0x40 self.tx_prio = (hdr[1] & 0x20) == 0x20 self.pid = ((hdr[1] & 0x1F) << 8) + hdr[2] self.tx_scr = (hdr[3] & 0xC0) >> 6 self.adapt = (hdr[3] & 0x30) >> 4 self.cont = (hdr[3] & 0x0F) self.data = data[4:] class TsSection: def __init__ ( self, pid, data ): hdr = map(ord, data[:3]) self.pid = pid self.tid = hdr[0] self.iscrc = (hdr[1] & 0x80) == 0x80 self.len = ((hdr[1] & 0x0F) << 8) + hdr[2] self.data = data[3:] #print 'TS Section:' #print hdr #print self.tid, self.len, len(data) def process ( self ): print 'TS Section:' print self.tid, self.len, len(self.data) #print str2hex(self.data, 16) #print self.data # Strip header hdr = map(ord, self.data[:11]) plen = self.len - 11 data = self.data[11:] #print str2hex(data, 16) # Process each event while plen: r = self.process_event(data, plen) if r < 0: break plen = plen - r data = data[r:] def get_string ( self, data, dlen, charset ): #print 'get_string():' #print str2hex(data, 16) l = ord(data[0]) if not l: return (None, 0) #print l, dlen if l + 1 > dlen: return (None, -1) c = ord(data[1]) print c conv = None if c == 0: return (None, -1) elif c <= 0xb: conv = convert_iso_8859[c + 4] data = data[1:] dlen = dlen - 1 elif c <= 0xf: return (None, -1) elif c == 0x10: conv = 0 elif c <= 0x14: return (None, -1) elif c == 0x15: conv = 0 elif c <= 0x1f: return (None, -1) else: conv = 'default' s = dvb_convert_string(data[1:1+l], conv) return (s, l+1) def short_event ( self, data, dlen ): if dlen < 5: return None lang = data[:3] (title, l) = self.get_string(data[3:], dlen-3, None) if l < 0: return None (sumry, l) = self.get_string(data[3+l:], dlen-3-l, None) return (title, sumry) def process_event ( self, data, elen ): if (elen < 12): return -1 # Get lengths hdr = map(ord, data[:12]) dllen = ((hdr[10] & 0x0F) << 8) + hdr[11] data = data[12:] elen = elen - 12 if elen < dllen: return -1 ret = 12 + dllen # Header info eid = (hdr[0] << 8) + hdr[1] start = dvb_convert_date(hdr[2:]) print 'process event (%d):' % dllen print ' EID : %d' % eid print ' START : %d' % start while dllen > 2: dtag = ord(data[0]) dlen = ord(data[1]) print 'dtag = 0x%02x, dlen = %d' % (dtag, dlen) dllen = dllen - 2 data = data[2:] if dllen < dlen: return ret if dtag == 0x4d: (title, summary) = self.short_event(data, dlen) print ' TITLE : %s' % title print ' SUMMARY : %s' % summary dllen = dllen - dlen data = data[dlen:] return ret if __name__ == '__main__': import os, sys fp = open(sys.argv[1]) cur = nxt = None while True: pkt = TsPacket(fp.read(188)) # Restrict to EIT if pkt.pid != 0x12: continue # Start/End if pkt.pl_init: ptr = ord(pkt.data[0]) if ptr == 0x00: cur = TsSection(pkt.pid, pkt.data[1:]) else: if cur: cur.data = cur.data + pkt.data[:1+ptr] nxt = TsSection(pkt.pid, pkt.data[1+ptr:]) # Middle elif cur: cur.data = cur.data + pkt.data # Complete? if cur: if len(cur.data) >= cur.len: print 'Process Section:' #try: cur.process() #except: pass cur = None print sys.exit(0) else: print 'waiting for %d bytes' % (cur.len - len(cur.data)) # Next if nxt: cur = nxt