示例#1
0
 def decode(self):
     """
     decode SCTE35 Avail Descriptor
     """
     bitbin = BitBin(self.bites)
     self.parse_id(bitbin)
     self.provider_avail_id = bitbin.asint(32)
示例#2
0
 def __init__(self, mesg):
     mesg = self.mkbits(mesg)
     self.bitbin = BitBin(mesg)
     self.descriptors = []
     self.info_section = None
     self.command = None
     self.do()
示例#3
0
 def decode(self):
     """
     decode SCTE35 Time Descriptor
     """
     bitbin = BitBin(self.bites)
     self.parse_id(bitbin)
     self.tai_seconds = bitbin.asint(48)
     self.tai_ns = bitbin.asint(32)
     self.utc_offset = bitbin.asint(16)
 def parse_pusi(self, packetdata):
     '''
     If the pusi data contains these markers,
     we can pull a PTS value..
     '''
     if packetdata[2] == 1:
         if packetdata[3] not in self.NON_PTS_STREAM_IDS:
             if (packetdata[6] >> 6) == 2:
                 if (packetdata[7] >> 6) == 2:
                     if (packetdata[9] >> 4) == 2:
                         bitbin = BitBin(packetdata[9:])
                         bitbin.forward(4)
                         self.parse_pts(bitbin)
示例#5
0
 def parse_tspacket(self, packet):
     two_bytes, one_byte = unpack('>HB', packet[:3])
     # tei = two_bytes >> 15
     pusi = two_bytes >> 14 & 0x1
     # ts_priority = two_bytes >>13 & 0x1
     pid = two_bytes & 0x1fff
     # scramble = one_byte >>6
     afc = (one_byte & 48) >> 4
     # count = 0
     if afc in [2, 3]:
         afcl = unpack('>B', packet[4:5])[0]
         afcl += 12
         fu = packet[4:afcl]
         bitbin = BitBin(fu)
         adaptation_fields(bitbin)
         return
     # No PTS times in pid 101
     if pid == 101: return
     # Here's where you find PTS
     if pusi: self.parse_pusi(packet[3:19])
     # SCTE35_TID (0xfc) is required .
     if packet[4] != self.SCTE35_TID: return
     #  If the SCTE 35 pid is known, the packet pid must match.
     if self.PID and (pid != self.PID): return
     #  Only show splice_null commands if self.show_null is True
     if not self.show_null:
         if packet[17] == 0: return
     try:
         tf = Splice(packet[4:])
     except:
         return
     print()
     tf.show()
     if not self.PID: self.PID = pid
     return
示例#6
0
 def decode(self):
     """
     decode is called only by a TimeSignal instance
     """
     bitbin = BitBin(self.bites)
     start = bitbin.idx
     self._decode_pts(bitbin)
     self._set_len(start, bitbin.idx)
示例#7
0
 def decode(self):
     """
     Decode SCTE35 Audio Descriptor
     """
     bitbin = BitBin(self.bites)
     self.parse_id(bitbin)
     self.audio_count = a_c = bitbin.asint(4)
     bitbin.forward(4)
     while a_c:
         a_c -= 1
         comp = {}
         comp["component_tag"] = bitbin.asint(8)
         comp["ISO_code="] = bitbin.asint(24)
         comp["bit_stream_mode"] = bitbin.asint(3)
         comp["num_channels"] = bitbin.asint(4)
         comp["full_srvc_audio"] = bitbin.asflag(1)
         self.components.append(comp)
示例#8
0
 def mk_command(self, payload):
     cmdbb = BitBin(payload)
     bit_start = cmdbb.idx
     self.set_splice_command(cmdbb)
     bit_end = cmdbb.idx
     cmdl = self.command.splice_command_length = int((bit_start -
                                                      bit_end) >> 3)
     self.info_section.splice_command_length = cmdl
     return payload[cmdl:]
