threefive is The #1 SCTE-35 tool on the Planet. Death to those who oppose me.
Project description
Install |SCTE-35 Cli | SCTE-35 HLS | Cue Class | Stream Class | Online SCTE-35 Parser | Encode SCTE-35 | SCTE-35 Examples
| SCTE-35 XML and More XML | SuperKabuki SCTE-35 MPEGTS Packet Injection | SCTE-35 As a Service
v3.0.57 is the latest
- threefive installs.
- today: 350
- last seven days: 2,288
- last thirty days: 10,491
- last five years: 1,029,995
threefive
- Decodes SCTE-35 in TEN formats: MPEGTS, Base64, Bytes, Dicts, Hex,HLS, Integers,JSON,XML and XML+Binary.
- Encodes SCTE-35 in EIGHT formats: MPEGTS, Base64, Bytes, Hex, Int, JSON,XML, and Xml+binary.
- Supports All HLS SCTE-35 Tags.
- Does Automatic AES decryption for MPEGTS and HLS.
- Has Built-in Multicast Sender and Receiver.
- Injects SCTE-35 Packets into MPEGTS video.
The SuperKabuki SCTE-35 MPEGTS Packet Injection Engine
Sassy, the new SCTE-35 as a service, Decode SCTE-35 in your browser
Super Cool SCTE-35 Examples
New XML stuff in threefive
Documentation
Install
Quick Start
- Here's how to decode these SCTE-35 formats with threefive.
- This covers both the Cli tool and library.
MPEGTS
* MPEGTS streams can be Files, Http(s), Multicast, UDP Unicast, or stdin.- cli
threefive https://example.com/video.ts
- wildcards work too.
threefive /mpegts/*.ts
- lib
from threefive import Stream
stream = Stream('https://example.com/video.ts')
stream.decode()
Base64
- cli
threefive '/DAsAAAAAyiYAP/wCgUAAAABf1+ZmQEBABECD0NVRUkAAAAAf4ABADUAAC2XQZU='
- lib
from threefive import Cue
data = '/DAsAAAAAyiYAP/wCgUAAAABf1+ZmQEBABECD0NVRUkAAAAAf4ABADUAAC2XQZU='
cue=Cue(data)
cue.show()
Bytes
-
cli
- Bytes don't work on the cli
-
lib
from threefive import Cue
data = b'\xfc0\x16\x00\x00\x00\x00\x00\x00\x00\xff\xf0\x05\x06\xfe\x00\xc0D\xa0\x00\x00\x00\xb5k\x88'
cue=Cue(data)
cue.show()
Hex
-
Can be a hex literal or hex string or bytes.
-
cli
threefive 0xfc301600000000000000fff00506fed605225b0000b0b65f3b
- lib
from threefive import Cue
data = 0xfc301600000000000000fff00506fed605225b0000b0b65f3b
cue=Cue(data)
cue.show()
Int
-
Can be a literal integer or string or bytes.
-
cli
threefive 1583008701074197245727019716796221243043855984942057168199483b
- lib
from threefive import Cue
data = 1583008701074197245727019716796221243043855984942057168199483
cue=Cue(data)
cue.show()
JSON
- cli
- put JSON SCTE-35 in a file and redirect it into threefive
threefive < json.json
- lib
from threefive import Cue
data = '''{
"info_section": {
"table_id": "0xfc",
"section_syntax_indicator": false,
"private": false,
"sap_type": "0x03",
"sap_details": "No Sap Type",
"section_length": 22,
"protocol_version": 0,
"encrypted_packet": false,
"encryption_algorithm": 0,
"pts_adjustment": 0.0,
"cw_index": "0x00",
"tier": "0x0fff",
"splice_command_length": 5,
"splice_command_type": 6,
"descriptor_loop_length": 0,
"crc": "0xb56b88"
},
"command": {
"command_length": 5,
"command_type": 6,
"name": "Time Signal",
"time_specified_flag": true,
"pts_time": 140.005333
},
"descriptors": []
}
'''
cue=Cue(data)
cue.show()
Xml
- cli
- put xml SCTE-35 in a file and redirect it into threefive
threefive < xmlbin.xml
- lib
from threefive import Cue
data = '''
<scte35:SpliceInfoSection xmlns:scte35="https://scte.org/schemas/35"
ptsAdjustment="0" protocolVersion="0" sapType="3" tier="4095">
<scte35:TimeSignal>
<scte35:SpliceTime ptsTime="12600480"/>
</scte35:TimeSignal>
</scte35:SpliceInfoSection>
'''
cue=Cue(data)
cue.show()
Xml+binary
- cli
- write xml+binary to a file and redirect it to threefive
threefive < xmlbin.xml
- lib
from threefive import Cue
data = '''<scte35:Signal xmlns:scte35="https://scte.org/schemas/35">
<scte35:Binary>/DAWAAAAAAAAAP/wBQb+AMBEoAAAALVriA==</scte35:Binary>
</scte35:Signal>
'''
cue=Cue(data)
cue.show()
Examples
XML
- XML New! updated 05/01/2025
Cli
- SCTE-35 Cli Super Tool Encodes, Decodes, and Recodes. This is pretty cool, it does SCTE-35 seven different ways.
- The cli tool comes with builtin documentation just type
threefive help
- The cli tool comes with builtin documentation just type
HLS
- Advanced Parsing of SCTE-35 in HLS with threefive All HLS SCTE-35 tags, Sidecar Files, AAC ID3 Header Timestamps, SCTE-35 filters... Who loves you baby?
MPEGTS Packet Injection
SCTE-35 As a Service
- Decode SCTE-35 without installing anything. If you can make an https request, you can use Sassy to decode SCTE-35. .
Classes
- The python built in help is always the most up to date docs for the library.
a@fu:~/build7/threefive$ pypy3
>>>> from threefive import Stream
>>>> help(Stream)
- Class Structure
- Cue Class Cue is the main SCTE-35 class to use.
- Stream Class The Stream class handles MPEGTS SCTE-35 streams local, Http(s), UDP, and Multicast.
| more
-
Online SCTE-35 Parser Supporte Base64, Bytes,Hex,Int, Json, Xml, and Xml+binary.
-
Encode SCTE-35 Some encoding code examples.
Install
- python3 via pip
python3 -mpip install threefive
- pypy3
pypy3 -mpip install threefive
- from the git repo
git clone https://github.com/superkabuki/scte35.git
cd threefive
make install
Using the library
- Let me show you how easy threefive is to use.
- well start off reading SCTE-35 xml from a file
a@fu:~/threefive$ pypy3
Python 3.9.16 (7.3.11+dfsg-2+deb12u3, Dec 30 2024, 22:36:23)
[PyPy 7.3.11 with GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>> from threefive import reader
>>>> from threefive import Cue
>>>> data =reader('/home/a/xml.xml').read()
* load it into a threefive.Cue instance
```py3
>>>> cue = Cue(data)
- Show the data as JSON
>>>> cue.show()
{
"info_section": {
"table_id": "0xfc",
"section_syntax_indicator": false,
"private": false,
"sap_type": "0x03",
"sap_details": "No Sap Type",
"section_length": 92,
"protocol_version": 0,
"encrypted_packet": false,
"encryption_algorithm": 0,
"pts_adjustment": 0.0,
"cw_index": "0x00",
"tier": "0x0fff",
"splice_command_length": 15,
"splice_command_type": 5,
"descriptor_loop_length": 60,
"crc": "0x7632935"
},
"command": {
"command_length": 15,
"command_type": 5,
"name": "Splice Insert",
"break_auto_return": false,
"break_duration": 180.0,
"splice_event_id": 1073743095,
"splice_event_cancel_indicator": false,
"out_of_network_indicator": true,
"program_splice_flag": false,
"duration_flag": true,
"splice_immediate_flag": false,
"event_id_compliance_flag": true,
"unique_program_id": 1,
"avail_num": 12,
"avails_expected": 5
},
"descriptors": [
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 12,
"descriptor_length": 8
},
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 13,
"descriptor_length": 8
},
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 14,
"descriptor_length": 8
},
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 15,
"descriptor_length": 8
},
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 16,
"descriptor_length": 8
},
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 17,
"descriptor_length": 8
}
]
}
- convert the data back to xml
>>>> print(cue.xml())
<scte35:SpliceInfoSection xmlns:scte35="https://scte.org/schemas/35" ptsAdjustment="0" protocolVersion="0" sapType="3" tier="4095">
<scte35:SpliceInsert spliceEventId="1073743095" spliceEventCancelIndicator="false" spliceImmediateFlag="false" eventIdComplianceFlag="true" availNum="12" availsExpected="5" outOfNetworkIndicator="true" uniqueProgramId="1">
<scte35:BreakDuration autoReturn="false" duration="16200000"/>
</scte35:SpliceInsert>
<scte35:AvailDescriptor providerAvailId="12"/>
<scte35:AvailDescriptor providerAvailId="13"/>
<scte35:AvailDescriptor providerAvailId="14"/>
<scte35:AvailDescriptor providerAvailId="15"/>
<scte35:AvailDescriptor providerAvailId="16"/>
<scte35:AvailDescriptor providerAvailId="17"/>
</scte35:SpliceInfoSection>
- convert to xml+binary
>>>> print(cue.xmlbin())
<scte35:Signal xmlns:scte35="https://scte.org/schemas/35">
<scte35:Binary>/DBcAAAAAAAAAP/wDwVAAAT3f69+APcxQAABDAUAPAAIQ1VFSQAAAAwACENVRUkAAAANAAhDVUVJAAAADgAIQ1VFSQAAAA8ACENVRUkAAAAQAAhDVUVJAAAAEQdjKTU=</scte35:Binary>
</scte35:Signal>
- convert to base64
>>>> print(cue.base64())
/DBcAAAAAAAAAP/wDwVAAAT3f69+APcxQAABDAUAPAAIQ1VFSQAAAAwACENVRUkAAAANAAhDVUVJAAAADgAIQ1VFSQAAAA8ACENVRUkAAAAQAAhDVUVJAAAAEQdjKTU=
- convert to hex
>>>> print(cue.hex())
0xfc305c00000000000000fff00f05400004f77faf7e00f7314000010c05003c0008435545490000000c0008435545490000000d0008435545490000000e0008435545490000000f000843554549000000100008435545490000001107632935
- show just the splice command
>>>> cue.command.show()
{
"command_length": 15,
"command_type": 5,
"name": "Splice Insert",
"break_auto_return": false,
"break_duration": 180.0,
"splice_event_id": 1073743095,
"splice_event_cancel_indicator": false,
"out_of_network_indicator": true,
"program_splice_flag": false,
"duration_flag": true,
"splice_immediate_flag": false,
"event_id_compliance_flag": true,
"unique_program_id": 1,
"avail_num": 12,
"avails_expected": 5
}
- edit the break duration
>>>> cue.command.break_duration=30
>>>> cue.command.show()
{
"command_length": 15,
"command_type": 5,
"name": "Splice Insert",
"break_auto_return": false,
"break_duration": 30,
"splice_event_id": 1073743095,
"splice_event_cancel_indicator": false,
"out_of_network_indicator": true,
"program_splice_flag": false,
"duration_flag": true,
"splice_immediate_flag": false,
"event_id_compliance_flag": true,
"unique_program_id": 1,
"avail_num": 12,
"avails_expected": 5
}
- re-encode to base64 with the new duration
>>>> cue.base64()
'/DBcAAAAAAAAAP/wDwVAAAT3f69+ACky4AABDAUAPAAIQ1VFSQAAAAwACENVRUkAAAANAAhDVUVJAAAADgAIQ1VFSQAAAA8ACENVRUkAAAAQAAhDVUVJAAAAEe1FB6g='
- re-encode to xml with the new duration
>>>> print(cue.xml())
<scte35:SpliceInfoSection xmlns:scte35="https://scte.org/schemas/35" ptsAdjustment="0" protocolVersion="0" sapType="3" tier="4095">
<scte35:SpliceInsert spliceEventId="1073743095" spliceEventCancelIndicator="false" spliceImmediateFlag="false" eventIdComplianceFlag="true" availNum="12" availsExpected="5" outOfNetworkIndicator="true" uniqueProgramId="1">
<scte35:BreakDuration autoReturn="false" duration="2700000"/>
</scte35:SpliceInsert>
<scte35:AvailDescriptor providerAvailId="12"/>
<scte35:AvailDescriptor providerAvailId="13"/>
<scte35:AvailDescriptor providerAvailId="14"/>
<scte35:AvailDescriptor providerAvailId="15"/>
<scte35:AvailDescriptor providerAvailId="16"/>
<scte35:AvailDescriptor providerAvailId="17"/>
</scte35:SpliceInfoSection>
- show just the descriptors
>>>> _ = [d.show() for d in cue.descriptors]
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 12,
"descriptor_length": 8
}
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 13,
"descriptor_length": 8
}
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 14,
"descriptor_length": 8
}
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 15,
"descriptor_length": 8
}
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 16,
"descriptor_length": 8
}
{
"tag": 0,
"identifier": "CUEI",
"name": "Avail Descriptor",
"provider_avail_id": 17,
"descriptor_length": 8
}
- pop off the last descriptor and re-encode to xml
>>>> cue.descriptors.pop()
{'tag': 0, 'identifier': 'CUEI', 'name': 'Avail Descriptor', 'private_data': None, 'provider_avail_id': 17, 'descriptor_length': 8}
>>>> print(cue.xml())
<scte35:SpliceInfoSection xmlns:scte35="https://scte.org/schemas/35" ptsAdjustment="0" protocolVersion="0" sapType="3" tier="4095">
<scte35:SpliceInsert spliceEventId="1073743095" spliceEventCancelIndicator="false" spliceImmediateFlag="false" eventIdComplianceFlag="true" availNum="12" availsExpected="5" outOfNetworkIndicator="true" uniqueProgramId="1">
<scte35:BreakDuration autoReturn="false" duration="2700000"/>
</scte35:SpliceInsert>
<scte35:AvailDescriptor providerAvailId="12"/>
<scte35:AvailDescriptor providerAvailId="13"/>
<scte35:AvailDescriptor providerAvailId="14"/>
<scte35:AvailDescriptor providerAvailId="15"/>
<scte35:AvailDescriptor providerAvailId="16"/>
</scte35:SpliceInfoSection>
The Cli tool
The cli tool installs automatically with pip or the Makefile.
- SCTE-35 Inputs
- SCTE-35 Outputs
- Parse MPEGTS streams for SCTE-35
- Parse SCTE-35 in hls
- Display MPEGTS iframes
- Display raw SCTE-35 packets from video streams
- Repair SCTE-35 streams changed to bin data by ffmpeg
Inputs
- Most inputs are auto-detected.
- stdin is auto selected and auto detected.
- SCTE-35 data is printed to stderr
- stdout is used when piping video
- mpegts can be specified by file name or URI.
threefive udp://@235.2.5.35:3535
- If a file comtains a SCTE-35 cue as a string( base64,hex,int,json,or xml+bin), redirect the file contents.
threefive < json.json
- quoted strings(( base64,hex,int,json or xml+bin), can be passed directly on the command line as well.
threefive '/DAWAAAAAAAAAP/wBQb+ztd7owAAdIbbmw=='
Input Type | Cli Example |
---|---|
Base64 | threefive '/DAsAAAAAyiYAP/wCgUAAAABf1+ZmQEBABECD0NVRUkAAAAAf4ABADUAAC2XQZU=' |
Hex | threefive 0xfc301600000000000000fff00506fed605225b0000b0b65f3b |
HLS | threefive hls https://example.com/master.m3u8 |
JSON | threefive < json.json |
Xmlbin | js threefive < xmlbin.xml |
Streams
Protocol | Cli Example |
---|---|
File | threefive video.ts |
Http(s) | threefive https://example.com/video.ts |
Stdin | threefive < video.ts |
UDP Multicast | threefive udp://@235.35.3.5:9999 |
UDP Unicast | threefive udp://10.0.0.7:5555 |
HLS__ | threefive hls https://example.com/master.m3u8 |
Outputs
- output type is determined by the key words base64, bytes, hex, int, json, and xmlbin.
- json is the default.
- Any input (except HLS,) can be returned as any output
- examples Base64 to Hex etc...)
Output Type | Cli Example |
---|---|
Base 64 | threefive 0xfc301600000000000000fff00506fed605225b0000b0b65f3b base64 |
Bytes | threefive 0xfc301600000000000000fff00506fed605225b0000b0b65f3b bytes |
Hex | threefive '/DAsAAAAAyiYAP/wCgUAAAABf1+ZmQEBABECD0NVRUkAAAAAf4ABADUAAC2XQZU=' hex |
Integer | threefive '/DAsAAAAAyiYAP/wCgUAAAABf1+ZmQEBABECD0NVRUkAAAAAf4ABADUAAC2XQZU=' int |
JSON | threefive 0xfc301600000000000000fff00506fed605225b0000b0b65f3b json |
Xml+bin | threefive 0xfc301600000000000000fff00506fed605225b0000b0b65f3b xmlbin |
hls
- parse hls manifests and segments for SCTE-35
threefive hls https://example.com/master.m3u8
Iframes
- Show iframes PTS in an MPEGTS video
threefive iframes https://example.com/video.ts
packets
- Print raw SCTE-35 packets from multicast mpegts video
threefive packets udp://@235.35.3.5:3535
proxy
- Parse a https stream and write raw video to stdout
threefive proxy video.ts
pts
- Print PTS from mpegts video
threefive pts video.ts
sidecar
- Parse a stream, write pts,write SCTE-35 Cues to sidecar.txt
threefive sidecar video.ts
sixfix
- Fix SCTE-35 data mangled by ffmpeg
threefive sixfix video.ts
show
- Probe mpegts video ( kind of like ffprobe )
threefive show video.ts
version
- Show version
threefive version
help
- Help
threefive help
Stream Multicast with the threefive cli, it's easy.
- The threefive cli has long been a Multicast Receiver( client )
- The cli now comes with a builtin Multicast Sender( server).
- Start the Receiver first
- It's optimized for MPEGTS (1316 byte Datagrams) but you can send any video or file.
- The defaults will work in most situations, you don't even have to set the address.
- threefive cli also supports UDP Unicast Streaming.
a@fu:~$ threefive mcast help
usage: threefive mcast [-h] [-i INPUT] [-a ADDR] [-b BIND_ADDR] [-t TTL]
optional arguments:
-h, --help show this help message and exit
-i INPUT, --input INPUT
like "/home/a/vid.ts" or "udp://@235.35.3.5:3535" or
"https://futzu.com/xaa.ts"
[default:sys.stdin.buffer]
-a ADDR, --addr ADDR Destination IP:Port [default:235.35.3.5:3535]
-b BIND_ADDR, --bind_addr BIND_ADDR
Local IP to bind [default:0.0.0.0]
-t TTL, --ttl TTL Multicast TTL (1 - 255) [default:32]
a@fu:~$
iodisco.com/scte35
Month | Savings |
---|---|
January | $100 |
Base64 SCTE-35
- The Cli tool can decode Base64 SCTE-35 on the command line.
a@fu:~$ threefive '/DAgAAAAAAAAAP/wDwUAAAABf//+AA27oAABAAAAANwB3tE='
- Using the library Base64 SCTE-35 is decoded by the Cue class.
from threefive import Cue
data='/DAgAAAAAAAAAP/wDwUAAAABf//+AA27oAABAAAAANwB3tE='
cue=Cue(data)
cue.show()
Hex SCTE-35
- The Cli tool
a@fu:~$ threefive 0xfc302000000000000000fff00f05000000017ffffe000dbba0000100000000dc01ded1
- Convert from Hex to bas64,bytes,json,Int, xml or xmlbin
a@fu:~$ threefive 0xfc302000000000000000fff00f05000000017ffffe000dbba0000100000000dc01ded1 base64
a@fu:~$ threefive 0xfc302000000000000000fff00f05000000017ffffe000dbba0000100000000dc01ded1 xml
- Convert to Hex
a@fu:~$ threefive '/DAgAAAAAAAAAP/wDwUAAAABf//+AA27oAABAAAAANwB3tE=' hex
- lib
from threefive import Cue
data='0xfc302000000000000000fff00f05000000017ffffe000dbba0000100000000dc01ded1''
cue=Cue(data)
cue.show()
- Convert from Hex to bas64,bytes,json,Int, xml or xmlbin
from threefive import Cue
data='0xfc302000000000000000fff00f05000000017ffffe000dbba0000100000000dc01ded1''
cue=Cue(data)
cue.base64() # base64
cue.bytes() # or bytes
cue.show() # or json
cue.int() # or int
cue.xml() # or xml
cue.xmlbin() # or xmlbin
Install |SCTE-35 Cli | SCTE-35 HLS | Cue Class | Stream Class | Online SCTE-35 Parser | Encode SCTE-35 | SCTE-35 Examples | SCTE-35 XML and More XML | threefive runs Four Times Faster on pypy3 | SuperKabuki SCTE-35 MPEGTS Packet Injection
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
File details
Details for the file threefive-3.0.57.tar.gz
.
File metadata
- Download URL: threefive-3.0.57.tar.gz
- Upload date:
- Size: 76.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
dc977a9630b641236c538fcd5459f4065651a9b1b7630164f68bccea07a87061
|
|
MD5 |
1e34473957604e43f4ad2e2b6c938602
|
|
BLAKE2b-256 |
09ae96569e2b92196bee2fae9bedc08e4aa484806f03922c97dd6a3d4944870e
|
File details
Details for the file threefive-3.0.57-py3-none-any.whl
.
File metadata
- Download URL: threefive-3.0.57-py3-none-any.whl
- Upload date:
- Size: 78.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 |
48e334b690bbec4742292338014dbd988b60f383a240fd95914dcb9f7f42b09a
|
|
MD5 |
5217b8262d8e6c903eeffd703b02e1e9
|
|
BLAKE2b-256 |
53f22060748d3df47aa4feb69480d24480145295311a9d2c7ce7adc8a62e4f14
|