-
Notifications
You must be signed in to change notification settings - Fork 4
/
mpeg2.py
131 lines (106 loc) · 3.66 KB
/
mpeg2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from struct import unpack
from time import sleep
import sys
class TSPacket(object):
def __init__(self, raw_data=None):
self.raw_data = raw_data
self.sync = None
self.pid = None
self.error = None
self.start = None
self.priority = None
self.scramble = None
self.adapt = None
self.count = None
self.payload = None
if raw_data:
self.parse(raw_data)
def parse(self, raw_data):
self.raw_data = raw_data
sync, pid, count, payload = unpack('>BHB184s', raw_data)
self.sync = sync
self.error = (pid & 32768) >> 15
self.start = (pid & 16384) >> 14
self.priority = (pid & 8192) >> 13
self.pid = pid & 8191
self.scramble = (count & 192) >> 6
self.adapt = (count & 48) >> 4
self.count = count & 15
self.payload = payload
def __str__(self):
return 'sync: %#x error: %i start: %i priority: %i pid: %#x scramble: %i adapt: %i count: %#x len(payload): %i' % (self.sync, self.error, self.start, self.priority, self.pid, self.scramble, self.adapt, self.count, len(self.payload))
class PESPacket(object):
STREAM_TYPES = {
'\xbc': 'program_stream_map',
'\xbd': 'private_stream_1',
'\xbe': 'padding_stream',
'\xbf': 'private_stream_2',
'\xf0': 'ECM_stream',
'\xf1': 'EMM_stream',
'\xf2': 'DSM-CC',
'\xf3': 'ISO/IEG_13552_stream',
'\xf4': 'PMT',
'\xf5': 'PMT',
'\xf6': 'PMT',
'\xf7': 'PMT',
'\xf8': 'PMT',
'\xf9': 'ancillary_stream',
'\xff': 'program_stream_directory',
}
def __init__(self, tspacket=None):
self.tspacket = tspacket
self.prefix = None
self.id = None
self.length = None
self.streamid = None
self.streamtype = None
if tspacket:
self.parse(tspacket)
def parse(self, tspacket):
if not tspacket.start:
self.payload = tspacket.payload
return
if tspacket.adapt:
length = unpack('>c', tspacket.payload[0])
length = ord(length[0])
length, adapt = unpack('>cs%i' % length, tspacket.payload)
print repr(length, adapt)
self.prefix, self.streamid, self.length = unpack('>3scH', tspacket.payload)
self.payload = tspacket.payload[6:]
if self.id in self.STREAM_TYPES:
self.streamtype = self.STREAM_TYPES[self.id]
else:
if (self.id >> 4) == 14:
self.streamtype = 'video'
self.streamid = self.id & 15
if (self.id >> 5) == 6:
self.streamtype = 'audio'
self.streamid = self.id & 31
def is_header(self):
if self.prefix and self.id and self.length:
return True
else:
return False
def main():
input = file(sys.argv[1], 'rb')
psize = 188
chunksize = 7
while True:
data = input.read(psize * chunksize)
if not data: break
# Chop off anything before the sync bit
sync_offset = data.find('\x47')
if sync_offset == -1:
print 'No sync bit in packet.'
continue
if sync_offset != 0:
print 'Resync'
data = data[sync_offset:]
for i in range(chunksize):
packet = data[:psize]
data = data[psize:]
packet = TSPacket(packet)
print packet
#pes = PESPacket(packet)
#print pes.streamtype
if __name__ == '__main__': main()