Skip to main content

A SCTE 35 Decoder for Mpeg-TS video, and Base64 or Hex encoded messages

Project description

threefive

SCTE35 Decoder



Splice Commands

  • source splice_commands.py
  • Splice Null
  • Splice Schedule (lightly tested)
  • Splice Insert
  • Time Signal
  • Bandwidth Reservation (lightly tested)

Splice Descriptors

  • source descriptors.py
  • DTMF Descriptor
  • Segmentation Descriptor
  • Segmentation UPID (partially implemented)
  • Segmentation Types and Messages
  • Time Descriptor
  • Audio Descriptor (lightly tested)

🡡 top

Fast Start Directions

Dependencies

Install

pip install threefive
Collecting threefive
  Downloading threefive-2.0.99-py3-none-any.whl (12 kB)
Collecting bitn>=0.0.27
  Downloading bitn-0.0.27-py3-none-any.whl (3.0 kB)
Installing collected packages: bitn, threefive
Successfully installed bitn-0.0.27 threefive-2.0.99

🡡 top

Easy threefive

The decode Function

  • source decode.py
  • threefive.decode is an all purpose function to decode SCTE 35 messages from a file or string.
import threefive

MpegTS

threefive.decode('/path/to/mpegwithscte35.ts') 

Binary

threefive.decode('/mnt/build/file.bin')

Output for MpegTS and Binary Files and Streams

{ 'SCTE35': { 'Info_Section': { 'crc': '0x10fa4d9e',
                                'cw_index': '0x0',
                                'descriptor_loop_length': 10,
                                'encrypted_packet': False,
                                'encryption_algorithm': 0,
                                'private': False,
                                'protocol_version': 0,
                                'pts_adjustment': 0.0,
                                'reserved': '0x3',
                                'section_length': 47,
                                'section_syntax_indicator': False,
                                'splice_command_length': 4095,
                                'splice_command_type': 5,
                                'table_id': '0xfc',
                                'tier': '0xfff'},
              'Splice_Command': { 'avail_expected': 0,
                                  'avail_num': 0,
                                  'break_auto_return': False,
                                  'break_duration': 242.0,
                                  'duration_flag': True,
                                  'name': 'Splice '
                                          'Insert',
                                  'out_of_network_indicator': True,
                                  'program_splice_flag': True,
                                  'pts_time': 89742.161689,
                                  'splice_event_cancel_indicator': False,
                                  'splice_event_id': 662,
                                  'splice_immediate_flag': False,
                                  'time_specified_flag': True,
                                  'unique_program_id': 1},
              'Splice_Descriptors': [ { 'descriptor_length': 8,
                                        'identifier': 'CUEI',
                                        'name': 'Avail '
                                                'Descriptor',
                                        'provider_avail_id': 0,
                                        'splice_descriptor_tag': 0}]}}

Base64 Encoded Strings

mesg='/DBhAAAAAAAA///wBQb+qM1E7QBLAhdDVUVJSAAArX+fCAgAAAAALLLXnTUCAAIXQ1VFSUg/nwgIAAAAACyy150RAAACF0NVRUlIAAAnf58ICAAAAAAsstezEAAAihiGnw=='
threefive.decode(mesg)

Hex Encoded Strings

hexed='0xFC302F000000000000FFFFF014054800008F7FEFFE7369C02EFE0052CCF500000000000A0008435545490000013562DBA30A'
threefive.decode(hexed)

Output for Base64 and Hex Strings

{ 'SCTE35': { 'Info_Section': { 'crc': '0x62dba30a',
                                'cw_index': '0xff',
                                'descriptor_loop_length': 10,
                                'encrypted_packet': False,
                                'encryption_algorithm': 0,
                                'private': False,
                                'protocol_version': 0,
                                'pts_adjustment': 0.0,
                                'reserved': '0x3',
                                'section_length': 47,
                                'section_syntax_indicator': False,
                                'splice_command_length': 20,
                                'splice_command_type': 5,
                                'table_id': '0xfc',
                                'tier': '0xfff'},
              'Splice_Command': { 'avail_expected': 0,
                                  'avail_num': 0,
                                  'break_auto_return': True,
                                  'break_duration': 60.293567,
                                  'duration_flag': True,
                                  'name': 'Splice '
                                          'Insert',
                                  'out_of_network_indicator': True,
                                  'program_splice_flag': True,
                                  'pts_time': 21514.559089,
                                  'splice_event_cancel_indicator': False,
                                  'splice_event_id': 1207959695,
                                  'splice_immediate_flag': False,
                                  'time_specified_flag': True,
                                  'unique_program_id': 0},
              'Splice_Descriptors': [ { 'descriptor_length': 8,
                                        'identifier': 'CUEI',
                                        'name': 'Avail '
                                                'Descriptor',
                                        'provider_avail_id': 309,
                                        'splice_descriptor_tag': 0}]}}

🡡 top

Advanced threefive

Splice Class

  • source splice.py

  • The threefive.Splice class decodes a SCTE35 binary, base64, or hex encoded string.

  • threefive.Splice provides several methods to access the parsed data.

from threefive import Splice

b64 = "/DBIAAAAAAAA///wBQb+ek2ItgAyAhdDVUVJSAAAGH+fCAgAAAAALMvDRBEAAAIXQ1VFSUgAABl/nwgIAAAAACyk26AQAACZcuND"

scte35 = Splice(b64)

