threefive 3.0.83__tar.gz → 3.0.85__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {threefive-3.0.83 → threefive-3.0.85}/PKG-INFO +54 -122
- {threefive-3.0.83 → threefive-3.0.85}/README.md +53 -121
- {threefive-3.0.83 → threefive-3.0.85}/pyproject.toml +2 -3
- {threefive-3.0.83 → threefive-3.0.85}/threefive/base.py +6 -2
- {threefive-3.0.83 → threefive-3.0.85}/threefive/cli.py +40 -23
- {threefive-3.0.83 → threefive-3.0.85}/threefive/descriptors.py +172 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/stream.py +211 -147
- {threefive-3.0.83 → threefive-3.0.85}/threefive/version.py +1 -1
- {threefive-3.0.83 → threefive-3.0.85}/threefive.egg-info/PKG-INFO +54 -122
- {threefive-3.0.83 → threefive-3.0.85}/LICENSE +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/setup.cfg +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/__init__.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/aac.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/bitn.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/bump.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/commands.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/crc.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/crctable.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/cue.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/encode.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/gums.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/hls.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/hlsprofile.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/hlstags.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/iframes.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/new_reader.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/packetdata.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/pmt.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/section.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/segment.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/segmentation.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/sixfix.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/speedo.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/streamtypes.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/stuff.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/superkabuki.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/throttle.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/udp.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/upids.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/uxp.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive/xml.py +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive.egg-info/SOURCES.txt +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive.egg-info/dependency_links.txt +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive.egg-info/entry_points.txt +0 -0
- {threefive-3.0.83 → threefive-3.0.85}/threefive.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: threefive
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.85
|
|
4
4
|
Summary: threefive is The #1 SCTE-35 Decoder and Encoder on the Planet.
|
|
5
5
|
Author-email: AdrianofDoom <spam@iodisco.com>
|
|
6
6
|
License-Expression: Sleepycat
|
|
@@ -17,79 +17,40 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
20
|
-
### It is now official, phase three of threefive's global domination has begun. Behold [threefive.js](https://github.com/keithah/threefive.js)
|
|
21
|
-
_threefive has been ported to Javascript, C#, and Go._
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
20
|
# [ threefive ]
|
|
27
21
|
|
|
28
|
-
> _... If someone says they don't use threefive for SCTE-35, they're either drunk or they're lying_. <BR> ~Adrian
|
|
29
|
-
|
|
30
22
|
## https://github.com/superkabuki/threefive
|
|
31
|
-
|
|
32
23
|
### threefive is the industry leading SCTE-35 tool.
|
|
33
|
-
#### Need to inject SCTE-35 into HLS? [X9k3.](https://github.com/superkabuki/x9k3)
|
|
34
24
|
|
|
35
|
-
*
|
|
25
|
+
* In case you were wondering ....
|
|
36
26
|
|
|
37
|
-
|
|
27
|
+
<img width="672" height="586" alt="image" src="https://github.com/user-attachments/assets/0c327200-e1f0-4055-825f-349fe89c32d6" />
|
|
38
28
|
|
|
39
|
-
* __Injects SCTE-35 Packets__ into `MPEGTS`✔.
|
|
40
29
|
|
|
41
|
-
* __Network support__ for `HTTP(s)`✔ `Multicast`✔ `UDP`✔ `SRT`✔
|
|
42
30
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
* __Automatic__ `AES decryption`✔
|
|
31
|
+
#### Need to inject SCTE-35 into HLS? [X9k3.](https://github.com/superkabuki/x9k3)
|
|
46
32
|
|
|
33
|
+
* __Decodes SCTE-35__ from `MPEGTS`✔ `Base64`✔ `Bytes`✔ `DASH`✔ `Hex` ✔ `HLS`✔ `Integers`✔ `JSON`✔ `XML`✔ `XML+Binary`✔
|
|
34
|
+
|
|
35
|
+
* __Encodes SCTE-35__ to `MPEGTS`✔ `Base64`✔ `Bytes`✔ `Hex`✔ `Integers`✔ `JSON`✔ `XML`✔ `XML+Binary`✔
|
|
47
36
|
___
|
|
48
37
|
|
|
49
|
-
# Tip of the week.
|
|
50
|
-
## Q. How do I get a list of all the SCTE-35 cues in a stream?
|
|
51
|
-
## A. Like this
|
|
52
|
-
```py3
|
|
53
|
-
from threefive import Stream
|
|
54
|
-
|
|
55
|
-
strm=Stream('some_video.ts')
|
|
56
|
-
list_o_cues=[]
|
|
57
|
-
for cue in strm.decode_next(): # Stream.decode_next is a generator
|
|
58
|
-
list_o_cues.append(cue) # these will be threefive.Cue instances
|
|
59
|
-
|
|
60
|
-
# then you can do stuff like
|
|
61
|
-
|
|
62
|
-
for cue in list_o_cues:
|
|
63
|
-
|
|
64
|
-
print(cue.xml())
|
|
65
|
-
|
|
66
|
-
print(cue.command)
|
|
67
|
-
|
|
68
|
-
cue.show()
|
|
69
|
-
```
|
|
70
|
-
* I have always felt that if you use a library, you shouldn't have to write a lot of code.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
### [ News ]
|
|
74
|
-
|
|
75
38
|
|
|
39
|
+
## [ News ]
|
|
40
|
+
* __threefive.Stream.decode()__ now does __interpreter detection__ and uses __multiprocessing__ for __python3.11__ and __python3.14__ for a __serious speedup__.
|
|
41
|
+
* __Event Descriptors__ and __Property__ types from __the recently published 2026 SCTE-35 Specification part 2__ have been added.
|
|
76
42
|
* __threefive no longer uses setuptools for packaging__ and I know you don't care.
|
|
77
|
-
* __Python3 vs. Pypy3__ [__parsing SCTE35 with threefive__](https://github.com/superkabuki/threefive_is_scte35#python3-vs-pypy3-running-threefive) (watch the cool video)
|
|
78
43
|
* __threefive now supports__ [__Secure Reliable Transport__](https://github.com/superkabuki/threefive_is_scte35/blob/main/README.md#threefive-now-supports-srt) (watch the cool video)
|
|
79
|
-
* I have been __trying to setup threefive on readthedocs__,it's not going very well, but I'm working on it.
|
|
80
44
|
___
|
|
81
45
|
|
|
82
|
-
## [ Latest version is v3.0.
|
|
46
|
+
## [ Latest version is v3.0.85 ]
|
|
83
47
|
|
|
84
|
-
* __v3.0.83__ is to fix a bug 3.0.81 related to AES decryption..
|
|
85
48
|
* threefive cyclomatic complexity score is 1.9337094499294782 _( that's better than the Python standard library)_ .
|
|
86
49
|
* __threefive now has NO External Dependencies__
|
|
87
50
|
* SRT and AES support is now optional
|
|
88
51
|
* __threefive is fully python v3.14 compliant__
|
|
89
52
|
* __No more setup tools!__ threefive now uses a __toml file and a Makefile__ to generate packages,
|
|
90
53
|
* I'm just trying to fit in with the cool python kids.
|
|
91
|
-
* __fix__ for addressable tv Upids
|
|
92
|
-
* __fix__ for private descriptor encoding and xml encoding.
|
|
93
54
|
* __New__ the threefive cli tool has spun off several new cli tools. I had to split the cli up, the help was just way too long.
|
|
94
55
|
* In addition to the __threefive__ cli you also get:
|
|
95
56
|
* __scte35bump__ _adjust scte-35 pts in mpegts streams_
|
|
@@ -97,8 +58,45 @@ ___
|
|
|
97
58
|
* __scte35hls__ _parse scte-35 from hls tags and segments_
|
|
98
59
|
* __scte35inject__ _inject scte-35 packets into mpegts streams_
|
|
99
60
|
* __gums__ _(the Grande Unified unicast and Multicast Server)_
|
|
100
|
-
|
|
101
|
-
|
|
61
|
+
___
|
|
62
|
+
|
|
63
|
+
### If you parse the output from the threefive cli....
|
|
64
|
+
* Comments, errors, and warnings, even printed comments, errors, and warnings, that are not the output, start with an octothorpe '#' and can be stripped, if needed, with sed.
|
|
65
|
+
```sed
|
|
66
|
+
threefive video.ts 2>&1 | sed -n '/^\#/!p' -
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### [ Speed Test ]
|
|
70
|
+
#### pypy3 vs. python3.11 vs. python3.14 running threefive 3.0.0x840c (_pre-release_)
|
|
71
|
+
|
|
72
|
+
* Using multiprocessing cuts parsing time in half for python 3.11 even more for python3.14
|
|
73
|
+
|
|
74
|
+
* single process pypy3 is still faster though.
|
|
75
|
+
|
|
76
|
+
* The test is to parse a 3.7 GB file for 286 SCTE-35 Cues.
|
|
77
|
+
|
|
78
|
+
* Results
|
|
79
|
+
|
|
80
|
+
| interpreter| time |
|
|
81
|
+
|------------|----------|
|
|
82
|
+
|__pypy3__ |__3.532 secs__|
|
|
83
|
+
|python3.11 |5.520 secs|
|
|
84
|
+
|python3.14 |5.521 secs|
|
|
85
|
+
|
|
86
|
+
* When I did the same test for threefive v3.0.83, pypy3 was 4.1 seconds, python3.11 was 10 seconds, and python3.14 was over 14 secs
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
## [ Try these in your browser ]
|
|
90
|
+
#### Parse SCTE-35 in MPEGTS over HTTP, in your browser with[ Go, Wasm and Super Karate Death Car](https://bigcorp.ltd/gowasm)
|
|
91
|
+
|
|
92
|
+
#### Parse, edit, and convert SCTE-35 Cues in your browser with [fastcgi, python3, threefive, and nstuff](https://iodisco.com/scte35)
|
|
93
|
+
|
|
94
|
+
#### Parse SCTE-35 in MPEGTS over HTTP, in your browser with[ threefive.js,javascript, and a little sed](https://bigcorp.ltd/bread) just to keep things interesting.
|
|
95
|
+
|
|
96
|
+
#### Decode SCTE-35 data via Http request in a browser, with curl, or whatever with [Sassy](https://github.com/superkabuki/threefive_is_scte35/blob/main/sassy.md) , SCTE-35 as a Service.
|
|
97
|
+
|
|
98
|
+
___
|
|
99
|
+
# [__[ Examples ]__](https://github.com/superkabuki/threefive/tree/main/examples)
|
|
102
100
|
|
|
103
101
|
|
|
104
102
|
|
|
@@ -108,6 +106,7 @@ ___
|
|
|
108
106
|
* [threefive SCTE-35 __Online Parser__](https://iodisco.com/scte35) hosted on my server_
|
|
109
107
|
* [ SCTE-35 __Online Parser__ powered by threefive](http://www.domus1938.com/scte35parser) _another online parser powered by threefive_
|
|
110
108
|
* [SCTE-35 __As a Service__](sassy.md) _if you can make an http request, you can parse SCTE-35, no install needed._
|
|
109
|
+
|
|
111
110
|
* [__install__](#install)
|
|
112
111
|
* __command line tools__
|
|
113
112
|
* [ __threefive__](#cli) _decode SCTE-35 on the command line_
|
|
@@ -123,9 +122,7 @@ ___
|
|
|
123
122
|
* [__Cue__ Class](https://github.com/superkabuki/threefive/blob/main/cue.md) _this class you'll use often_
|
|
124
123
|
* [__Stream__ Class](https://github.com/superkabuki/threefive/blob/main/stream.md) _this is the class for parsing MPEGTS_
|
|
125
124
|
|
|
126
|
-
* [Use __threefive to stream Multicast__](#-threefive-streams-multicast-its-easy-) _threefive is a multicast client and server_
|
|
127
125
|
* [SCTE-35 __Sidecar Files__](https://github.com/superkabuki/SCTE-35_Sidecar_Files) _threefive supports SCTE-35 sidecar files_
|
|
128
|
-
* [__SuperKabuki__ SCTE-35 MPEGTS __Packet Injection__](inject.md) _inject SCTE-35 into MPEGTS streams_
|
|
129
126
|
* [SCTE-35 __HLS__](https://github.com/superkabuki/threefive/blob/main/hls.md) _parse SCTE-35 in HLS__
|
|
130
127
|
* [SCTE-35 __XML__ ](https://github.com/superkabuki/SCTE-35/blob/main/xml.md) and [More __XML__](node.md) _threefive can parse and encode SCTE-35 xml_
|
|
131
128
|
* [__Encode__ SCTE-35](https://github.com/superkabuki/threefive/blob/main/encode.md) _threefive can encode SCTE-35 in every SCTE-35 format_
|
|
@@ -644,10 +641,8 @@ Type "help", "copyright", "credits" or "license" for more information.
|
|
|
644
641
|
* [__SCTE-35 Inputs__](#inputs)
|
|
645
642
|
* [__SCTE-35 Outputs__](#outputs)
|
|
646
643
|
* [Parse __MPEGTS__ streams for __SCTE-35__](#streams)
|
|
647
|
-
* [Parse __SCTE-35__ in __hls__](#hls)
|
|
648
644
|
* [Display __MPEGTS__ __iframes__](#iframes)
|
|
649
645
|
* [Display raw __SCTE-35 packets__ from __video streams__](#packets)
|
|
650
|
-
* [__Repair SCTE-35 streams__ changed to __bin data__ by __ffmpeg__](#sixfix)
|
|
651
646
|
|
|
652
647
|
#### `Inputs`
|
|
653
648
|
|
|
@@ -692,14 +687,12 @@ threefive '/DAWAAAAAAAAAP/wBQb+ztd7owAAdIbbmw=='
|
|
|
692
687
|
| __Stdin__ | `threefive < video.ts` |
|
|
693
688
|
| __UDP Multicast__| `threefive udp://@235.35.3.5:9999` |
|
|
694
689
|
| __UDP Unicast__ | `threefive udp://10.0.0.7:5555` |
|
|
695
|
-
| __HLS__ | `threefive hls https://example.com/master.m3u8`|
|
|
696
|
-
| | |
|
|
697
690
|
|
|
698
691
|
|
|
699
692
|
#### Outputs
|
|
700
693
|
* output type is determined by the key words __base64, bytes, hex, int, json, and xmlbin__.
|
|
701
694
|
* __json is the default__.
|
|
702
|
-
* __Any input
|
|
695
|
+
* __Any input can be returned as any output__
|
|
703
696
|
* examples __Base64 to Hex__ etc...)
|
|
704
697
|
|
|
705
698
|
|
|
@@ -711,12 +704,6 @@ threefive '/DAWAAAAAAAAAP/wBQb+ztd7owAAdIbbmw=='
|
|
|
711
704
|
| __Integer__ | `threefive '/DAsAAAAAyiYAP/wCgUAAAABf1+ZmQEBABECD0NVRUkAAAAAf4ABADUAAC2XQZU=' int` |
|
|
712
705
|
| __JSON__ | `threefive 0xfc301600000000000000fff00506fed605225b0000b0b65f3b json ` |
|
|
713
706
|
| __Xml+bin__ | `threefive 0xfc301600000000000000fff00506fed605225b0000b0b65f3b xmlbin ` |`
|
|
714
|
-
|
|
715
|
-
#### `hls`
|
|
716
|
-
* parse hls manifests and segments for SCTE-35
|
|
717
|
-
```smalltalk
|
|
718
|
-
threefive hls https://example.com/master.m3u8
|
|
719
|
-
```
|
|
720
707
|
___
|
|
721
708
|
#### `Iframes`
|
|
722
709
|
* Show iframes PTS in an MPEGTS video
|
|
@@ -754,13 +741,7 @@ ___
|
|
|
754
741
|
threefive sidecar video.ts
|
|
755
742
|
```
|
|
756
743
|
___
|
|
757
|
-
#### `sixfix`
|
|
758
|
-
* Fix SCTE-35 data mangled by ffmpeg
|
|
759
744
|
|
|
760
|
-
```smalltalk
|
|
761
|
-
threefive sixfix video.ts
|
|
762
|
-
```
|
|
763
|
-
___
|
|
764
745
|
#### `show`
|
|
765
746
|
|
|
766
747
|
* Probe mpegts video _( kind of like ffprobe )_
|
|
@@ -784,54 +765,6 @@ ___
|
|
|
784
765
|
___
|
|
785
766
|
|
|
786
767
|
|
|
787
|
-
## [ threefive Streams Multicast, it's easy. ]
|
|
788
|
-
* The threefive cli has long been a Multicast Receiver( client )
|
|
789
|
-
* The cli now comes with a builtin Multicast Sender( server).
|
|
790
|
-
* It's optimized for MPEGTS (1316 byte Datagrams) but you can send any video or file.
|
|
791
|
-
* The defaults will work in most situations, you don't even have to set the address.
|
|
792
|
-
* threefive cli also supports UDP Unicast Streaming.
|
|
793
|
-
|
|
794
|
-
If you're tired of configuring strange kernel settings with sysctl trying to get multicast to work,<br>
|
|
795
|
-
threefive multicast is written from scratch in raw sockets and autoconfigures most settings,<br>
|
|
796
|
-
threefive adjusts the SO_RCVBUF, SO_SNDBUF, SO_REUSEADDR,SO_REUSEPORT,IP_MULTICAST_TTL and IP_MULTICAST_LOOP for you.<br>
|
|
797
|
-
all you really need to do is make sure multicast is enabled on the network device, threefive can handle the rest.<br>
|
|
798
|
-
```js
|
|
799
|
-
ip link set wlp2s0 multicast on
|
|
800
|
-
|
|
801
|
-
```
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
```js
|
|
805
|
-
a@fu:~$ threefive mcast help
|
|
806
|
-
usage: threefive mcast [-h] [-i INPUT] [-a ADDR] [-b BIND_ADDR] [-t TTL]
|
|
807
|
-
|
|
808
|
-
optional arguments:
|
|
809
|
-
-h, --help show this help message and exit
|
|
810
|
-
-i INPUT, --input INPUT
|
|
811
|
-
like "/home/a/vid.ts" or "udp://@235.35.3.5:3535" or
|
|
812
|
-
"https://futzu.com/xaa.ts"
|
|
813
|
-
[default:sys.stdin.buffer]
|
|
814
|
-
-a ADDR, --addr ADDR Destination IP:Port [default:235.35.3.5:3535]
|
|
815
|
-
-b BIND_ADDR, --bind_addr BIND_ADDR
|
|
816
|
-
Local IP to bind [default:0.0.0.0]
|
|
817
|
-
-t TTL, --ttl TTL Multicast TTL (1 - 255) [default:32]
|
|
818
|
-
a@fu:~$
|
|
819
|
-
```
|
|
820
|
-
|
|
821
|
-
* the video shows three streams being read and played from threefive's multicast, one stream is being converted to srt.
|
|
822
|
-
* the command
|
|
823
|
-
```sh
|
|
824
|
-
a@fu:~/scratch/threefive$ threefive mcast -i ~/mpegts/ms.ts
|
|
825
|
-
|
|
826
|
-
```
|
|
827
|
-
|
|
828
|
-
https://github.com/user-attachments/assets/df95b8da-5ca6-4bf3-b029-c95204841e43
|
|
829
|
-
|
|
830
|
-
* __threefive mcast__ sends __1316 byte datagrams__. Here's `tcpdump multicast`output.
|
|
831
|
-
|
|
832
|
-
<img width="1126" height="679" alt="image" src="https://github.com/user-attachments/assets/b29f33c7-d35c-42be-95fb-2c6e72d1ab9b" />
|
|
833
|
-
|
|
834
|
-
___
|
|
835
768
|
|
|
836
769
|
|
|
837
770
|
## [iodisco.com/scte35](https://iodisco.com/scte35)
|
|
@@ -847,6 +780,5 @@ ___
|
|
|
847
780
|
<img width="258" height="256" alt="image" src="https://github.com/user-attachments/assets/642cb803-9465-408e-bb6e-03549eb22d78" />
|
|
848
781
|
|
|
849
782
|
___
|
|
850
|
-
[__Install__](#install) |[__SCTE-35 Cli__](#the-cli-tool) |
|
|
851
|
-
| [__SCTE-35 XML__ ](https://github.com/superkabuki/SCTE-35/blob/main/xml.md) and [More __XML__](node.md) | [__threefive runs Four Times Faster on pypy3__](https://pypy.org/)
|
|
852
|
-
|
|
783
|
+
[__Install__](#install) |[__SCTE-35 Cli__](#the-cli-tool) | [__Cue__ Class](https://github.com/superkabuki/threefive/blob/main/cue.md) | [__Stream__ Class](https://github.com/superkabuki/threefive/blob/main/stream.md) | [__Online SCTE-35 Parser__](https://iodisco.com/scte35) | [__SCTE-35 Examples__](https://github.com/superkabuki/threefive/tree/main/examples)
|
|
784
|
+
| [__SCTE-35 XML__ ](https://github.com/superkabuki/SCTE-35/blob/main/xml.md) and [More __XML__](node.md) | [__threefive runs Four Times Faster on pypy3__](https://pypy.org/)
|
|
@@ -1,76 +1,37 @@
|
|
|
1
|
-
### It is now official, phase three of threefive's global domination has begun. Behold [threefive.js](https://github.com/keithah/threefive.js)
|
|
2
|
-
_threefive has been ported to Javascript, C#, and Go._
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
1
|
# [ threefive ]
|
|
8
2
|
|
|
9
|
-
> _... If someone says they don't use threefive for SCTE-35, they're either drunk or they're lying_. <BR> ~Adrian
|
|
10
|
-
|
|
11
3
|
## https://github.com/superkabuki/threefive
|
|
12
|
-
|
|
13
4
|
### threefive is the industry leading SCTE-35 tool.
|
|
14
|
-
#### Need to inject SCTE-35 into HLS? [X9k3.](https://github.com/superkabuki/x9k3)
|
|
15
5
|
|
|
16
|
-
*
|
|
6
|
+
* In case you were wondering ....
|
|
17
7
|
|
|
18
|
-
|
|
8
|
+
<img width="672" height="586" alt="image" src="https://github.com/user-attachments/assets/0c327200-e1f0-4055-825f-349fe89c32d6" />
|
|
19
9
|
|
|
20
|
-
* __Injects SCTE-35 Packets__ into `MPEGTS`✔.
|
|
21
10
|
|
|
22
|
-
* __Network support__ for `HTTP(s)`✔ `Multicast`✔ `UDP`✔ `SRT`✔
|
|
23
11
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* __Automatic__ `AES decryption`✔
|
|
12
|
+
#### Need to inject SCTE-35 into HLS? [X9k3.](https://github.com/superkabuki/x9k3)
|
|
27
13
|
|
|
14
|
+
* __Decodes SCTE-35__ from `MPEGTS`✔ `Base64`✔ `Bytes`✔ `DASH`✔ `Hex` ✔ `HLS`✔ `Integers`✔ `JSON`✔ `XML`✔ `XML+Binary`✔
|
|
15
|
+
|
|
16
|
+
* __Encodes SCTE-35__ to `MPEGTS`✔ `Base64`✔ `Bytes`✔ `Hex`✔ `Integers`✔ `JSON`✔ `XML`✔ `XML+Binary`✔
|
|
28
17
|
___
|
|
29
18
|
|
|
30
|
-
# Tip of the week.
|
|
31
|
-
## Q. How do I get a list of all the SCTE-35 cues in a stream?
|
|
32
|
-
## A. Like this
|
|
33
|
-
```py3
|
|
34
|
-
from threefive import Stream
|
|
35
|
-
|
|
36
|
-
strm=Stream('some_video.ts')
|
|
37
|
-
list_o_cues=[]
|
|
38
|
-
for cue in strm.decode_next(): # Stream.decode_next is a generator
|
|
39
|
-
list_o_cues.append(cue) # these will be threefive.Cue instances
|
|
40
|
-
|
|
41
|
-
# then you can do stuff like
|
|
42
|
-
|
|
43
|
-
for cue in list_o_cues:
|
|
44
|
-
|
|
45
|
-
print(cue.xml())
|
|
46
|
-
|
|
47
|
-
print(cue.command)
|
|
48
|
-
|
|
49
|
-
cue.show()
|
|
50
|
-
```
|
|
51
|
-
* I have always felt that if you use a library, you shouldn't have to write a lot of code.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
### [ News ]
|
|
55
|
-
|
|
56
19
|
|
|
20
|
+
## [ News ]
|
|
21
|
+
* __threefive.Stream.decode()__ now does __interpreter detection__ and uses __multiprocessing__ for __python3.11__ and __python3.14__ for a __serious speedup__.
|
|
22
|
+
* __Event Descriptors__ and __Property__ types from __the recently published 2026 SCTE-35 Specification part 2__ have been added.
|
|
57
23
|
* __threefive no longer uses setuptools for packaging__ and I know you don't care.
|
|
58
|
-
* __Python3 vs. Pypy3__ [__parsing SCTE35 with threefive__](https://github.com/superkabuki/threefive_is_scte35#python3-vs-pypy3-running-threefive) (watch the cool video)
|
|
59
24
|
* __threefive now supports__ [__Secure Reliable Transport__](https://github.com/superkabuki/threefive_is_scte35/blob/main/README.md#threefive-now-supports-srt) (watch the cool video)
|
|
60
|
-
* I have been __trying to setup threefive on readthedocs__,it's not going very well, but I'm working on it.
|
|
61
25
|
___
|
|
62
26
|
|
|
63
|
-
## [ Latest version is v3.0.
|
|
27
|
+
## [ Latest version is v3.0.85 ]
|
|
64
28
|
|
|
65
|
-
* __v3.0.83__ is to fix a bug 3.0.81 related to AES decryption..
|
|
66
29
|
* threefive cyclomatic complexity score is 1.9337094499294782 _( that's better than the Python standard library)_ .
|
|
67
30
|
* __threefive now has NO External Dependencies__
|
|
68
31
|
* SRT and AES support is now optional
|
|
69
32
|
* __threefive is fully python v3.14 compliant__
|
|
70
33
|
* __No more setup tools!__ threefive now uses a __toml file and a Makefile__ to generate packages,
|
|
71
34
|
* I'm just trying to fit in with the cool python kids.
|
|
72
|
-
* __fix__ for addressable tv Upids
|
|
73
|
-
* __fix__ for private descriptor encoding and xml encoding.
|
|
74
35
|
* __New__ the threefive cli tool has spun off several new cli tools. I had to split the cli up, the help was just way too long.
|
|
75
36
|
* In addition to the __threefive__ cli you also get:
|
|
76
37
|
* __scte35bump__ _adjust scte-35 pts in mpegts streams_
|
|
@@ -78,8 +39,45 @@ ___
|
|
|
78
39
|
* __scte35hls__ _parse scte-35 from hls tags and segments_
|
|
79
40
|
* __scte35inject__ _inject scte-35 packets into mpegts streams_
|
|
80
41
|
* __gums__ _(the Grande Unified unicast and Multicast Server)_
|
|
81
|
-
|
|
82
|
-
|
|
42
|
+
___
|
|
43
|
+
|
|
44
|
+
### If you parse the output from the threefive cli....
|
|
45
|
+
* Comments, errors, and warnings, even printed comments, errors, and warnings, that are not the output, start with an octothorpe '#' and can be stripped, if needed, with sed.
|
|
46
|
+
```sed
|
|
47
|
+
threefive video.ts 2>&1 | sed -n '/^\#/!p' -
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### [ Speed Test ]
|
|
51
|
+
#### pypy3 vs. python3.11 vs. python3.14 running threefive 3.0.0x840c (_pre-release_)
|
|
52
|
+
|
|
53
|
+
* Using multiprocessing cuts parsing time in half for python 3.11 even more for python3.14
|
|
54
|
+
|
|
55
|
+
* single process pypy3 is still faster though.
|
|
56
|
+
|
|
57
|
+
* The test is to parse a 3.7 GB file for 286 SCTE-35 Cues.
|
|
58
|
+
|
|
59
|
+
* Results
|
|
60
|
+
|
|
61
|
+
| interpreter| time |
|
|
62
|
+
|------------|----------|
|
|
63
|
+
|__pypy3__ |__3.532 secs__|
|
|
64
|
+
|python3.11 |5.520 secs|
|
|
65
|
+
|python3.14 |5.521 secs|
|
|
66
|
+
|
|
67
|
+
* When I did the same test for threefive v3.0.83, pypy3 was 4.1 seconds, python3.11 was 10 seconds, and python3.14 was over 14 secs
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## [ Try these in your browser ]
|
|
71
|
+
#### Parse SCTE-35 in MPEGTS over HTTP, in your browser with[ Go, Wasm and Super Karate Death Car](https://bigcorp.ltd/gowasm)
|
|
72
|
+
|
|
73
|
+
#### Parse, edit, and convert SCTE-35 Cues in your browser with [fastcgi, python3, threefive, and nstuff](https://iodisco.com/scte35)
|
|
74
|
+
|
|
75
|
+
#### Parse SCTE-35 in MPEGTS over HTTP, in your browser with[ threefive.js,javascript, and a little sed](https://bigcorp.ltd/bread) just to keep things interesting.
|
|
76
|
+
|
|
77
|
+
#### Decode SCTE-35 data via Http request in a browser, with curl, or whatever with [Sassy](https://github.com/superkabuki/threefive_is_scte35/blob/main/sassy.md) , SCTE-35 as a Service.
|
|
78
|
+
|
|
79
|
+
___
|
|
80
|
+
# [__[ Examples ]__](https://github.com/superkabuki/threefive/tree/main/examples)
|
|
83
81
|
|
|
84
82
|
|
|
85
83
|
|
|
@@ -89,6 +87,7 @@ ___
|
|
|
89
87
|
* [threefive SCTE-35 __Online Parser__](https://iodisco.com/scte35) hosted on my server_
|
|
90
88
|
* [ SCTE-35 __Online Parser__ powered by threefive](http://www.domus1938.com/scte35parser) _another online parser powered by threefive_
|
|
91
89
|
* [SCTE-35 __As a Service__](sassy.md) _if you can make an http request, you can parse SCTE-35, no install needed._
|
|
90
|
+
|
|
92
91
|
* [__install__](#install)
|
|
93
92
|
* __command line tools__
|
|
94
93
|
* [ __threefive__](#cli) _decode SCTE-35 on the command line_
|
|
@@ -104,9 +103,7 @@ ___
|
|
|
104
103
|
* [__Cue__ Class](https://github.com/superkabuki/threefive/blob/main/cue.md) _this class you'll use often_
|
|
105
104
|
* [__Stream__ Class](https://github.com/superkabuki/threefive/blob/main/stream.md) _this is the class for parsing MPEGTS_
|
|
106
105
|
|
|
107
|
-
* [Use __threefive to stream Multicast__](#-threefive-streams-multicast-its-easy-) _threefive is a multicast client and server_
|
|
108
106
|
* [SCTE-35 __Sidecar Files__](https://github.com/superkabuki/SCTE-35_Sidecar_Files) _threefive supports SCTE-35 sidecar files_
|
|
109
|
-
* [__SuperKabuki__ SCTE-35 MPEGTS __Packet Injection__](inject.md) _inject SCTE-35 into MPEGTS streams_
|
|
110
107
|
* [SCTE-35 __HLS__](https://github.com/superkabuki/threefive/blob/main/hls.md) _parse SCTE-35 in HLS__
|
|
111
108
|
* [SCTE-35 __XML__ ](https://github.com/superkabuki/SCTE-35/blob/main/xml.md) and [More __XML__](node.md) _threefive can parse and encode SCTE-35 xml_
|
|
112
109
|
* [__Encode__ SCTE-35](https://github.com/superkabuki/threefive/blob/main/encode.md) _threefive can encode SCTE-35 in every SCTE-35 format_
|
|
@@ -625,10 +622,8 @@ Type "help", "copyright", "credits" or "license" for more information.
|
|
|
625
622
|
* [__SCTE-35 Inputs__](#inputs)
|
|
626
623
|
* [__SCTE-35 Outputs__](#outputs)
|
|
627
624
|
* [Parse __MPEGTS__ streams for __SCTE-35__](#streams)
|
|
628
|
-
* [Parse __SCTE-35__ in __hls__](#hls)
|
|
629
625
|
* [Display __MPEGTS__ __iframes__](#iframes)
|
|
630
626
|
* [Display raw __SCTE-35 packets__ from __video streams__](#packets)
|
|
631
|
-
* [__Repair SCTE-35 streams__ changed to __bin data__ by __ffmpeg__](#sixfix)
|
|
632
627
|
|
|
633
628
|
#### `Inputs`
|
|
634
629
|
|
|
@@ -673,14 +668,12 @@ threefive '/DAWAAAAAAAAAP/wBQb+ztd7owAAdIbbmw=='
|
|
|
673
668
|
| __Stdin__ | `threefive < video.ts` |
|
|
674
669
|
| __UDP Multicast__| `threefive udp://@235.35.3.5:9999` |
|
|
675
670
|
| __UDP Unicast__ | `threefive udp://10.0.0.7:5555` |
|
|
676
|
-
| __HLS__ | `threefive hls https://example.com/master.m3u8`|
|
|
677
|
-
| | |
|
|
678
671
|
|
|
679
672
|
|
|
680
673
|
#### Outputs
|
|
681
674
|
* output type is determined by the key words __base64, bytes, hex, int, json, and xmlbin__.
|
|
682
675
|
* __json is the default__.
|
|
683
|
-
* __Any input
|
|
676
|
+
* __Any input can be returned as any output__
|
|
684
677
|
* examples __Base64 to Hex__ etc...)
|
|
685
678
|
|
|
686
679
|
|
|
@@ -692,12 +685,6 @@ threefive '/DAWAAAAAAAAAP/wBQb+ztd7owAAdIbbmw=='
|
|
|
692
685
|
| __Integer__ | `threefive '/DAsAAAAAyiYAP/wCgUAAAABf1+ZmQEBABECD0NVRUkAAAAAf4ABADUAAC2XQZU=' int` |
|
|
693
686
|
| __JSON__ | `threefive 0xfc301600000000000000fff00506fed605225b0000b0b65f3b json ` |
|
|
694
687
|
| __Xml+bin__ | `threefive 0xfc301600000000000000fff00506fed605225b0000b0b65f3b xmlbin ` |`
|
|
695
|
-
|
|
696
|
-
#### `hls`
|
|
697
|
-
* parse hls manifests and segments for SCTE-35
|
|
698
|
-
```smalltalk
|
|
699
|
-
threefive hls https://example.com/master.m3u8
|
|
700
|
-
```
|
|
701
688
|
___
|
|
702
689
|
#### `Iframes`
|
|
703
690
|
* Show iframes PTS in an MPEGTS video
|
|
@@ -735,13 +722,7 @@ ___
|
|
|
735
722
|
threefive sidecar video.ts
|
|
736
723
|
```
|
|
737
724
|
___
|
|
738
|
-
#### `sixfix`
|
|
739
|
-
* Fix SCTE-35 data mangled by ffmpeg
|
|
740
725
|
|
|
741
|
-
```smalltalk
|
|
742
|
-
threefive sixfix video.ts
|
|
743
|
-
```
|
|
744
|
-
___
|
|
745
726
|
#### `show`
|
|
746
727
|
|
|
747
728
|
* Probe mpegts video _( kind of like ffprobe )_
|
|
@@ -765,54 +746,6 @@ ___
|
|
|
765
746
|
___
|
|
766
747
|
|
|
767
748
|
|
|
768
|
-
## [ threefive Streams Multicast, it's easy. ]
|
|
769
|
-
* The threefive cli has long been a Multicast Receiver( client )
|
|
770
|
-
* The cli now comes with a builtin Multicast Sender( server).
|
|
771
|
-
* It's optimized for MPEGTS (1316 byte Datagrams) but you can send any video or file.
|
|
772
|
-
* The defaults will work in most situations, you don't even have to set the address.
|
|
773
|
-
* threefive cli also supports UDP Unicast Streaming.
|
|
774
|
-
|
|
775
|
-
If you're tired of configuring strange kernel settings with sysctl trying to get multicast to work,<br>
|
|
776
|
-
threefive multicast is written from scratch in raw sockets and autoconfigures most settings,<br>
|
|
777
|
-
threefive adjusts the SO_RCVBUF, SO_SNDBUF, SO_REUSEADDR,SO_REUSEPORT,IP_MULTICAST_TTL and IP_MULTICAST_LOOP for you.<br>
|
|
778
|
-
all you really need to do is make sure multicast is enabled on the network device, threefive can handle the rest.<br>
|
|
779
|
-
```js
|
|
780
|
-
ip link set wlp2s0 multicast on
|
|
781
|
-
|
|
782
|
-
```
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
```js
|
|
786
|
-
a@fu:~$ threefive mcast help
|
|
787
|
-
usage: threefive mcast [-h] [-i INPUT] [-a ADDR] [-b BIND_ADDR] [-t TTL]
|
|
788
|
-
|
|
789
|
-
optional arguments:
|
|
790
|
-
-h, --help show this help message and exit
|
|
791
|
-
-i INPUT, --input INPUT
|
|
792
|
-
like "/home/a/vid.ts" or "udp://@235.35.3.5:3535" or
|
|
793
|
-
"https://futzu.com/xaa.ts"
|
|
794
|
-
[default:sys.stdin.buffer]
|
|
795
|
-
-a ADDR, --addr ADDR Destination IP:Port [default:235.35.3.5:3535]
|
|
796
|
-
-b BIND_ADDR, --bind_addr BIND_ADDR
|
|
797
|
-
Local IP to bind [default:0.0.0.0]
|
|
798
|
-
-t TTL, --ttl TTL Multicast TTL (1 - 255) [default:32]
|
|
799
|
-
a@fu:~$
|
|
800
|
-
```
|
|
801
|
-
|
|
802
|
-
* the video shows three streams being read and played from threefive's multicast, one stream is being converted to srt.
|
|
803
|
-
* the command
|
|
804
|
-
```sh
|
|
805
|
-
a@fu:~/scratch/threefive$ threefive mcast -i ~/mpegts/ms.ts
|
|
806
|
-
|
|
807
|
-
```
|
|
808
|
-
|
|
809
|
-
https://github.com/user-attachments/assets/df95b8da-5ca6-4bf3-b029-c95204841e43
|
|
810
|
-
|
|
811
|
-
* __threefive mcast__ sends __1316 byte datagrams__. Here's `tcpdump multicast`output.
|
|
812
|
-
|
|
813
|
-
<img width="1126" height="679" alt="image" src="https://github.com/user-attachments/assets/b29f33c7-d35c-42be-95fb-2c6e72d1ab9b" />
|
|
814
|
-
|
|
815
|
-
___
|
|
816
749
|
|
|
817
750
|
|
|
818
751
|
## [iodisco.com/scte35](https://iodisco.com/scte35)
|
|
@@ -828,6 +761,5 @@ ___
|
|
|
828
761
|
<img width="258" height="256" alt="image" src="https://github.com/user-attachments/assets/642cb803-9465-408e-bb6e-03549eb22d78" />
|
|
829
762
|
|
|
830
763
|
___
|
|
831
|
-
[__Install__](#install) |[__SCTE-35 Cli__](#the-cli-tool) |
|
|
832
|
-
| [__SCTE-35 XML__ ](https://github.com/superkabuki/SCTE-35/blob/main/xml.md) and [More __XML__](node.md) | [__threefive runs Four Times Faster on pypy3__](https://pypy.org/)
|
|
833
|
-
|
|
764
|
+
[__Install__](#install) |[__SCTE-35 Cli__](#the-cli-tool) | [__Cue__ Class](https://github.com/superkabuki/threefive/blob/main/cue.md) | [__Stream__ Class](https://github.com/superkabuki/threefive/blob/main/stream.md) | [__Online SCTE-35 Parser__](https://iodisco.com/scte35) | [__SCTE-35 Examples__](https://github.com/superkabuki/threefive/tree/main/examples)
|
|
765
|
+
| [__SCTE-35 XML__ ](https://github.com/superkabuki/SCTE-35/blob/main/xml.md) and [More __XML__](node.md) | [__threefive runs Four Times Faster on pypy3__](https://pypy.org/)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
[project]
|
|
3
3
|
name = "threefive"
|
|
4
|
-
version = "3.0.
|
|
4
|
+
version = "3.0.85"
|
|
5
5
|
authors = [
|
|
6
6
|
{ name="AdrianofDoom", email="spam@iodisco.com" },
|
|
7
7
|
]
|
|
@@ -12,8 +12,6 @@ dependencies=[
|
|
|
12
12
|
|
|
13
13
|
]
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
15
|
classifiers = [
|
|
18
16
|
"Environment :: Console",
|
|
19
17
|
"Operating System :: OS Independent",
|
|
@@ -22,6 +20,7 @@ classifiers = [
|
|
|
22
20
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
23
21
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
24
22
|
]
|
|
23
|
+
|
|
25
24
|
license = "Sleepycat"
|
|
26
25
|
license-files = ["LICEN[CS]E*"]
|
|
27
26
|
|
|
@@ -170,12 +170,16 @@ class SCTE35Base:
|
|
|
170
170
|
def _b2l(val):
|
|
171
171
|
if isinstance(val, SCTE35Base):
|
|
172
172
|
val.kv_clean()
|
|
173
|
+
print(val)
|
|
173
174
|
if isinstance(val, (list)):
|
|
174
|
-
val
|
|
175
|
+
if val and isinstance(val[0], SCTE35Base):
|
|
176
|
+
val = [v.kv_clean() for v in val]
|
|
177
|
+
else:
|
|
178
|
+
val = [_b2l(v) for v in val]
|
|
175
179
|
if isinstance(val, (dict)):
|
|
176
180
|
val = {k: _b2l(v) for k, v in val.items()}
|
|
177
181
|
if isinstance(val, (bytes, bytearray)):
|
|
178
|
-
val =
|
|
182
|
+
val = val.decode()
|
|
179
183
|
return val
|
|
180
184
|
|
|
181
185
|
return {
|