示例#9
0
 def _program_association_table(self, pkt):
     """
     parse program association table ( pid 0 )
     to program to program table pid mappings.
     """
     sectionlen = (pkt[6] & 15 << 8) | pkt[7]
     pkt = pkt[13:(sectionlen + 5)]
     bitbin = BitBin(pkt)
     slib = sectionlen << 3
     slib -= 40
     while slib > 32:
         program_number = bitbin.asint(16)
         bitbin.forward(3)
         if program_number == 0:
             bitbin.forward(13)
         else:
             self._pmt_pids.add(bitbin.asint(13))
         slib -= 32
     bitbin.forward(32)
示例#10
0
def parse_private_upid_SBSB(bites, upid_length):
    bitbin = BitBin(bites)
    return {
        "private_cni": hex(bitbin.asint(16)),
        "private_version": bitbin.asint(8),
        "private_transmission_id": struct.unpack("<Q", bitbin.asbites(64))[0],
        "private_product_code": struct.unpack("<Q", bitbin.asbites(64))[0],
        "private_web_publication_key": bitbin.astext(25 * 8),
    }
示例#11
0
def parse_tspacket(packet, packetnum):
    three_bytes = BitBin(packet[:3])
    tei = three_bytes.asflag(1)
    pusi = three_bytes.asflag(1)
    ts_priority = three_bytes.asflag(1)
    pid = three_bytes.asint(13)
    if pusi:
        parse_pes(packet, packetnum)
示例#12
0
 def decode(self):
     """
     decode SCTE35 Dtmf Descriptor
     """
     bitbin = BitBin(self.bites)
     self.parse_id(bitbin)
     self.preroll = bitbin.asint(8)
     self.dtmf_count = d_c = bitbin.asint(3)
     bitbin.forward(5)
     while d_c:
         d_c -= 1
         self.dtmf_chars.append(bitbin.astext(8))
示例#13
0
 def set_splice_descriptor(self, payload):
     '''
     Splice Descriptors looked up in self.descriptor_map
     '''
     # splice_descriptor_tag 8 uimsbf
     tag = payload[0]
     desc_len = payload[1]
     payload = payload[2:]
     bitbin = BitBin(payload[:desc_len])
     payload = payload[desc_len:]
     if tag in self.descriptor_map.keys():
         sd = self.descriptor_map[tag](bitbin, tag)
         sd.descriptor_length = desc_len
         return sd
     else:
         return False
示例#14
0
 def _set_splice_descriptor(self, payload):
     """
     Splice Descriptors looked up in self._descriptor_map
     """
     # splice_descriptor_tag 8 uimsbf
     tag = payload[0]
     desc_len = payload[1]
     payload = payload[2:]
     bitbin = BitBin(payload[:desc_len])
     payload = payload[desc_len:]
     if tag in self._descriptor_map:
         spliced = self._descriptor_map[tag](tag)
         spliced.decode(bitbin)
         spliced.descriptor_length = desc_len
         return spliced
     return False
示例#15
0
 def decode(self):
     """
     SpliceInsert.decode
     """
     bitbin = BitBin(self.bites)
     start = bitbin.idx
     self.splice_event_id = bitbin.asint(32)
     self.splice_event_cancel_indicator = bitbin.asflag(1)
     bitbin.forward(7)
     if not self.splice_event_cancel_indicator:
         self._decode_flags(bitbin)
         if self.program_splice_flag:
             if not self.splice_immediate_flag:
                 self._decode_pts(bitbin)
         else:
             self._decode_components(bitbin)
             if not self.splice_immediate_flag:
                 self._decode_pts(bitbin)
         if self.duration_flag:
             self._decode_break(bitbin)
         self.unique_program_id = bitbin.asint(16)
         self.avail_num = bitbin.asint(8)
         self.avail_expected = bitbin.asint(8)
     self._set_len(start, bitbin.idx)
示例#16
0
 def decode(self):
     """
     decode a segmentation descriptor
     """
     bitbin = BitBin(self.bites)
     self.parse_id(bitbin)
     self.segmentation_event_id = bitbin.ashex(32)  # 4 bytes
     self.segmentation_event_cancel_indicator = bitbin.asflag(1)
     bitbin.forward(7)  # 1 byte
     if not self.segmentation_event_cancel_indicator:
         self._decode_flags(bitbin)  # 1 byte
         if not self.program_segmentation_flag:
             self._decode_components(bitbin)
         self._decode_segmentation(bitbin)
