Skip to main content

A Fast 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')

JSON Output for MpegTS and Binary Files and Streams

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


{
        "SCTE35": {
                "Info_Section": {
                        "table_id": "0xfc",
                        "section_syntax_indicator": false,
                        "private": false,
                        "reserved": "0x3",
                        "section_length": 42,
                        "protocol_version": 0,
                        "encrypted_packet": false,
                        "encryption_algorithm": 0,
                        "pts_adjustment": 0.0,
                        "cw_index": "0x0",
                        "tier": "0xfff",
                        "splice_command_length": 15,
                        "splice_command_type": 5,
                        "descriptor_loop_length": 10,
                        "crc": "0x6e33321e"
                },
                "Splice_Command": {
                        "name": "Splice Insert",
                        "splice_event_id": 662,
                        "splice_event_cancel_indicator": false,
                        "out_of_network_indicator": false,
                        "program_splice_flag": true,
                        "duration_flag": false,
                        "splice_immediate_flag": false,
                        "time_specified_flag": true,
                        "pts_time": 89984.161689,
                        "unique_program_id": 1,
                        "avail_num": 0,
                        "avail_expected": 0,
                        "splice_command_length": 15
                },
                "Splice_Descriptors": [
                        {
                                "tag": 0,
                                "identifier": "CUEI",
                                "name": "Avail Descriptor",
                                "provider_avail_id": 0,
                                "descriptor_length": 8
                        }
                ]
        }
}

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": {
                        "table_id": "0xfc",
                        "section_syntax_indicator": false,
                        "private": false,
                        "reserved": "0x3",
                        "section_length": 47,
                        "protocol_version": 0,
                        "encrypted_packet": false,
                        "encryption_algorithm": 0,
                        "pts_adjustment": 0.0,
                        "cw_index": "0xff",
                        "tier": "0xfff",
                        "splice_command_length": 20,
                        "splice_command_type": 5,
                        "descriptor_loop_length": 10,
                        "crc": "0x62dba30a"
                },
                "Splice_Command": {
                        "name": "Splice Insert",
                        "splice_event_id": 1207959695,
                        "splice_event_cancel_indicator": false,
                        "out_of_network_indicator": true,
                        "program_splice_flag": true,
                        "duration_flag": true,
                        "splice_immediate_flag": false,
                        "time_specified_flag": true,
                        "pts_time": 21514.559089,
                        "break_auto_return": true,
                        "break_duration": 60.293567,
                        "unique_program_id": 0,
                        "avail_num": 0,
                        "avail_expected": 0,
                        "splice_command_length": 20
                },
                "Splice_Descriptors": [
                        {
                                "tag": 0,
                                "identifier": "CUEI",
                                "name": "Avail Descriptor",
                                "provider_avail_id": 309,
                                "descriptor_length": 8
                        }
                ]
        }
}

🡡 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)

JSON Pretty Print SCTE 35 Message

scte35.show()

Return SCTE 35 Message

scte35.get()

JSON Pretty Print Splice Info Section

scte35.show_info_section()

Return Splice Info Section

scte35.get_info_section()

JSON Pretty Print Splice Command

scte35.show_command()

Return Splice Command

scte35.get_command()

JSON 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": {
                        "table_id": "0xfc",
                        "section_syntax_indicator": false,
                        "private": false,
                        "reserved": "0x3",
                        "section_length": 47,
                        "protocol_version": 0,
                        "encrypted_packet": false,
                        "encryption_algorithm": 0,
                        "pts_adjustment": 0.0,
                        "cw_index": "0x0",
                        "tier": "0xfff",
                        "splice_command_length": 20,
                        "splice_command_type": 5,
                        "descriptor_loop_length": 10,
                        "crc": "0x10fa4d9e"
                },
                "Splice_Command": {
                        "name": "Splice Insert",
                        "splice_event_id": 662,
                        "splice_event_cancel_indicator": false,
                        "out_of_network_indicator": true,
                        "program_splice_flag": true,
                        "duration_flag": true,
                        "splice_immediate_flag": false,
                        "time_specified_flag": true,
                        "pts_time": 89742.161689,
                        "break_auto_return": false,
                        "break_duration": 242.0,
                        "unique_program_id": 1,
                        "avail_num": 0,
                        "avail_expected": 0,
                        "splice_command_length": 20
                },
                "Splice_Descriptors": [
                        {
                                "tag": 0,
                                "identifier": "CUEI",
                                "name": "Avail Descriptor",
                                "provider_avail_id": 0,
                                "descriptor_length": 8
                        }
                ]
        }
}

