Home
Softono
threefive_is_scte35

threefive_is_scte35

Open source Python
20
Stars
4
Forks
1
Issues
1
Watchers
1 week
Last Commit

About threefive_is_scte35

threefive is the highest rated SCTE-35 parser/encoder. Ever.

Platforms

Web Self-hosted

Languages

Python

threefive is the highest rated SCTE-35 tool. Ever.

  • Decodes SCTE-35 from MPEGTSBase64BytesDASHHexHLSIntegersJSONXMLXML+Binary
  • Encodes SCTE-35 to MPEGTSBase64BytesHexIntegersJSONXMLXML+Binary

[ News ]

  • threefive now has support for SCTE-35-2. Event Descriptors and Property types from the recently published 2026 SCTE-35-2 Specification.
  • threefive v3.0.93 will support HLS autodetection in the cli.

[ Latest threefive version is v3.0.91 ]


[ Examples ]


[ Tip of the Week ]


[ Documentation ]

Need to inject SCTE-35 into HLS? X9k3.

[Install]

  • python3 via pip

    python3 -mpip install threefive
  • pypy3 via pip

    pypy3 -mpip install threefive
  • To add SRT support

    python3 -m pip install srtfu
  • To add Automatic AES decryption

    python3 -mpip install pyaes
  • From the git repo

git clone https://github.com/superkabuki/scte35.git
cd threefive
make install
  • I've jazzed up the makefile to make it easier to install for different python versions and pypy3
    
    git clone https://github.com/superkabuki/scte35.git
    cd threefive

make install py3=pypy3

OR

make install py3=python3.14

works for any python in your path or use a full path if needed.

# [⇧](#-documentation-)
___

### [CLI]
The threefive cli tool is able to parse SCTE-35 from MPEGTS Streams,Base64,Hex,Integers,JSON XML,and XMLBinary.
The format is auto-detected.

# [⇧](#-documentation-)

