{"id":28627997,"url":"https://github.com/superkabuki/x9k3","last_synced_at":"2026-02-11T05:32:32.279Z","repository":{"id":298347353,"uuid":"999680244","full_name":"superkabuki/x9k3","owner":"superkabuki","description":"The Official X9k3 repo: x9k3 is an ABR HLS SCTE-35 Injector and Segmenter. Of course it's powered by threefive. ","archived":false,"fork":false,"pushed_at":"2026-01-23T20:20:16.000Z","size":282,"stargazers_count":6,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-31T00:43:20.570Z","etag":null,"topics":["adrianofdoom","ads","boobs","gurkhan","hls","lefthandofgod","mpegts","python3","scte","scte-35","scte-35-hls","scte104","scte35","sidecar","splice","spliceinfosection","threefive","x9k3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/superkabuki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-10T16:10:04.000Z","updated_at":"2026-01-23T20:20:37.000Z","dependencies_parsed_at":"2025-06-10T17:44:29.731Z","dependency_job_id":"dbb04516-315b-4f1d-87aa-0bcc6d1309a3","html_url":"https://github.com/superkabuki/x9k3","commit_stats":null,"previous_names":["superkabuki/x9k3","superkabuki/scte35_x9k3","superkabuki/x9k3-kabuki"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/superkabuki/x9k3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superkabuki%2Fx9k3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superkabuki%2Fx9k3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superkabuki%2Fx9k3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superkabuki%2Fx9k3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/superkabuki","download_url":"https://codeload.github.com/superkabuki/x9k3/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/superkabuki%2Fx9k3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29327326,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T03:52:29.695Z","status":"ssl_error","status_checked_at":"2026-02-11T03:52:23.094Z","response_time":97,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adrianofdoom","ads","boobs","gurkhan","hls","lefthandofgod","mpegts","python3","scte","scte-35","scte-35-hls","scte104","scte35","sidecar","splice","spliceinfosection","threefive","x9k3"],"created_at":"2025-06-12T10:10:44.917Z","updated_at":"2026-02-11T05:32:32.273Z","avatar_url":"https://github.com/superkabuki.png","language":"Python","funding_links":[],"categories":["SCTE-35 \u0026 SCTE-104"],"sub_categories":[],"readme":"\n# x9k3 \n# x9k3 Injects SCTE-35 Into HLS \n\n # x9k3 News\n* \u003cs\u003eI'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,\nand I'm ironing that out.\u003c/s\u003e __SRT support__ for input videos is now working.\n* \u003cs\u003eExpect a __new release__ with SRT support __by February__.\u003c/s\u003e __x9k3 v1.0.13 was released 01/31/2026.__\n* __python 3.14__ makes changes to the default __multiprocessing spawn__ method, I __fixed__ that __in x9k3__ on __01/14/2026.__\n* __x9k3 runs perfectly on python3__, but __x9k3 runs best on pypy3__.  It's all about the __JIT__ man. \n\n  _Adrian_\n\n---\n\u003c/samp\u003e\n\n\n\n# Current Version:  `v1.0.13`  _(01/31/2026)_ \n# `Features`\n\n   * __All SCTE-35 HLS Tags__ are Supported.\n   * __Add SCTE-35 Tags to ABR HLS__\n   * __Segment MPEGTS streams into HLS and transfer SCTE-35 or add new SCTE-35 Tags__\n   * __SCTE-35 Cues__ in __Mpegts Streams__ are Translated into __HLS tags__.\n   * __SCTE-35 Cues can be added from a [Sidecar File](#sidecar-files)__.\n   * Segments are __Split on SCTE-35 Cues__ as needed.\n   * Segments __Start on iframes__.\n   * Supports __h264__ and __h265__ .\n   * __Multi-protocol.__ Input sources may be __Files, Http(s), Multicast, SRT, or Unicast UDP streams__.\n   * Supports [__Live__](https://github.com/futzu/scte35-hls-x9k3#live) __Streaming__.\n\n---\n\n# Documentation\n\n### Q. \n__What`s up with all the releases?__\n\n### A.\n __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.\u003cBR\u003e __Sometimes I just make a stupid mistake doing the build and have to do a new one__.\n\n* [Install](#install)\n* Use \n    * [__Cli__](#cli)\n      * [Switches](#switches) _( --this and --that)_\n      * [__Usage__ Examples](#example-usage)  \n    * [__Lib__](#programmatically) _(how to use x9k3 as a library)_\n      * [ABR in Code](#abr-in-code)  \n    * [__Sidecar Files__](#sidecar-files) _(these are how you add the SCTE-35, super important)_\n      * [Adding SCTE-35 in real time](#in-live-mode-you-can-do-dynamic-cue-injection-with-a-sidecar-file)\n      * [SCTE-35 Splice Immediate ](#sidecar-files-can-now-accept-0-as-the-pts-insert-time-for-splice-immediate) (_not the same as real time_)\n      * __SCTE-35 Generation__ with [adbreak3](#adbreak3)\n    * [__Playlists__](#playlists) _(make a playlist of MPEGTS or M3u8 files and feed it to x9k3 as input)_\n* HLS Stuff\n    * [__HLS as Input__](#hls-as-input) \n    * [__ABR HLS__](#abr-hls) _(there are some terms and conditions)_\n       * [__ABR__ in Code](#abr-in-code) _(in less than ten lines)_\n    * [__Byterange__ HLS](#byterange) \n    * [__Live__ HLS](#live) _(sliding windows, deleting segments, all that jazz)_\n    * [__Looping__ videos](#--replay) _(play the same thing over and over)_\n* [__Cues__](#cues)\n    * [CUE-OUT](#cue-out) \n    * [CUE-IN](#cue-in)\n* [SCTE-35 __Tags__](#supported-hls--tags)\n    * [__#EXT-X-CUE__](#x_cue)\n    * [__#EXT-X-SCTE35__](#x_scte35)\n    * [__#EXT-X-DATERANGE__](#x_daterange)\n    * [__#EXT-X-SPLICEPOINT__](#x_splicepoint)\n\n\n\n\n# `Install`\n* Use __pip__ to __install__ the __x9k3 lib__ and the executable scripts __x9k3__, __adbreak3__, and __adinterval3__.\n```lua\n# python3\n\npython3 -mpip install x9k3\n\n# pypy3 \n\npypy3 -mpip install x9k3\n```\n\n* _Both OpenBSD and Debian now require '--break-system-packages' to be appended to the pip install command if you are not using a venv._\n\n[⇪ top](#documentation)\n\n# `Details` \n\n*  __X-SCTE35__, __X-CUE__, __X-DATERANGE__, or __X-SPLICEPOINT__ HLS tags can be generated. set with the `--hls_tag` switch.\n\n* reading from stdin now available\n* Segments are cut on iframes.\n* Segment time is 2 seconds or more, determined by GOP size. Can be set with the `-t` switch or by setting `X9K3.args.time` \n* Segments are named seg1.ts seg2.ts etc...\n*  For SCTE-35, Video segments are cut at the the first iframe \u003e=  the splice point pts.\n*  If no pts time is present in the SCTE-35 cue, the segment is cut at the next iframe. \n* SCTE-35 cues with a preroll are inserted at the splice point.\n* x9k3 can continue an existing m3u8 file. You can switch or resume streams, x9k3 handles the details.\n\n# `How to Use`\n\n\n\n# `cli` \n\n### `do the simplest thing that can possibly work`\n\n* There are __a lot of command line switches__ available, but __you do not have to use them all.__ \u003cBR\u003e\n\nTry it like this first \n\n```js\nx9k3 -i video.ts -o output_dir\n```\n\nlater you can add as many switches as you like. \n\n\n### Switches\n```smalltalk\na@fu:~/x9k3$ x9k3 --help\n\nusage: x9k3 [-h] [-i INPUT] [-b] [-c] [-d] [-l] [-n]\n            [-no_adrian_is_cool_tags_at_splice_points_because_I_suck] [-N]\n            [-o OUTPUT_DIR] [-e] [-p] [-r] [-s SIDECAR_FILE] [-S] [-t TIME]\n            [-T HLS_TAG] [-w WINDOW_SIZE] [-v]\n\noptional arguments:\n\n  -h, --help            show this help message and exit\n\n  -i INPUT, --input INPUT\n                        The Input video can be mpegts or m3u8 with mpegts\n                        segments, or a playlist with mpegts files and/or\n                        mpegts m3u8 files. The input can be a local video,\n                        http(s), udp, multicast or stdin.\n\n  -b, --byterange       Flag for byterange hls [default:False]\n\n  -c, --continue_m3u8   Resume writing index.m3u8 [default:False]\n\n  -d, --delete          delete segments (enables --live) [default:False]\n\n  -l, --live            Flag for a live event (enables sliding window m3u8)\n                        [default:False]\n\n  -n, --no_discontinuity                 \n                        Flag to disable adding #EXT-X-DISCONTINUITY tags at\n                        splice points [default:False]\n\n  -no_adrian_is_cool_tags_at_splice_points_because_I_suck\n                        Flag to disable adding #EXT-X-ADRIAN-IS-COOL tags at\n                        splice points [default:False]\n\n  -N, --no-throttle,             \n                        Flag to disable live throttling [default:False]\n\n  -o OUTPUT_DIR, --output_dir OUTPUT_DIR\n                        Directory for segments and index.m3u8(created if\n                        needed) [default:'.']\n\n  -e, --exclude_mpegts  Flag to exclude parsing SCTE-35 from MPEGTS.\n                        [default:False]\n\n  -p, --program_date_time\n                        Flag to add Program Date Time tags to index.m3u8  [default:False]\n\n  -r, --replay          Flag for replay aka looping (enables --live,--delete)\n                        [default:False]\n\n  -s SIDECAR_FILE, --sidecar_file SIDECAR_FILE\n                        Sidecar file of SCTE-35 (pts,cue) pairs.\n                        [default:None]\n\n  -S, --shulga          Flag to enable Shulga iframe detection mode\n                        [default:False]\n\n  -t TIME, --time TIME  Segment time in seconds [default:2]\n\n  -T HLS_TAG, --hls_tag HLS_TAG\n                        x_scte35, x_cue, x_daterange, or x_splicepoint\n                        [default:x_cue]\n\n  -w WINDOW_SIZE, --window_size WINDOW_SIZE\n                        sliding window size (enables --live) [default:5]\n\n  -v, --version         Show version\n\n```\n\n### `Example Usage`\n\n #### `local file as input`\n ```smalltalk\n    x9k3 -i video.mpegts\n ```\n #### `multicast stream as input with a live sliding window`   \n   ```smalltalk\n   x9k3 --live -i udp://@235.35.3.5:3535 -o output_dir\n   ```\n  #### Live mode works with a live source or static files.\n  *  x9k3 will throttle segment creation to mimic a live stream.\n   ```js\n   x9k3 --live -i /some/video.ts -o output_dir\n   ```\n #### `live sliding window and deleting expired segments`\n   ```smalltalk\n   x9k3  -i udp://@235.35.3.5:3535 --delete -o output_dir\n   ```\n#### `https stream for input, and writing segments to an output directory`\n   *  directory will be created if it does not exist.\n ```smalltalk\n   x9k3 -i https://so.slo.me/longb.ts --output_dir /home/a/variant0\n ```\n#### `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`\n ```smalltalk\n   x9k3 -i https://slow.golf/longb.m3u8 --output_dir /home/a/variant0 -continue_m3u8 -s sidecar.txt\n ```  \n#### `using stdin as input`\n   ```smalltalk\n   cat video.ts | x9k3   -o output_dir\n   ```\n#### `live m3u8 file as input, add SCTE-35 from a sidecar file, change segment duration to 3 and output as live stream`\n```smalltalk\nx9k3 -i https://example.com/rendition.m3u8 -s sidecar.txt -t 3 -l -o output-dir\n```\n[⇪ top](#documentation)\n\n\n\n# `Programmatically`\n\n## `Up and Running in three Lines`\n\n```smalltalk\n        from x9k3 import X9K3            # 1\n        x9 = X9K3('/home/a/cool.ts')     # 2\n        x9.decode()                      # 3\n```\n\n\n\n#### Writing Code with x9k3\n\n* you can get a complete set of args and the defaults like this\n\n```js\nfrom x9k3 import X9K3\nx9 = X9K3()\n\n\u003e\u003e\u003e\u003e {print(k,':',v) for k,v in vars(x9.args).items()}\n\ninput : \u003c_io.BufferedReader name='\u003cstdin\u003e'\u003e\ncontinue_m3u8 : False\ndelete : False\nlive : False\nno_discontinuity : False\nno_throttle : False\noutput_dir : .\nprogram_date_time : False\nreplay : False\nsidecar_file : None\nshulga : False\ntime : 2\nhls_tag : x_cue\nwindow_size : 5\nversion : False\n```\n*   or just\n```lua\n\u003e\u003e\u003e\u003e print(x9.args)\n\nNamespace(input=\u003c_io.BufferedReader name='\u003cstdin\u003e'\u003e, 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)\n```\n\n\n* Setting  parameters\n\n```js\nfrom x9k3 import X9K3\nx9 = X9K3()\n```\n*  `input source`\n\n```smalltalk\nx9.args.input = \"https://futzu.com/xaa.ts\"   \n```\n* `hls_tag` can be x_scte35, x_cue, x_daterange, or x_splicepoint\n\n```smalltalk\nx9.args.hls tag = x_cue \n```\n* `output directory` default is \".\"\n```js\nx9.args.output_dir=\"/home/a/stuff\"\n```\n* `live`\n```smalltalk \nx9.args.live = True\n```\n* `replay` (loop video) ( also sets live )\n```js\nx9.args.replay = True\n```\n* `delete` segments when they expire ( also sets live )\n```js\nx9.args.delete = True\n```\n\n* add `program date time` tags ( also sets live )\n```js\nx9.args.program_date_time= True\n```\n* set `window size` for live mode ( requires live ) \n```js\nx9.args.window_size = 5 \n```\n* run \n```js\nx9.decode()\n```\n\n[⇪ top](#documentation)\n\n### `HLS as input`\n* x9k3 can use HLS manifests as input.\n* HLS Must be MPEGTS with audio and video together in the segment.\n* No audio only or separate audio.\n* Existing HLS SCTE-35 Tags in input manifests will be dropped.\n* [ABR HLS](#abr-hls) has additional restrictions\n\n ### `Byterange`\n * with the cli tool\n    * use __full path to video file__  when creating byterange m3u8. \n```smalltalk\nx9k3 -i /home/a/input.ts -b\n```\n* programmatically\n```smalltalk\nfrom x9k3 import X9K3\nx9 = X9K3()\nx9.self.args.byterange = True\nx9.decode()\n```\n* output\n```lua\n#EXTM3U\n#EXT-X-VERSION:4\n#EXT-X-TARGETDURATION:3\n#EXT-X-MEDIA-SEQUENCE:0\n#EXT-X-DISCONTINUITY-SEQUENCE:0\n#EXT-X-X9K3-VERSION:0.2.55\n#EXTINF:2.000000,\n#EXT-X-BYTERANGE:135548@0\nmsnbc1000.ts\n#EXTINF:2.000000,\n#EXT-X-BYTERANGE:137992@135548\nmsnbc1000.ts\n#EXTINF:2.000000,\n#EXT-X-BYTERANGE:134796@273540\nmsnbc1000.ts\n#EXTINF:2.000000,\n#EXT-X-BYTERANGE:140436@408336\nmsnbc1000.ts\n#EXTINF:2.000000,\n#EXT-X-BYTERANGE:130096@548772\nmsnbc1000.ts\n\u003cSNIP\u003e\n```\n[⇪ top](#documentation)\n\n### `ABR HLS` \n\n__Here's how it works__. \n\u003csamp\u003e\n* When x9k3 detects a master.m3u8 as input, it starts up an ABR instance.\n* The ABR instance parses the master.m3u8 and finds rendtitions.\n* For each rendition an x9k3 process is started.\n* The ABR process also parses the SCTE-35 sidecar file and writes a sidecar file for each rendition.\n* The master.m3u8 is written to the output_dir.\n* Rendition segments and manifest files are written to output_dir/0, output_dir/1, etc.\n* any args passed in are set for all rendtions.\n\u003c/samp\u003e\n\u003cimg width=\"829\" height=\"384\" alt=\"image\" src=\"https://github.com/user-attachments/assets/5a2e885f-44e0-42a6-a3d3-b524b4cb0758\" /\u003e\n\n __The terms and condtions__.\n\n* HLS version 3 support only\n* Use a Sidecar file for SCTE-35 \n* Only MPEGTS segments\n* Audio and Video MUST be in the same stream.\n* No separate Audio tracks\n* No Audio only\n* No WebVTT\n* Pass a local master.m3u8 as input for x9k3\n```sh\nx9k3 -i ~/o21/master.m3u8 -t 3 -l -s sidecar.txt\n```\n\n* ABR works well over a network, if you have the bandwidth to download all renditions simultaneously.\n     * If you don't have the bandwidth, the renditions will get out of sync.\n     * The throttle time is a good indicator. throttle must be greater than half of target duration for all renditions.\n     * throttle time is shown in the x9k3 output\n\n```rebol\n./0/seg0.ts:   start: 0.160   end: 10.000   duration: 9.840  # \u003c-- duration   \nthrottling 8.22                        # \u003c--- throttle time        throttle time \u003e (duration / 2) GOOD\n\n\n./2/seg0.ts:   start: 0.160   end: 10.000   duration: 9.840  # \u003c-- duration  \nthrottling 4.23                       # \u003c--- throttle time          throttle time \u003c (duration / 2)  BAD\n\n```\n\n### `ABR in Code`\n```py3\nPython 3.9.16 (7.3.11+dfsg-2+deb12u3, Dec 30 2024, 22:36:23)\n[PyPy 7.3.11 with GCC 12.2.0] on linux\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\u003e\u003e\u003e\u003e from x9k3 import argue\n\u003e\u003e\u003e\u003e from x9k3.x9mp import do\n\u003e\u003e\u003e\u003e url = 'https://demo.unified-streaming.com/k8s/live/scte35.isml/.m3u8'\n\u003e\u003e\u003e\u003e args = argue()\n\u003e\u003e\u003e\u003e args.input=url\n\u003e\u003e\u003e\u003e do(args)\n\n```\n* imports\n```py3\nfrom x9k3 import argue\nfrom x9k3.x9mp import do\n```\n* define source\n```py3\n url = 'https://demo.unified-streaming.com/k8s/live/scte35.isml/.m3u8'\n\n```\n* generate  the args.\n* [more about args](#writing-code-with-x9k3)\n```py3\n\nargs = argue()\n```\n* args is the Namespace returned by the standard library's argparser.\n* These are same options as the cli x9k3.\n```py3\nargs\nNamespace(input=\u003c_io.BufferedReader name='\u003cstdin\u003e'\u003e, byterange=False, continue_m3u8=False,\n  delete=False, live=False, no_discontinuity=False, no_adrian_is_cool_tags_at_splice_points_because_I_suck=False,\n  no_throttle=False, output_dir='.', exclude_mpegts=False,program_date_time=False, replay=False, sidecar_file=None,\n  shulga=False, time=2, hls_tag='x_cue', window_size=5, version=False)\n```\n* use dot notation to set what you need\n ```py3\n args.input=url\n```\n* call do(args)\n```py3\nfrom x9k3.x9mp import do\n\n```\n\n* That's it.\n   \n[⇪ top](#documentation)\n\n\n### `Playlists`\n* playlists can be used as input\n* playlist files must end in `.playlist`\n* lines are  video or  video, sidecar\n   * if video,sidecar, the sidecar file only applies to that video\n* playlists can have mpegts video, mpegts m3u8, and playlists.\n \n* example playlist\n```lua\nf10.ts,f10sidecar.txt # comments can be here\nf17.ts\nf60.ts\nflat-striped.ts\n# Comments can go here too.\nflat.ts\ninput.ts\nnmax.ts\nnmx.ts,nmx-sidecar.txt\nhttps://futzu.com/xaa.ts\nhttps://example.com/index.m3u8,another-sidecar.txt\n```\n* using\n```lua\n x9k3 -i out.playlist\n```\n[⇪ top](#documentation)\n\n\n### `Sidecar Files`   \n#### load scte35 cues from a Sidecar file\n\n    \nSidecar Cues will be handled the same as SCTE35 cues from a video stream.   \nline format for text file  `insert_pts, cue`\n    \n    \npts is the insert time for the cue, A four second preroll is standard. \ncue can be base64,hex, int, or bytes\n     \n  ```smalltalk\n  a@debian:~/x9k3$ cat sidecar.txt\n  \n  38103.868589, /DAxAAAAAAAAAP/wFAUAAABdf+/+zHRtOn4Ae6DOAAAAAAAMAQpDVUVJsZ8xMjEqLYemJQ== \n  38199.918911, /DAsAAAAAAAAAP/wDwUAAABef0/+zPACTQAAAAAADAEKQ1VFSbGfMTIxIxGolm0= \n\n      \n```\n  ```smalltalk\n  x9k3 -i  noscte35.ts  -s sidecar.txt \n  ```\n#### [adbreak3](#adbreak3) writes to sidecar files for you.\n\n##   In Live Mode you can do dynamic cue injection with a `Sidecar file`\n   ```js\n   touch sidecar.txt\n   \n   x9k3 -i vid.ts -s sidecar.txt -l \n   \n   # Open another terminal and printf cues into sidecar.txt\n   \n   printf '38103.868589, /DAxAAAAAAAAAP/wFAUAAABdf+/+zHRtOn4Ae6DOAAAAAAAMAQpDVUVJsZ8xMjEqLYemJQ==\\n' \u003e sidecar.txt\n   \n   ```\n#### [adbreak3](#adbreak3) also does dynamic injection.\n\n## `Sidecar files` can now accept 0 as the PTS insert time for Splice Immediate. \n \n \n\n Specify 0 as the insert time,  the cue will be insert at the start of the next segment.\n __Using 0 only works in live mode__\n\n ```js\n printf '0,/DAhAAAAAAAAAP/wEAUAAAAJf78A/gASZvAACQAAAACokv3z\\n' \u003e sidecar.txt\n\n ```\n [⇪ top](https://github.com/futzu/x9k3/blob/main/README.md#hls--scte35--x9k3)\n\n ##  A CUE-OUT can be terminated early using a `sidecar file`.\n\n \n 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.\n Do the steps above ,\n and then do this\n ```js\n printf '0,/DAcAAAAAAAAAP/wCwUAAAABfx8AAAEAAAAA3r8DiQ==\\n' \u003e sidecar.txt\n```\n It will cause the CUE-OUT to end at the next segment start.\n ```js\n#EXT-X-CUE-OUT 13.4\n./seg5.ts:\tstart:112.966667\tend:114.966667\tduration:2.233334\n#EXT-X-CUE-OUT-CONT 2.233334/13.4\n./seg6.ts:\tstart:114.966667\tend:116.966667\tduration:2.1\n#EXT-X-CUE-OUT-CONT 4.333334/13.4\n./seg7.ts:\tstart:116.966667\tend:118.966667\tduration:2.0\n#EXT-X-CUE-OUT-CONT 6.333334/13.4\n./seg8.ts:\tstart:117.0\t        end:119.0\tduration:0.033333\n#EXT-X-CUE-IN None\n./seg9.ts:\tstart:119.3\t        end:121.3\tduration:2.3\n\n``` \n __Using 0 only works in live mode__\n[⇪ top](#documentation)\n\n   ---\n## `Cues`   \n   \n##   `CUE-OUT`\n#### A CUE-OUT is defined as:\n\n* `A Splice Insert Command` with:\n   *  the `out_of_network_indicator` set to `True` \n   *  a `break_duration`.\n        \n* `A Time Signal Command` and a Segmentation Descriptor with:\n   *  a `segmentation_duration` \n   *  a `segmentation_type_id` of:\n      * 0x22: \"Break Start\",\n      * 0x30: \"Provider Advertisement Start\",\n      * 0x32: \"Distributor Advertisement Start\",\n      * 0x34: \"Provider Placement Opportunity Start\",\n      * 0x36: \"Distributor Placement Opportunity Start\",\n      * 0x44: \"Provider Ad Block Start\",\n      * 0x46: \"Distributor Ad Block Start\",\n\n[⇪ top](https://github.com/futzu/x9k3/blob/main/README.md#hls--scte35--x9k3)\n\n## `CUE-IN`\n#### A CUE-IN is defined as:\n* `A Splice Insert Command`\n  *  with the `out_of_network_indicator` set to `False`\n\n* `A Time Signal Command` and a Segmentation Descriptor with:\n   *  a `segmentation_type_id` of:\n\n      * 0x23: \"Break End\",\n      * 0x31: \"Provider Advertisement End\",\n      * 0x33: \"Distributor Advertisement End\",\n      * 0x35: \"Provider Placement Opportunity End\",\n      * 0x37: \"Distributor Placement Opportunity End\",\n      * 0x45: \"Provider Ad Block End\",\n      * 0x47: \"Distributor Ad Block End\",\n\n* For CUE-OUT and CUE-IN, `only the first Segmentation Descriptor will be used`\n---\n[⇪ top](#documentation)\n    \n## `Supported HLS  Tags`\n* #EXT-X-CUE \n* #EXT-X-DATERANGE \n* #EXT-X-SCTE35 \n* #EXT-X-SPLICEPOINT \n\n###  `x_cue`\n* CUE-OUT\n```lua\n#EXT-X-DISCONTINUITY\n#EXT-X-CUE-OUT:242.0\n#EXTINF:4.796145,\nseg32.ts\n```\n* CUE-OUT-CONT\n```lua\n#EXT-X-CUE-OUT-CONT:4.796145/242.0\n#EXTINF:2.12,\n```\n* CUE-IN\n```lua\n#EXT-X-DISCONTINUITY\n#EXT-X-CUE-IN\n#EXTINF:5.020145,\nseg145.ts\n\n```\n### `x_scte35`\n* CUE-OUT\n```lua\n#EXT-X-DISCONTINUITY\n#EXT-X-SCTE35:CUE=\"/DAvAAAAAAAAAP/wFAUAAAKWf+//4WoauH4BTFYgAAEAAAAKAAhDVUVJAAAAAOv1oqc=\" ,CUE-OUT=YES \n#EXTINF:4.796145,\nseg32.ts\n```\n* CUE-OUT-CONT\n```lua\n#EXT-X-SCTE35:CUE=\"/DAvAAAAAAAAAP/wFAUAAAKWf+//4WoauH4BTFYgAAEAAAAKAAhDVUVJAAAAAOv1oqc=\" ,CUE-OUT=CONT\n#EXTINF:2.12,\nseg33.ts\n```\n* CUE-IN\n```lua\n#EXT-X-DISCONTINUITY\n#EXT-X-SCTE35:CUE=\"/DAqAAAAAAAAAP/wDwUAAAKWf0//4rZw2AABAAAACgAIQ1VFSQAAAAAtegE5\" ,CUE-IN=YES \n#EXTINF:5.020145,\nseg145.ts\n```\n### `x_daterange`\n* CUE-OUT\n```lua\n#EXT-X-DISCONTINUITY\n#EXT-X-DATERANGE:ID=\"1\",START-DATE=\"2022-10-14T17:36:58.321731Z\",PLANNED-DURATION=242.0,SCTE35-OUT=0xfc302f00000000000000fff01405000002967fefffe16a1ab87e014c562000010000000a00084355454900000000ebf5a2a7\n#EXTINF:4.796145,\nseg32.ts\n```\n* CUE-IN\n```lua\n#EXT-X-DISCONTINUITY\n#EXT-X-DATERANGE:ID=\"2\",END-DATE=\"2022-10-14T17:36:58.666073Z\",SCTE35-IN=0xfc302a00000000000000fff00f05000002967f4fffe2b670d800010000000a000\n843554549000000002d7a0139\n#EXTINF:5.020145,\nseg145.ts\n```\n\n### `x_splicepoint`\n* CUE-OUT\n```lua\n#EXT-X-DISCONTINUITY\n#EXT-X-SPLICEPOINT-SCTE35:/DAvAAAAAAAAAP/wFAUAAAKWf+//4WoauH4BTFYgAAEAAAAKAAhDVUVJAAAAAOv1oqc=\n#EXTINF:4.796145,\nseg32.ts\n```\n* CUE-IN\n```lua\n#EXT-X-DISCONTINUITY\n#EXT-X-SPLICEPOINT-SCTE35:/DAqAAAAAAAAAP/wDwUAAAKWf0//4rZw2AABAAAACgAIQ1VFSQAAAAAtegE5\n#EXTINF:5.020145,\nseg145.ts\n\n```\n[⇪ top](#documentation)\n\n## `VOD`\n\n* x9k3 defaults to VOD style playlist generation.\n* All segment are listed in the m3u8 file. \n\n## `Live`\n* Activated by the `--live`, `--delete`, or `--replay` switch or by setting `X9K3.live=True`\n\n### `--live`\n   * Like VOD except:\n     * M3u8 manifests are regenerated every time a segment is written\n     * Segment creation is throttled when using non-live sources to simulate live streaming. ( like ffmpeg's \"-re\" )\n     * default Sliding Window size is 5, it can be changed with the `-w` switch or by setting `X9k3.window.size` \n###  `--delete`\n  * implies `--live`\n  * deletes segments when they move out of the sliding window of the m3u8.\n### `--replay`\n  * implies `--live`\n  * implies `--delete`\n  * loops a video file and throttles segment creation to fake a live stream.\n\n[⇪ top](#documentation)\n\n   \n### `adbreak3`\n\n* included with x9k3\n* adbreak3 is a cli tool to generate SCTE-35 for sidecar files.\n* by default adbreak3 generates 2 SCTE35 Cues with Splice Inserts for CUE-OUT and CUE-IN and writes it to a sidecar file.\n\n```sed\na@fu:~$ adbreak3 -h\nusage: adbreak3 [-h] [-d DURATION] [-e EVENT_ID] [-i] [-o] [-p PTS] [-P] [-s SIDECAR] [-v]\n\noptional arguments:\n  -h, --help            show this help message and exit\n  -d DURATION, --duration DURATION\n                        Set duration of ad break. [ default: 60.0 ]\n  -e EVENT_ID, --event-id EVENT_ID\n                        Set event id for ad break. [ default: 1 ]\n  -i, --cue-in-only     Only make a cue-in SCTE-35 cue [ default: False ]\n  -o, --cue-out-only    Only make a cue-out SCTE-35 cue [ default: False ]\n  -p PTS, --pts PTS     Set start pts for ad break. Not setting pts will generate a Splice Immediate CUE-OUT. [default: 0.0 ]\n  -P, --preroll         Add SCTE data four seconds before splice point. Used with MPEGTS. [ default: False ]\n  -s SIDECAR, --sidecar SIDECAR\n                        Sidecar file of SCTE-35 (pts,cue) pairs. [ default: sidecar.txt ]\n  -v, --version         Show version\n```\n* Usage:\n```rebol\na@fu:~$ adbreak3 --pts 1234.567890 --duration 30 --sidecar sidecar.txt\n\nWriting to sidecar file: sidecar.txt\n\n\t\tCUE-OUT   PTS:1234.567889   Id:1   Duration: 30.0\n\t\tCUE-IN    PTS:1264.567889   Id:2\n```\n\n* Sidecar file has SCTE-35 Cues for CUE-OUT and CUE-IN\n\n```smalltalk\na@fu:~$ cat sidecar.txt \n1234.56789,/DAlAAAAAAAAAP/wFAUAAABNf+/+Bp9rxv4AKTLgAE0AAAAAFz4v5A==\n1264.56789,/DAgAAAAAAAAAP/wDwUAAABOf0/+BsiepgBOAAAAABSgtGA=\n```\n\n* Pass to x9k3\n```rebol\nx9k3 -i input.ts -s sidecar.txt\n\n```\n#### `Super Cool Feature`: adbreak3 can be used in real time to add SCTE-35 on the fly to live HLS manifest.\n\n\n \n\n\n\n\n\n\n   ![image](https://github.com/futzu/x9k3/assets/52701496/65d915f9-8721-4386-9353-2e32911c6a64)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuperkabuki%2Fx9k3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsuperkabuki%2Fx9k3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuperkabuki%2Fx9k3/lists"}