HLS and SCTE-35 x9k3 is a HLS Segmenter with SCTE 35, and Live Streaming from Non-Live Soures and Looping.
Install | Use | CUE-OUT | CUE-IN | SCTE-35 Tags | Sidecar SCTE35 | Byterange m3u8 | Playlists | Live hls | Bugs | Online SCTE-35 encoder
530 Days
nonstop.13.6 TerraBytes
3.5 MegaBytes
.
0.5%
v.0.2.57
only supported version is the current version
. Keep up.-b
or --byterange
Playlists
can now be used as input.start time
is now always read, never calculated.duration verification
for segments that exceed the target duration
.adbreak
script to generate SCTE-35 Cues.m3u8 files as input
. Resegment and add SCTE-35 to an existing m3u8. -i INPUT
, --input INPUT
continue an m3u8 file.
Segments may be added to an existing m3u8, VOD or live. -c
, --continue_m3u8
discontinuity tags
may now be omitted
. -n
, --no_discontinuity
CUE-IN
throttling
can be disabled
with the -N
, --no_throttle
flagHeads Up
adbreak
$ adbreak -h
usage: adbreak [-h] [-d DURATION] [-p PTS] [-s SIDECAR]
options:
-h, --help show this help message and exit
-d DURATION, --duration DURATION
set duration of ad break. [ default: 60.0 ]
-p PTS, --pts PTS set start pts for ad break. Not setting pts will
generate a Splice Immediate CUE-OUT. [ default: 0.0 ]
-s SIDECAR, --sidecar SIDECAR
Sidecar file of SCTE-35 (pts,cue) pairs. [ default:
sidecar.txt ]
adbreak --pts 1234.567890 --duration 30 --sidecar sidecar.txt
1234.56789,/DAlAAAAAAAAAP/wFAUAAAABf+/+Bp9rxv4AKTLgAAEAAAAAhzvmvQ==
1264.56789,/DAgAAAAAAAAAP/wDwUAAAABf0/+BsiepgABAAAAAPh51T0=
x9k3 -i input.ts -s sidecar.txt
Features
Requires
Install
# python3
python3 -mpip install x9k3
# pypy3
pypy3 -mpip install x9k3
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.
How to Use
cli
a@fu:~/x9k3-repo$ x9k3 -h
usage: x9k3 [-h] [-i INPUT] [-b] [-c] [-d] [-l] [-n] [-N] [-o OUTPUT_DIR] [-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]
-N, --no-throttle disable live throttling [default:False]
-o OUTPUT_DIR, --output_dir OUTPUT_DIR
Directory for segments and index.m3u8(created if
needed) [default:'.']
-p, --program_date_time
Flag to add Program Date Time tags to index.m3u8 (
enables --live) [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
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
x9k3 --live -i /some/video.ts
live sliding window and deleting expired segments
x9k3 -i udp://@235.35.3.5:3535 --delete
https stream for input, and writing segments to an output directory
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
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
Programmatically
Up and Running in three Lines
from x9k3 import X9K3 # 1
x9 = X9K3('/home/a/cool.ts') # 2
x9.decode() # 3
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
>>>> print(x9.args)
Namespace(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)
from x9k3 import X9K3
x9 = X9K3()
input source
x9.args.input = "https://futzu.com/xaa.ts"
hls_tag
can be x_scte35, x_cue, x_daterange, or x_splicepointx9.args.hls tag = x_cue
output directory
default is "."x9.args.output_dir="/home/a/stuff"
live
x9.args.live = True
replay
(loop video) ( also sets live )x9.args.replay = True
delete
segments when they expire ( also sets live )x9.args.delete = True
program date time
tags ( also sets live )x9.args.program_date_time= True
window size
for live mode ( requires live )x9.args.window_size = 5
x9.decode()
byterange
x9k3 -i /home/a/input.ts -b
from x9k3 import X9K3
x9 = X9K3()
x9.self.args.byterange = True
x9.decode()
#EXTM3U
#EXT-X-VERSION:4
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-DISCONTINUITY-SEQUENCE:0
#EXT-X-X9K3-VERSION:0.2.55
#EXTINF:2.000000,
#EXT-X-BYTERANGE:135548@0
msnbc1000.ts
#EXTINF:2.000000,
#EXT-X-BYTERANGE:137992@135548
msnbc1000.ts
#EXTINF:2.000000,
#EXT-X-BYTERANGE:134796@273540
msnbc1000.ts
#EXTINF:2.000000,
#EXT-X-BYTERANGE:140436@408336
msnbc1000.ts
#EXTINF:2.000000,
#EXT-X-BYTERANGE:130096@548772
msnbc1000.ts
<SNIP>
playlists
playlists can be used as input
playlist files must end in .playlist
lines are video or video, sidecar
playlists can have mpegts video, mpegts m3u8, and playlists.
example playlist
f10.ts,f10sidecar.txt # comments can be here
f17.ts
f60.ts
flat-striped.ts
# Comments can go here too.
flat.ts
input.ts
nmax.ts
nmx.ts,nmx-sidecar.txt
https://futzu.com/xaa.ts
https://example.com/index.m3u8,another-sidecar.txt
x9k3 -i out.playlist
Sidecar Files
Sidecar Cues will be handled the same as SCTE35 cues from a video stream.
line format for text file insert_pts, cue
pts is the insert time for the cue, A four second preroll is standard. cue can be base64,hex, int, or bytes
a@debian:~/x9k3$ cat sidecar.txt
38103.868589, /DAxAAAAAAAAAP/wFAUAAABdf+/+zHRtOn4Ae6DOAAAAAAAMAQpDVUVJsZ8xMjEqLYemJQ==
38199.918911, /DAsAAAAAAAAAP/wDwUAAABef0/+zPACTQAAAAAADAEKQ1VFSbGfMTIxIxGolm0=
x9k3 -i noscte35.ts -s sidecar.txt
Sidecar file
touch sidecar.txt
x9k3 -i vid.ts -s sidecar.txt -l
# Open another terminal and printf cues into sidecar.txt
printf '38103.868589, /DAxAAAAAAAAAP/wFAUAAABdf+/+zHRtOn4Ae6DOAAAAAAAMAQpDVUVJsZ8xMjEqLYemJQ==\n' > sidecar.txt
Sidecar files
can now accept 0 as the PTS insert time for Splice Immediate.Specify 0 as the insert time, the cue will be insert at the start of the next segment. Using 0 only works in live mode
printf '0,/DAhAAAAAAAAAP/wEAUAAAAJf78A/gASZvAACQAAAACokv3z\n' > sidecar.txt
sidecar file
.In the middle of a CUE-OUT send a splice insert with the out_of_network_indicator flag not set and the splice immediate flag set. Do the steps above , and then do this
printf '0,/DAcAAAAAAAAAP/wCwUAAAABfx8AAAEAAAAA3r8DiQ==\n' > sidecar.txt
It will cause the CUE-OUT to end at the next segment start.
#EXT-X-CUE-OUT 13.4
./seg5.ts: start:112.966667 end:114.966667 duration:2.233334
#EXT-X-CUE-OUT-CONT 2.233334/13.4
./seg6.ts: start:114.966667 end:116.966667 duration:2.1
#EXT-X-CUE-OUT-CONT 4.333334/13.4
./seg7.ts: start:116.966667 end:118.966667 duration:2.0
#EXT-X-CUE-OUT-CONT 6.333334/13.4
./seg8.ts: start:117.0 end:119.0 duration:0.033333
#EXT-X-CUE-IN None
./seg9.ts: start:119.3 end:121.3 duration:2.3
Using 0 only works in live mode
CUE-OUT
A Splice Insert Command
with:
out_of_network_indicator
set to True
break_duration
.A Time Signal Command
and a Segmentation Descriptor with:
segmentation_duration
segmentation_type_id
of:
CUE-IN
A Splice Insert Command
out_of_network_indicator
set to False
A Time Signal Command
and a Segmentation Descriptor with:
a segmentation_type_id
of:
For CUE-OUT and CUE-IN, only the first Segmentation Descriptor will be used
Supported HLS Tags
x_cue
#EXT-X-DISCONTINUITY
#EXT-X-CUE-OUT:242.0
#EXTINF:4.796145,
seg32.ts
#EXT-X-CUE-OUT-CONT:4.796145/242.0
#EXTINF:2.12,
#EXT-X-DISCONTINUITY
#EXT-X-CUE-IN
#EXTINF:5.020145,
seg145.ts
x_scte35
#EXT-X-DISCONTINUITY
#EXT-X-SCTE35:CUE="/DAvAAAAAAAAAP/wFAUAAAKWf+//4WoauH4BTFYgAAEAAAAKAAhDVUVJAAAAAOv1oqc=" ,CUE-OUT=YES
#EXTINF:4.796145,
seg32.ts
#EXT-X-SCTE35:CUE="/DAvAAAAAAAAAP/wFAUAAAKWf+//4WoauH4BTFYgAAEAAAAKAAhDVUVJAAAAAOv1oqc=" ,CUE-OUT=CONT
#EXTINF:2.12,
seg33.ts
#EXT-X-DISCONTINUITY
#EXT-X-SCTE35:CUE="/DAqAAAAAAAAAP/wDwUAAAKWf0//4rZw2AABAAAACgAIQ1VFSQAAAAAtegE5" ,CUE-IN=YES
#EXTINF:5.020145,
seg145.ts
x_daterange
#EXT-X-DISCONTINUITY
#EXT-X-DATERANGE:ID="1",START-DATE="2022-10-14T17:36:58.321731Z",PLANNED-DURATION=242.0,SCTE35-OUT=0xfc302f00000000000000fff01405000002967fefffe16a1ab87e014c562000010000000a00084355454900000000ebf5a2a7
#EXTINF:4.796145,
seg32.ts
#EXT-X-DISCONTINUITY
#EXT-X-DATERANGE:ID="2",END-DATE="2022-10-14T17:36:58.666073Z",SCTE35-IN=0xfc302a00000000000000fff00f05000002967f4fffe2b670d800010000000a000
843554549000000002d7a0139
#EXTINF:5.020145,
seg145.ts
x_splicepoint
#EXT-X-DISCONTINUITY
#EXT-X-SPLICEPOINT-SCTE35:/DAvAAAAAAAAAP/wFAUAAAKWf+//4WoauH4BTFYgAAEAAAAKAAhDVUVJAAAAAOv1oqc=
#EXTINF:4.796145,
seg32.ts
#EXT-X-DISCONTINUITY
#EXT-X-SPLICEPOINT-SCTE35:/DAqAAAAAAAAAP/wDwUAAAKWf0//4rZw2AABAAAACgAIQ1VFSQAAAAAtegE5
#EXTINF:5.020145,
seg145.ts
VOD
Live
--live
, --delete
, or --replay
switch or by setting X9K3.live=True
--live
-w
switch or by setting X9k3.window.size
--delete
--live
--replay
--live
--delete