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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4d716f2d8745ceb5f15a6b8bee367233cdd4a5553e78de32fd2456729eda0b1
|
|
| MD5 |
5c6b9757413114976e9246f7ecaf4888
|
|
| BLAKE2b-256 |
0a0f47c0e64ed38fd33aa4943a7214d0d2cd47c02d68682e4150f4e4ca111dac
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad8ffd394b663ac4f3cdcb70d7f90a5750bd88c4e937ad9186dc4dd715917f95
|
|
| MD5 |
723102048409075f85a7aaa36891c0bc
|
|
| BLAKE2b-256 |
3395345490162c115a09968aed6dead977188ce258b918569187075390f32ce2
|