SkillAgentSearch skills...

X9k3

The Official X9k3 repo: x9k3 is an ABR HLS SCTE-35 Injector and Segmenter. Of course it's powered by threefive.

Install / Use

/learn @superkabuki/X9k3

README

x9k3

x9k3 Injects SCTE-35 Into HLS

x9k3 News

  • <s>I'm trying add support for injesting SRT streams. I have SRT working with threefive.the issue I'm having with x9k3 is disconnecting and reconnecting takes about 5 seconds longer that I want it to, and I'm ironing that out.</s> SRT support for input videos is now working.

  • <s>Expect a new release with SRT support by February.</s> x9k3 v1.0.13 was released 01/31/2026.

  • python 3.14 makes changes to the default multiprocessing spawn method, I fixed that in x9k3 on 01/14/2026.

  • x9k3 runs perfectly on python3, but x9k3 runs best on pypy3. It's all about the JIT man.

    Adrian


</samp>

Current Version: v1.0.21

  • Updated threefive to 3.0.83
  • Fixed adbreak3
  • Auto-Enabbled Program Date Time tags when EXT-X-DATARANGE tags are used.
  • other top secret Jmes Bond type stuff.

Features

  • All SCTE-35 HLS Tags are Supported.
  • Add SCTE-35 Tags to ABR HLS
  • Segment MPEGTS streams into HLS and transfer SCTE-35 or add new SCTE-35 Tags
  • SCTE-35 Cues in Mpegts Streams are Translated into HLS tags.
  • SCTE-35 Cues can be added from a Sidecar File.
  • Segments are Split on SCTE-35 Cues as needed.
  • Segments Start on iframes.
  • Supports h264 and h265 .
  • Multi-protocol. Input sources may be Files, Http(s), Multicast, SRT, or Unicast UDP streams.
  • Supports Live Streaming.

Want to see something cool?

I'm working with a friend of mine on his HLS analyzing web app. This is why he made threefive.js, which is pretty damn good actually. Stay tuned for details! <img width="1187" height="529" alt="image" src="https://github.com/user-attachments/assets/a3987808-b48e-4402-a750-8bf229770d17" />

Documentation

Q.

