Last active
September 9, 2023 12:48
-
-
Save mipsparc/ca08e4ed5c6ffb485b03905bafafbe4c to your computer and use it in GitHub Desktop.
MPEG2-TSの中のTDTパケットを取り出して、中に入ってる時刻情報を表示するやつ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
#coding:utf-8 | |
#require bitstring | |
import bitstring | |
import math | |
import sys | |
filename = sys.argv[1] | |
packet_length = 188 | |
#packet_length = 204 | |
syncbyte = 0x47 | |
f = bitstring.ConstBitStream(filename=filename) | |
count = 0 | |
failcount = 0 | |
summary = {} | |
first = True | |
#quoted from https://gist.github.com/jiffyclub/1294443 | |
def mjd_to_date(mjd): | |
jd = mjd + 2400000.5 | |
jd = jd + 0.5 | |
F, I = math.modf(jd) | |
I = int(I) | |
A = math.trunc((I - 1867216.25)/36524.25) | |
if I > 2299160: | |
B = I + 1 + A - math.trunc(A / 4.) | |
else: | |
B = I | |
C = B + 1524 | |
D = math.trunc((C - 122.1) / 365.25) | |
E = math.trunc(365.25 * D) | |
G = math.trunc((C - E) / 30.6001) | |
day = int(C - E + F - math.trunc(30.6001 * G)) | |
if G < 13.5: | |
month = G - 1 | |
else: | |
month = G - 13 | |
if month > 2.5: | |
year = D - 4716 | |
else: | |
year = D - 4715 | |
return year, month, day | |
class TS: | |
def __init__(self, packet): | |
self.packet = packet | |
def unpack(self): | |
if packet_length == 188: | |
#188-5(header+pointer)-4(CRC)=179, 179*8=1432bits | |
self.sync, self.error, self.pid, self.scramble, self.counter, self.pointer, self.payload, self.crc = \ | |
self.packet.unpack('uint:8, bool, pad:2, uint:13, bits:2, pad:2, uint:4, uint:8, bits:1432, bytes:4') | |
else: | |
#204(16がリードソロモン) | |
self.sync, self.error, self.pid, self.scramble, self.counter, self.pointer, self.payload, self.crc, self.reedsolomon = \ | |
self.packet.unpack('uint:8, bool, pad:2, uint:13, bits:2, pad:2, uint:4, uint:8, bits:1432, bytes:4, bytes:16') | |
#find sync | |
if self.sync != syncbyte: | |
found = self.packet.find('0x47', bytealigned=True) #findには文字列で渡す… | |
return True | |
return False | |
def tdt_unpack(self): | |
table_id, mjd16, h1, h2, m1, m2, s1, s2 = \ | |
self.payload.unpack('uint:8, pad:16, uint:16, uint:4, uint:4, uint:4, uint:4, uint:4, uint:4') | |
year, month, day = mjd_to_date(mjd16) | |
hour = int(str(h1)+str(h2)) | |
minute = int(str(m1)+str(m2)) | |
sec = int(str(s1)+str(s2)) | |
print('TIME {}-{}-{} {}:{}:{} JST'.format(year, month, day, hour, minute, sec)) | |
while True: | |
try: | |
packet = f.read(packet_length*8) #bit | |
except bitstring.ReadError: #終端 | |
break | |
ts = TS(packet) | |
if ts.unpack(): | |
#syncできなかったら戻る | |
if ts.packet.bytepos != 0: #このパケット内にsyncがあったら | |
f.bytepos = f.bytepos - packet_length + ts.packet.bytepos | |
failcount += 1 | |
else: | |
#カウンタチェック | |
#if not first: | |
# print('PID:{} {}'.format(ts.pid, ts.counter)) | |
#TDT | |
if ts.pid == 0x14 and not ts.error: | |
ts.tdt_unpack() | |
if not ts.error: | |
try: | |
summary[ts.pid] += 1 | |
except KeyError: | |
summary[ts.pid] = 1 | |
first = False | |
count += 1 | |
print('-------------------------------') | |
print('PID count:',len(summary)) | |
print('Fail:', failcount) | |
print('Total:', count) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment