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)
Fast Start Directions
Dependencies
- Python 3
- bitn
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
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
}
]
}
}
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)
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
}
]
}
}
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
}
}
}
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 hashes)
Built Distribution
threefive-2.1.19-py3-none-any.whl
(14.7 kB
view hashes)
Close
Hashes for threefive-2.1.19-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ad8ffd394b663ac4f3cdcb70d7f90a5750bd88c4e937ad9186dc4dd715917f95 |
|
MD5 | 723102048409075f85a7aaa36891c0bc |
|
BLAKE2b-256 | 3395345490162c115a09968aed6dead977188ce258b918569187075390f32ce2 |