What`s up with all the releases?

A.

Whenever I figure something out or fix a bug, I make a new release. I'm not going to make you wait for a bug fix. This way, releases are incremental, rather than brand new software. Unless I have a really really good reason not to, I maintain backwards compatibilty and the interface, and by interface I mean function and method calls and such. New releases are designed to work with your existing code.<BR> Sometimes I just make a stupid mistake doing the build and have to do a new one.

Install

  • Use pip to install the x9k3 lib and the executable scripts x9k3, adbreak3, and adinterval3.
# python3

python3 -mpip install x9k3

# pypy3 

pypy3 -mpip install x9k3
  • Both OpenBSD and Debian now require '--break-system-packages' to be appended to the pip install command if you are not using a venv.

⇪ top

Details

  • X-SCTE35, X-CUE, X-DATERANGE, or X-SPLICEPOINT HLS tags can be generated. set with the --hls_tag switch.

  • reading from stdin now available

  • Segments are cut on iframes.

  • Segment time is 2 seconds or more, determined by GOP size. Can be set with the -t switch or by setting X9K3.args.time

  • Segments are named seg1.ts seg2.ts etc...

  • For SCTE-35, Video segments are cut at the the first iframe >= the splice point pts.

  • If no pts time is present in the SCTE-35 cue, the segment is cut at the next iframe.

  • SCTE-35 cues with a preroll are inserted at the splice point.

  • x9k3 can continue an existing m3u8 file. You can switch or resume streams, x9k3 handles the details.

How to Use

cli

do the simplest thing that can possibly work

  • There are a lot of command line switches available, but you do not have to use them all. <BR>

Try it like this first

x9k3 -i video.ts -o output_dir

later you can add as many switches as you like.

Switches

a@fu:~/x9k3$ x9k3 --help

usage: x9k3 [-h] [-i INPUT] [-b] [-c] [-d] [-l] [-n]
            [-no_adrian_is_cool_tags_at_splice_points_because_I_suck] [-N]
            [-o OUTPUT_DIR] [-e] [-p] [-r] [-s SIDECAR_FILE] [-S] [-t TIME]
            [-T HLS_TAG] [-w WINDOW_SIZE] [-v]

optional arguments:

  -h, --help            show this help message and exit

  -i INPUT, --input INPUT
                        The Input video can be mpegts or m3u8 with mpegts
                        segments, or a playlist with mpegts files and/or
                        mpegts m3u8 files. The input can be a local video,
                        http(s), udp, multicast or stdin.

  -b, --byterange       Flag for byterange hls [default:False]

  -c, --continue_m3u8   Resume writing index.m3u8 [default:False]

  -d, --delete          delete segments (enables --live) [default:False]

  -l, --live            Flag for a live event (enables sliding window m3u8)
                        [default:False]

  -n, --no_discontinuity                 
                        Flag to disable adding #EXT-X-DISCONTINUITY tags at
                        splice points [default:False]

  -no_adrian_is_cool_tags_at_splice_points_because_I_suck
                        Flag to disable adding #EXT-X-ADRIAN-IS-COOL tags at
                        splice points [default:False]

  -N, --no-throttle,             
                        Flag to disable live throttling [default:False]

  -o OUTPUT_DIR, --output_dir OUTPUT_DIR
                        Directory for segments and index.m3u8(created if
                        needed) [default:'.']

  -e, --exclude_mpegts  Flag to exclude parsing SCTE-35 from MPEGTS.
                        [default:False]

  -p, --program_date_time
                        Flag to add Program Date Time tags to index.m3u8  [default:False]

  -r, --replay          Flag for replay aka looping (enables --live,--delete)
                        [default:False]

  -s SIDECAR_FILE, --sidecar_file SIDECAR_FILE
                        Sidecar file of SCTE-35 (pts,cue) pairs.
                        [default:None]

  -S, --shulga          Flag to enable Shulga iframe detection mode
                        [default:False]

  -t TIME, --time TIME  Segment time in seconds [default:2]

  -T HLS_TAG, --hls_tag HLS_TAG
                        x_scte35, x_cue, x_daterange, or x_splicepoint
                        [default:x_cue]

  -w WINDOW_SIZE, --window_size WINDOW_SIZE
                        sliding window size (enables --live) [default:5]

  -v, --version         Show version

Example Usage

local file as input

   x9k3 -i video.mpegts

multicast stream as input with a live sliding window

x9k3 --live -i udp://@235.35.3.5:3535 -o output_dir

Live mode works with a live source or static files.

  • x9k3 will throttle segment creation to mimic a live stream.
x9k3 --live -i /some/video.ts -o output_dir

live sliding window and deleting expired segments

x9k3  -i udp://@235.35.3.5:3535 --delete -o output_dir

https stream for input, and writing segments to an output directory

  • directory will be created if it does not exist.
  x9k3 -i https://so.slo.me/longb.ts --output_dir /home/a/variant0

https hls m3u8 for input, and inserting SCTE-35 from a sidecar file, and continuing from a previously create index.m3u8 in the output dir

  x9k3 -i https://slow.golf/longb.m3u8 --output_dir /home/a/variant0 -continue_m3u8 -s sidecar.txt

using stdin as input

cat video.ts | x9k3   -o output_dir

live m3u8 file as input, add SCTE-35 from a sidecar file, change segment duration to 3 and output as live stream

x9k3 -i https://example.com/rendition.m3u8 -s sidecar.txt -t 3 -l -o output-dir

⇪ top

Programmatically

Up and Running in three Lines

        from x9k3 import X9K3            # 1
        x9 = X9K3('/home/a/cool.ts')     # 2
        x9.decode()                      # 3

Writing Code with x9k3

  • you can get a complete set of args and the defaults like this
from x9k3 import X9K3
x9 = X9K3()

>>>> {print(k,':',v) for k,v in vars(x9.args).items()}

input : <_io.BufferedReader name='<stdin>'>
continue_m3u8 : False
delete : False
live : False
no_discontinuity : False
no_throttle : False
output_dir : .
program_date_time : False
replay : False
sidecar_file : None
shulga : False
time : 2
hls_tag : x_cue
window_size : 5
version : False
  • or just
View on GitHub
GitHub Stars9
CategoryDevelopment
Updated3d ago
Forks2

Languages

Python

Security Score

90/100

Audited on Mar 30, 2026

No findings