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
- threefive installs.
- today: 225
- last seven days: 2,176
- last thirty days: 10,014
- last five years: 1,028,141
- 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.
- 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()
- XML New! updated 05/01/2025
- 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
- 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?
- Decode SCTE-35 without installing anything. If you can make an https request, you can use Sassy to decode SCTE-35. .
- 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.
-
Online SCTE-35 Parser Supporte Base64, Bytes,Hex,Int, Json, Xml, and Xml+binary.
-
Encode SCTE-35 Some encoding code examples.
- 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
- 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>
- 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
- 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 |
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 |
- 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 |
- parse hls manifests and segments for SCTE-35
threefive hls https://example.com/master.m3u8
- Show iframes PTS in an MPEGTS video
threefive iframes https://example.com/video.ts
- Print raw SCTE-35 packets from multicast mpegts video
threefive packets udp://@235.35.3.5:3535
- Parse a https stream and write raw video to stdout
threefive proxy video.ts
- Print PTS from mpegts video
threefive pts video.ts
- Parse a stream, write pts,write SCTE-35 Cues to sidecar.txt
threefive sidecar video.ts
- Fix SCTE-35 data mangled by ffmpeg
threefive sixfix video.ts
- Probe mpegts video ( kind of like ffprobe )
threefive show video.ts
- Show version
threefive version
- Help
threefive help
- 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:~$
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