示例#17
0
 def _program_map_section(self, pkt):
     """
     parse program maps for streams
     """
     # table_id = pkt[5]
     sectioninfolen = (pkt[6] & 15 << 8) | pkt[7]
     slib = sectioninfolen << 3
     program_number = (pkt[8] << 8) | pkt[9]
     # version = pkt[10] >> 1 & 31
     # current_next = pkt[10] & 1
     if self.the_program and (program_number != self.the_program):
         return None
     # section_number = pkt[11]
     # last_section_number = pkt[12]
     # pcr_pid = (pkt[13]& 31) << 8 | pkt[14]
     proginfolen = (pkt[15] & 15 << 8) | pkt[16]
     pkt = pkt[(17 + proginfolen):(slib + 9)]
     bitbin = BitBin(pkt)
     pilib = proginfolen << 3
     slib -= 72
     slib -= pilib  # Skip descriptors
     self._parse_program_streams(slib, bitbin, program_number)
示例#18
0
def parse_pes(packet, packetnum):
    bb = BitBin(packet[3:])
    if bb.asint(24) == 1 and bb.asint(8) not in NON_PTS_STREAM_IDS:
        PES_packet_length = bb.asint(16)
        if bb.asint(2) == 2:
            bb.asint(6)
            if bb.asint(2) in [2, 3]:
                bb.asint(14)
                if bb.asint(4) in [2, 3]:
                    to33 = bb.asint(3) << 30
                    bb.asflag(1)
                    to30 = bb.asint(15) << 15
                    bs.asflag(1)
                    to15 = bb.asint(15)
                    d = to33 + to30 + to15
                    print(f" PTS {d/90000:.6f} on Packet {packetnum}")
示例#19
0
 def decode(self, bites):
     bitbin = BitBin(bites)
     self.table_id = bitbin.ashex(8)
     if self.table_id != "0xfc":
         to_stderr("splice info section table id should be 0xfc")
     self.section_syntax_indicator = bitbin.asflag(1)
     self.private = bitbin.asflag(1)
     self.reserved = bitbin.ashex(2)
     if self.reserved != "0x3":
         to_stderr("splice info section reserved should be 0x3")
     self.section_length = bitbin.asint(12)
     self.protocol_version = bitbin.asint(8)
     if self.protocol_version != 0:
         to_stderr("splice info section protocol version should be 0")
     self.encrypted_packet = bitbin.asflag(1)
     self.encryption_algorithm = bitbin.asint(6)
     self.pts_adjustment = bitbin.as90k(33)
     self.cw_index = bitbin.ashex(8)
     self.tier = bitbin.ashex(12)
     self.splice_command_length = bitbin.asint(12)
     self.splice_command_type = bitbin.asint(8)
     self.descriptor_loop_length = 0