#### [ Parse SCTE-35 from HLS with threefive ]
```js
threefive https://example.com/master.m3u8

[ Parse SCTE-35 from MPEGTS ]

SCTE-35 can be parsed from MPEGTS over a variety of protocols.

  • SCTE-35 Input: MPEGTS
  • Protocols: pipes, files, stdin, http(s), multicast,SRT and UDP.
  • SCTE-35 Output: JSON (default) base64, bytes, hex, int, xml, and xmlbin.
SCTE-35 Input Protocol SCTE-35 Output Command
MPEGTS file JSON threefive video.ts
. https base64 threefive https://example.com/video.ts base64
. multicast bytes threefive udp://@235.3.5:3535 bytes
. SRT hex threefive srt://1.2.3.4:4201 hex
. UDP int threefive udp://10.10.10.10:1011 int
. Pipe xml cat video.ts | threefive xml
. stdin xml+bin threefive xmlbin < video.ts

[ Parse SCTE-35 Cues ]

  • The default output is JSON
  • SCTE-35 Inputs: base64, hex, int, JSON,int,xml,and xmlbin.
  • SCTE-35 Outputs: base64, bytes, hex, int,JSON, xml, and xmlbin.
  • Any Input can be used with Any Output

Here are several examples.

SCTE-35 Input SCTE-35 Output Command
base64 JSON threefive '/DAWAAAAAAAAAP/wBQb+AKmKxwAACzuu2Q=='
. bytes threefive '/DAWAAAAAAAAAP/wBQb+AKmKxwAACzuu2Q==' bytes
. hex threefive '/DAWAAAAAAAAAP/wBQb+AKmKxwAACzuu2Q==' hex
. xml threefive '/DAWAAAAAAAAAP/wBQb+AKmKxwAACzuu2Q==' xml
hex JSON threefive 0xfc301600000000000000fff00506fe00a98ac700000b3baed9
. base64 threefive 0xfc301600000000000000fff00506fe00a98ac700000b3baed9 base64
. int threefive 0xfc301600000000000000fff00506fe00a98ac700000b3baed9 int
. xmlbin threefive 0xfc301600000000000000fff00506fe00a98ac700000b3baed9 xmlbin
int JSON threefive 1583008701074197245727019716796221242036302348025116111908569
. hex threefive 1583008701074197245727019716796221242036302348025116111908569 hex
. xml threefive 1583008701074197245727019716796221242036302348025116111908569 xml
JSON base64 threefive < json.json base64
. bytes threefive < json.json bytes
. xml threefive < json.json xml
xml JSON threefive < xml.xml
xmlbin int threefive < xmlbin.xml int

[Additional functionality]

  • threefive has several additional features, mostly related to MPEGTS streams.
  • threefive has built in help, just type threefive help
  • This table shows how to use them.
Description How To Use
Inject SCTE35 packets threefive inject -i in.video -s sidecar.txt -o out.ts
Show raw SCTE35 packets threefive packets udp://@235.35.3.5:3535
Copy MPEGTS stream to stdout at realtime speed threefive rt input.ts
Create SCTE35 sidecar file threefive sidecar video.ts
Show streams in mpegts stream threefive show https://example.com/video.ts
Show iframes in mpegts stream threefive iframes srt://10.10.1.3:9000
Show PTS values from mpegts stream threefive pts udp://192.168.1.10:9000
Proxy the mpegts stream to stdout threefive proxy https://wexample.com/video.ts

Other tools

threefive also comes with:

scte35bump

  • bump adjusts SCTE-35 PTS in an MPEGTS stream
$ scte35bump -h
usage: scte35bump [-h] [-i INFILE] [-o OUTFILE] [-s SECS]

options:
  -h, --help            show this help message and exit
  -i INFILE, --infile INFILE
                        Input source, stdin, file, http(s), udp, or multicast
                        mpegts [default: sys.stdin.buffer]
  -o OUTFILE, --outfile OUTFILE
                        Output file [default: sys.stdout.buffer]
  -s SECS, --secs SECS  Adjustment to apply to SCTE-35 Cues. [default: 0.0]

scte35bump is part of threefive.

gums

  • the Grande Udp Multicast Server
$ gums -h
usage: gums [-h] [-i INPUT] [-a ADDR] [-b BIND_ADDR] [-t TTL]

options:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
                        like "/home/a/vid.ts" 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]

gums is part of threefive.

HLS

  • parse HLS for SCTE-35. Supports all HLS SCTE-35 tags.
$ threefive hls help

[ Input ] threefive hls takes an m3u8 URI as input. M3U8 formats supported:

  • master ( When a master.m3u8 used, threefive hls parses the first rendition it finds )
  • rendition Segment types supported:
  • AAC
  • AC3
  • MPEGTS *codecs:
    • video
      • mpeg2, h.264, h.265
    • audio
      • mpeg2, aac, ac3, mp3

scte35fix

  • when ffmpeg changes a SCTE-35 stream to bin data stream, scte35fix changes it back.
$ scte35fix -h

  scte35fix checks MPEGTS for SCTE-35 Streams
  that have been change to bin data (type 0x06)
  and changes them back to SCTE-35 (type 0x86) streams.
  Output files are created in the current directory
  and prefixed with 'sixfix-'.
  Only bin data streams containing SCTE-35 will be converted.
  Multiple files can be specified on the command line.
  Wild cards work too.

  Example Usage:
        scte35fix video.ts
        scte35fix video1.ts video2.ts
        scte35fix video*.ts
        scte35fix https://example.com/video.ts
        scte35fix srt://10.10.10.13:4201
scte35fix is part of threefive.

[Using the library]

  • Let me show you how easy threefive is to use.

  • 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

    >>>> 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
          },
    
      ]
    }
  • 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())

``` ___

[web]

[XML]

  • XML New! updated 05/01/2025

[HLS]

[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)

[threefive now supports SRT]

  • ( You have to unmute the audio )

https://github.com/user-attachments/assets/a323ea90-867f-480f-a55f-e9339263e511



[more]