threefive is SCTE35 for the civilized. Can threefive parse Mpegts video for SCTE35? Yes it can.
Project description
:rocket: threefive
threefive is a SCTE35 Parser, Decoder, Encoder library in Python3.
-
References the 2020 SCTE35 Specification.
-
threefive is simple and easy to use.
-
SCTE-35 can be parsed from strings or video with one function threefive.decode().
[Heads Up! Changes as of 1/1/2021](#changes
-
- HLS
- Multicast
- Splice Insert
- Splice_Null
- Time Signal
- UPID
- DTMF
- Stream
Changes
- 02/10/2021: threefive now encodes SCTE35 Cues.
- Encoding may be buggy, please don't use encoding in production just yet.
- Example Change pts_time for a Time Signal Splice Command
[PyPy 7.3.2 with GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>> from threefive import Cue
>>>> cue = Cue(b'/DA9AAAAAAAAAACABQb+0fha8gAnAiVDVUVJSAAAv3/PAAD4+mMNEQ4FTEEzMDkICAAAAAAuU4SBNAAAPIaCPw==')
>>>> cue.decode()
>>>> cue.command.pts_time
39141.2706
>>>> cue.get_command()
{'command_length': 5, 'name': 'Time Signal', 'time_specified_flag': True, 'pts_time': 39141.2706}
#
# Change the pts_time for the Time Signal Splice Command and encode a new Base64 encoded SCTE35 Cue.
#
>>>> cue.command.pts_time= 5000.9999
>>>> cue.get_command()
{'command_length': 5, 'name': 'Time Signal', 'time_specified_flag': True, 'pts_time': 5000.9999}
>>>> cue.encode()
b'/DA9AAAAAAAAAACABQb+GtPUBwAnAiVDVUVJSAAAv3/PAAD4+mMNEQ4FTEEzMDkICAAAAAAuU4SBNAAAPIaCPw=='
Fast Start
Dependencies
- Python 3.6+ or pypy3
- bitn
Install
- git
$ git clone https://github.com/futzu/SCTE35-threefive.git
$ cd SCTE-threefive
# you need root to install for the system
$ make install
# for pypy3
$ make pypy3
- pip
$ pip3 install threefive
# for pypy3
$ pypy3 -mpip install threefive
#If you don't have pip installed, try this.
$ pypy3 -mensurepip install pip
Easy threefive
The decode Function
- source decode.py
- threefive.decode is an all purpose function to decode SCTE 35 messages from a file or string.
- MpegTS
threefive.decode('/path/to/mpegwithscte35.ts')
- Base64
mesg='/DBUAAAAAAAA///wBQb+AAAAAAA+AjxDVUVJAAAACn+/Dy11cm46dXVpZDphYTg1YmJiNi01YzQzLTRiNmEtYmViYi1lZTNiMTNlYjc5OTkRAAB2c6LA'
threefive.decode(mesg)
- Hex
hexed='0xFC302F000000000000FFFFF014054800008F7FEFFE7369C02EFE0052CCF500000000000A0008435545490000013562DBA30A'
threefive.decode(hexed)
- Directly from a file encoded in Base64, Binary or Base64
$ cat cue.dat
/DCSAAAAAAAAAP/wBQb/RgeVUgB8AhdDVUVJbs6+VX+/CAgAAAAABy0IxzELGQIXQ1VFSW7MmIh/vwgIAAABGDayFhE3AQECHENVRUluzw0If/8AABvLoAgIAAAAAActVhIwDBkCKkNVRUluzw02f78MG1JUTE4xSAEAAAAAMTM3NjkyMDI1NDQ5NUgxAAEAAGnbuXg=
- pass threefive.decode the file name and it will parse it for SCTE35.
from threefive import decode
decode('cue.dat')
{
"info_section": {
"table_id": "0xfc",
"section_syntax_indicator": false,
"private": false,
"reserved": "0x3",
<--Snipped for Brevity -->
{
"tag": 2,
"identifier": "CUEI",
"name": "Segmentation Descriptor",
"segmentation_event_id": "0x6ecf0d36",
"segmentation_event_cancel_indicator": false,
"components": [],
"program_segmentation_flag": true,
"segmentation_duration_flag": false,
"delivery_not_restricted_flag": true,
"segmentation_message": "Content Identification",
"segmentation_upid_type": 12,
"segmentation_upid_length": 27,
"segmentation_upid": "MPU:{'format identifier': 1381256270, 'private data': 4720207453582705227611785054965731163782383190579622144}",
"segmentation_type_id": 1,
"segment_num": 0,
"segments_expected": 0,
"descriptor_length": 42
}
]
}
Advanced threefive
Cue Class
- source cue.py
- The threefive.Cue class decodes a SCTE35 binary, base64, or hex encoded string.
- threefive.Cue provides several methods to access the parsed data.
from threefive import Cue
b64 = "/DBIAAAAAAAA///wBQb+ek2ItgAyAhdDVUVJSAAAGH+fCAgAAAAALMvDRBEAAAIXQ1VFSUgAABl/nwgIAAAAACyk26AQAACZcuND"
cue = Cue(B64)
cue.decode()
Return Cue instance as dict
cue.get()
# Splice Info Section
cue.get_info_section()
# Splice Command
cue.get_command()
# Splice Descriptors
cue.get_descriptors()
Return Cue instance as JSON
jason = cue.get_json()
Print Cue instance as JSON
cue.show()
Stream Class
threefive.Stream(tsdata, show_null = False)
-
source stream.py
-
The threefive.Stream class parses SCTE35 messages from a file or stream.
-
tsdata is an open file handle.
-
show_null if set to True, enables showing SCTE 35 null commands.
-
Method | Description |
---|---|
Stream.show() | Prints all recognized Programs and streams by pid and type. |
Stream.decode(func=show_cue) | Prints SCTE-35 cues for SCTE-35 packets. Accepts an optional function, func, as arg. |
Stream.decode_next() | Returns the next SCTE35 cue as a threefive.Cue instance. |
Stream.decode_program(the_program=None, func=show_cue) | Same as Stream.decode except only packets where program == the_program |
Stream.decode_proxy(func=show_cue) | Same as Stream.decode except raw packets are written to stdout for piping to another program. |
Stream.show()
- List programs and streams for a video.
# pypy3
>>>> from threefive import Stream, version
>>>> version
'2.2.09'
>>>> with open('video.ts','rb') as tsdata:
.... st = Stream(tsdata)
.... st.show()
....
Program: 1030 (pcr pid: 1031)
1031: [0x1b] Video
1032: [0x3] ISO/IEC 11172 Audio
1034: [0x6] ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets with private data
1035: [0x86] SCTE 35
Program: 1100 (pcr pid: 1101)
1101: [0x1b] Video
1102: [0x3] ISO/IEC 11172 Audio
1104: [0x6] ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets with private data
1105: [0x86] SCTE 35
Program: 1080 (pcr pid: 1081)
1081: [0x1b] Video
1082: [0x3] ISO/IEC 11172 Audio
1084: [0x6] ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES packets with private data
Stream.decode(func=show_cue)
import sys
from threefive import Stream
if __name__ =='__main__':
with open(sys.argv[1],'rb') as tsdata:
sp = Stream.decode_nextStream(tsdata)
sp.decode()
-
Pass in custom function
-
func should match the interface
func(cue)
import sys
import threefive
def display(cue):
print(f'\033[92m{cue.packet_data}\033[00m')
print(f'{cue.command.name}')
def do():
with open(sys.argv[1],'rb') as tsdata:
sp = threefive.Stream(tsdata)
sp.decode(func = display)
if __name__ == '__main__':
do()
Stream.decode_next()
- Stream.decode_next returns the next SCTE35 cue as a threefive.Cue instance.
import sys
import threefive
def do():
arg = sys.argv[1]
with open(arg,'rb') as tsdata:
st = threefive.Stream(tsdata)
while True:
cue = st.decode_next()
if not cue:
return False
if cue:
cue.show()
if __name__ == "__main__":
do()
Stream.decode_program(the_program, func = show_cue)
- Use Stream.decode_program() instead of Stream.decode() to decode SCTE-35 from packets where program == the_program
import threefive
with open('../35.ts','rb') as tsdata:
threefive.Stream(tsdata).decode_program(1)
Stream.decode_proxy(func = show_cue)
-
Writes all packets to sys.stdout.
-
Writes scte35 data to sys.stderr.
import threefive
with open('vid.ts','rb') as tsdata:
sp = threefive.Stream(tsdata)
sp.proxy_decode()
- Pipe to mplayer
$ python3 proxy.py | mplayer -
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
threefive-2.2.61.tar.gz
(22.0 kB
view hashes)
Built Distribution
threefive-2.2.61-py3-none-any.whl
(20.4 kB
view hashes)
Close
Hashes for threefive-2.2.61-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5969f299e987a6d1d4867d82e12e98fdecbdc487c5cae16a2cc8d744188c84db |
|
MD5 | 42f177467076c746064f1d1ac00d7bf0 |
|
BLAKE2b-256 | ee350caaec22eefaeeabf5707a5272f927e5003068da769e4eb2d2a01116fb07 |