A Fast SCTE 35 Decoder for Mpeg-TS Video, and Base64 or Hex Encoded Messages.
Project description
threefive
SCTE35 Decoder
Splice Commands
- source command.py
- Splice Null
- Splice Schedule
- Splice Insert
- Time Signal
- Bandwidth Reservation
Splice Descriptors
- source descriptor.py
- DTMF Descriptor
- Segmentation Descriptor (all segmentation Upids)
- Segmentation Types and Messages
- Time Descriptor
- Audio Descriptor
Fast Start Directions
Dependencies
- Python 3
- bitn
Install
git
git clone https://github.com/futzu/SCTE35-threefive.git
cd SCTE-threefive
# you need root to install for the system
make install
...
Processing threefive-2.1.39-py3.8.egg
Copying threefive-2.1.39-py3.8.egg to /usr/local/lib/python3.8/dist-packages
Adding threefive 2.1.39 to easy-install.pth file
Installed /usr/local/lib/python3.8/dist-packages/threefive-2.1.39-py3.8.egg
Processing dependencies for threefive==2.1.39
Searching for bitn==0.0.27
Best match: bitn 0.0.27
Processing bitn-0.0.27-py3.8.egg
bitn 0.0.27 is already the active version in easy-install.pth
Using /usr/local/lib/python3.8/dist-packages/bitn-0.0.27-py3.8.egg
Finished processing dependencies for threefive==2.1.39
pip3
pip3 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
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='/DBUAAAAAAAA///wBQb+AAAAAAA+AjxDVUVJAAAACn+/Dy11cm46dXVpZDphYTg1YmJiNi01YzQzLTRiNmEtYmViYi1lZTNiMTNlYjc5OTkRAAB2c6LA'
threefive.decode(mesg)
Hex Encoded Strings
hexed='0xFC302F000000000000FFFFF014054800008F7FEFFE7369C02EFE0052CCF500000000000A0008435545490000013562DBA30A'
threefive.decode(hexed)
JSON Output for Base64 and Hex Strings
{
"SCTE35": {
"Info_Section": {
"table_id": "0xfc",
"section_syntax_indicator": false,
"private": false,
"reserved": "0x3",
"section_length": 84,
"protocol_version": 0,
"encrypted_packet": false,
"encryption_algorithm": 0,
"pts_adjustment": 0.0,
"cw_index": "0xff",
"tier": "0xfff",
"splice_command_length": 5,
"splice_command_type": 6,
"descriptor_loop_length": 62,
"crc": "0x7673a2c0"
},
"Splice_Command": {
"name": "Time Signal",
"time_specified_flag": true,
"pts_time": 0.0
},
"Splice_Descriptors": [
{
"tag": 2,
"identifier": "CUEI",
"name": "Segmentation Descriptor",
"segmentation_event_id": "0xa",
"segmentation_event_cancel_indicator": false,
"program_segmentation_flag": true,
"segmentation_duration_flag": false,
"delivery_not_restricted_flag": true,
"segmentation_upid_type": 15,
"segmentation_upid_length": 45,
"segmentation_upid": "URI:urn:uuid:aa85bbb6-5c43-4b6a-bebb-ee3b13eb7999",
"segmentation_type_id": 17,
"segmentation_message": "Program End",
"segment_num": 0,
"segments_expected": 0,
"descriptor_length": 60
}
]
}
}
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()
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).decode()
Pipe a Video to Stream
curl -s https://futzu.com/xaa.ts -o - \
| python3 -c 'import sys;import threefive; threefive.Stream(sys.stdin.buffer).decode()'
{
"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
}
]
}
}
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).decode()
Pipe a Video to StreamPlus
curl -s https://futzu.com/xaa.ts -o - \
| python3 -c 'import sys;import threefive; threefive.StreamPlus(sys.stdin.buffer).decode()'
{
"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
}
}
}
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.69.tar.gz
(16.5 kB
view hashes)
Built Distribution
threefive-2.1.69-py3-none-any.whl
(15.4 kB
view hashes)
Close
Hashes for threefive-2.1.69-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7a556785ea6c7dbc4152c9247c31dbd10f6ac54b6acb29e14d8882a86e2045f3 |
|
MD5 | a207b085e3338ae34f4e39382a352032 |
|
BLAKE2b-256 | 472a067546ec86d631adedf8cdd01669ed7765552cc796a66ce8689b93bafed9 |