示例#20
0
class Splice:

    descriptor_map = {
        0: Avail_Descriptor,
        1: Dtmf_Descriptor,
        2: Segmentation_Descriptor,
        3: Time_Descriptor,
        4: Audio_Descriptor
    }

    command_map = {
        0: Splice_Null,
        4: Splice_Schedule,
        5: Splice_Insert,
        6: Time_Signal,
        7: Bandwidth_Reservation,
        255: Private_Command
    }

    def __init__(self, mesg):
        mesg = self.mkbits(mesg)
        self.bitbin = BitBin(mesg)
        self.descriptors = []
        self.info_section = None
        self.command = None
        self.do()

    def do(self):
        self.info_section = Splice_Info_Section()
        self.info_section.decode(self.bitbin)
        self.set_splice_command()
        self.descriptorloop()
        self.info_section.crc = self.bitbin.ashex(32)

    def descriptorloop(self):
        self.info_section.descriptor_loop_length = self.bitbin.asint(16)
        dll = self.info_section.descriptor_loop_length
        tag_plus_header_size = 2  # 1 byte for descriptor_tag, 1 byte for header?
        while dll > 0:
            try:
                sd = self.set_splice_descriptor()
                sdl = sd.descriptor_length
                self.descriptors.append(sd)
            except:
                sdl = 0
            bit_move = sdl + tag_plus_header_size
            dll -= bit_move

    def kvprint(self, obj):
        print(f'{json.dumps(vars(obj))}')

    def sectionstart(self, section_name):
        print(f'{section_name}')

    def mkbits(self, s):
        if s[:2].lower() == '0x':
            s = s[2:]
        if s[:2].lower() == 'fc':
            return bytes.fromhex(s)
        try:
            return b64decode(s)
        except:
            return s

    def set_splice_command(self):
        sct = self.info_section.splice_command_type
        if sct not in self.command_map.keys():
            raise ValueError('unknown splice command type')
        self.command = self.command_map[sct]()
        self.command.decode(self.bitbin)

    def set_splice_descriptor(self):
        # splice_descriptor_tag 8 uimsbf
        tag = self.bitbin.asint(8)
        if tag in self.descriptor_map.keys():
            return self.descriptor_map[tag](self.bitbin, tag)

    def show_info_section(self):
        if self.info_section and self.command:
            self.sectionstart('Splice Info Section')
            self.kvprint(self.info_section)
        else:
            return False

    def show_command(self):
        if self.command:
            self.sectionstart('Splice Command')
            self.kvprint(self.command)
        else:
            return False

    def show_descriptors(self):
        if len(self.descriptors) > 0:
            for d in self.descriptors:
                idx = self.descriptors.index(d)
                self.sectionstart(f'Splice Descriptor {idx}')
                self.kvprint(d)

    def show(self):
        if self.info_section and self.command:
            self.sectionstart('[SCTE 35 Message]')
            self.show_info_section()
            self.show_command()
            self.show_descriptors()
        else:
            return False
示例#21
0
 def parse_pusi(self, packet):
     bitbin = BitBin(packet)
     if bitbin.asint(24) != 1: return
     if bitbin.asint(8) in self.NON_PTS_STREAM_IDS: return
     # PES_packet_length =
     bitbin.forward(16)
     if bitbin.asint(2) != 2: return
     bitbin.forward(6)
     '''
     PES_scramble_control = bitbin.asint(2)
     PES_priority = bitbin.asint(1)
     data_align_ind = bitbin.asint(1)
     copyright = bitbin.asint(1)
     orig_or_copy = bitbin.asint(1)
     '''
     if bitbin.asint(2) != 2: return
     bitbin.forward(14)
     if bitbin.asint(4) != 2: return
     a = bitbin.asint(3) << 30
     bitbin.forward(1)
     b = bitbin.asint(15) << 15
     bitbin.forward(1)
     c = bitbin.asint(15)
     d = (a + b + c) / 90000.0
     fpts = f'PTS \033[92m{d:.3f}\033[0m '
     print(f'\r{fpts}', end="\r")
     return
 def decode(self, bites):
     bitbin = BitBin(bites)
     self.table_id = bitbin.ashex(8)
     if self.table_id != '0xfc':
         raise ValueError('splice_info_section.table_id should be 0xfc')
     self.section_syntax_indicator = bitbin.asflag(1)
     self.private = bitbin.asflag(1)
     self.reserved = bitbin.ashex(2)
     if self.reserved != '0x3':
         raise ValueError('splice_info_section.reserved should be 0x3')
     self.section_length = bitbin.asint(12)
     self.protocol_version = bitbin.asint(8)
     if self.protocol_version != 0:
         raise ValueError(
             'splice_info_section.protocol_version should be 0')
     self.encrypted_packet = bitbin.asflag(1)
     self.encryption_algorithm = bitbin.asint(6)
     self.pts_adjustment = bitbin.as90k(33)
     self.cw_index = bitbin.ashex(8)
     self.tier = bitbin.ashex(12)
     self.splice_command_length = bitbin.asint(12)
     self.splice_command_type = bitbin.asint(8)
     self.descriptor_loop_length = 0