Pretty Print SCTE 35 Message

scte35.show()

Return SCTE 35 Message

scte35.get()

Pretty Print Splice Info Section

scte35.show_info_section()

Return Splice Info Section

scte35.get_info_section()

Pretty print Splice Command

scte35.show_command()

{ 'name': 'Time Signal',
  'pts_time': 22798.906911,
  'time_specified_flag': True}

Return Splice Command

scte35.get_command()

Pretty Print Splice Descriptors

scte35.show_descriptors()

Return Splice Descriptors

scte35.get_descriptors()

🡡 top


Stream Class

  • source stream.py

  • The threefive.Stream class parses SCTE35 messages from a file or stream.

  threefive.Stream(tsdata, show_null = False)
  • tsdata is an open file handle or sys.stdin.buffer to read 'piped' in data.
  • show_null if set to True, enables showing SCTE 35 null commands.

Parse a Local File with a Stream Instance

import sys
from threefive import Stream
'''

if __name__ =='__main__':
   with open(sys.argv[1],'rb') as tsdata:
       Stream(tsdata)

Pipe a Video to Stream

curl -s https://futzu.com/xaa.ts -o -  \
  | python3 -c 'import sys;import threefive; threefive.Stream(sys.stdin.buffer)' 

{ 'SCTE35': { 'Info_Section': { 'crc': '0x10fa4d9e',
                                'cw_index': '0x0',
                                'descriptor_loop_length': 10,
                                'encrypted_packet': False,
                                'encryption_algorithm': 0,
                                'private': False,
                                'protocol_version': 0,
                                'pts_adjustment': 0.0,
                                'reserved': '0x3',
                                'section_length': 47,
                                'section_syntax_indicator': False,
                                'splice_command_length': 4095,
                                'splice_command_type': 5,
                                'table_id': '0xfc',
                                'tier': '0xfff'},
              'Splice_Command': { 'avail_expected': 0,
                                  'avail_num': 0,
                                  'break_auto_return': False,
                                  'break_duration': 242.0,
                                  'duration_flag': True,
                                  'name': 'Splice '
                                          'Insert',
                                  'out_of_network_indicator': True,
                                  'program_splice_flag': True,
                                  'pts_time': 89742.161689,
                                  'splice_event_cancel_indicator': False,
                                  'splice_event_id': 662,
                                  'splice_immediate_flag': False,
                                  'time_specified_flag': True,
                                  'unique_program_id': 1},
              'Splice_Descriptors': [ { 'descriptor_length': 8,
                                        'identifier': 'CUEI',
                                        'name': 'Avail '
                                                'Descriptor',
                                        'provider_avail_id': 0,
                                        'splice_descriptor_tag': 0}]}}

🡡 top


StreamPlus Class

  • source streamplus.py
  • threefive.StreamPlus is a sub class of threefive.Stream
  threefive.StreamPlus(tsdata, show_null = False)
  • tsdata is an open file handle or sys.stdin.buffer to read 'piped' in data.

  • show_null if set to True, enables showing SCTE 35 null commands.

  • threefive.StreamPlus adds the PID and PTS timestamp for each SCTE 35 packet.

Parse a Local File with a StreamPlus Instance

import sys
from threefive import StreamPlus
'''

if __name__ =='__main__':
   with open(sys.argv[1],'rb') as tsdata:
       StreamPlus(tsdata)

Pipe a Video to StreamPlus

curl -s https://futzu.com/xaa.ts -o - \
| python3 -c 'import sys;import threefive; threefive.StreamPlus(sys.stdin.buffer)'

{ 'SCTE35': { 'Info_Section': { 'crc': '0x10fa4d9e',
                                'cw_index': '0x0',
                                'descriptor_loop_length': 10,
                                'encrypted_packet': False,
                                'encryption_algorithm': 0,
                                'private': False,
                                'protocol_version': 0,
                                'pts_adjustment': 0.0,
                                'reserved': '0x3',
                                'section_length': 47,
                                'section_syntax_indicator': False,
                                'splice_command_length': 4095,
                                'splice_command_type': 5,
                                'table_id': '0xfc',
                                'tier': '0xfff'},
              'Packet': { 'pid': '0x135',              <-- Pid of the SCTE 35 Packet
                          'pts': 89730.289522},        <-- PTS of the SCTE 35 Packet
              'Splice_Command': { 'avail_expected': 0,
                                  'avail_num': 0,
                                  'break_auto_return': False,
                                  'break_duration': 242.0,
                                  'duration_flag': True,
                                  'name': 'Splice '
                                          'Insert',
                                  'out_of_network_indicator': True,
                                  'program_splice_flag': True,
                                  'pts_time': 89742.161689,
                                  'splice_event_cancel_indicator': False,
                                  'splice_event_id': 662,
                                  'splice_immediate_flag': False,
                                  'time_specified_flag': True,
                                  'unique_program_id': 1},
              'Splice_Descriptors': [ { 'descriptor_length': 8,
                                        'identifier': 'CUEI',
                                        'name': 'Avail '
                                                'Descriptor',
                                        'provider_avail_id': 0,
                                        'splice_descriptor_tag': 0}]}}

🡡 top

Project details


Release history Release notifications | RSS feed

This version

2.1.3

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

threefive-2.1.3.tar.gz (14.3 kB view hashes)

Uploaded Source

Built Distribution

threefive-2.1.3-py3-none-any.whl (14.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page