🡡 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": {
                        "table_id": "0xfc",
                        "section_syntax_indicator": false,
                        "private": false,
                        "reserved": "0x3",
                        "section_length": 47,
                        "protocol_version": 0,
                        "encrypted_packet": false,
                        "encryption_algorithm": 0,
                        "pts_adjustment": 0.0,
                        "cw_index": "0x0",
                        "tier": "0xfff",
                        "splice_command_length": 20,
                        "splice_command_type": 5,
                        "descriptor_loop_length": 10,
                        "crc": "0x10fa4d9e"
                },
                "Splice_Command": {
                        "name": "Splice Insert",
                        "splice_event_id": 662,
                        "splice_event_cancel_indicator": false,
                        "out_of_network_indicator": true,
                        "program_splice_flag": true,
                        "duration_flag": true,
                        "splice_immediate_flag": false,
                        "time_specified_flag": true,
                        "pts_time": 89742.161689,
                        "break_auto_return": false,
                        "break_duration": 242.0,
                        "unique_program_id": 1,
                        "avail_num": 0,
                        "avail_expected": 0,
                        "splice_command_length": 20
                },
                "Splice_Descriptors": [
                        {
                                "tag": 0,
                                "identifier": "CUEI",
                                "name": "Avail Descriptor",
                                "provider_avail_id": 0,
                                "descriptor_length": 8
                        }
                ],
                "Packet_Data": {
                        "pid": "0x135",       <--- Packet PID
                        "pts": 89730.289522   <---- Packet PTS
                }
        }
}

🡡 top

Project details


Release history Release notifications | RSS feed

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.19.tar.gz (15.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

threefive-2.1.19-py3-none-any.whl (14.7 kB view details)

Uploaded Python 3

File details

Details for the file threefive-2.1.19.tar.gz.

File metadata

  • Download URL: threefive-2.1.19.tar.gz
  • Upload date:
  • Size: 15.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.4.2 requests/2.23.0 setuptools/44.0.0 requests-toolbelt/0.8.0 tqdm/4.43.0 CPython/3.8.2

File hashes

Hashes for threefive-2.1.19.tar.gz
Algorithm Hash digest
SHA256 b4d716f2d8745ceb5f15a6b8bee367233cdd4a5553e78de32fd2456729eda0b1
MD5 5c6b9757413114976e9246f7ecaf4888
BLAKE2b-256 0a0f47c0e64ed38fd33aa4943a7214d0d2cd47c02d68682e4150f4e4ca111dac

See more details on using hashes here.

File details

Details for the file threefive-2.1.19-py3-none-any.whl.

File metadata

  • Download URL: threefive-2.1.19-py3-none-any.whl
  • Upload date:
  • Size: 14.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.4.2 requests/2.23.0 setuptools/44.0.0 requests-toolbelt/0.8.0 tqdm/4.43.0 CPython/3.8.2

File hashes

Hashes for threefive-2.1.19-py3-none-any.whl
Algorithm Hash digest
SHA256 ad8ffd394b663ac4f3cdcb70d7f90a5750bd88c4e937ad9186dc4dd715917f95
MD5 723102048409075f85a7aaa36891c0bc
BLAKE2b-256 3395345490162c115a09968aed6dead977188ce258b918569187075390f32ce2

See more details on using hashes here.

Supported by

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