A Fast SCTE 35 Decoder for Mpeg-TS Video, and Base64 or Hex Encoded Messages.
Project description
:rocket: threefive
SCTE35 Decoder
- All 2019 SCTE-35 Splice Commands and Splice Descriptors are Fully Supported.
Heads Up! Changes as of 10/23/2020
- threefive works best with pypy3
- Requires Python 3.6+
- Latest Pip Version
- Fast Start
- Easy threefive
- Advanced threefive
- Examples
- HLS
- Multicast
- Splice Insert
- Splice_Null
- Time Signal
- UPID
- Stream.decode_proxy() Example
Changes
- As of version 2.1.95, threefive.version returns a string for the current version.
>>> import threefive
>>> threefive.version
'2.1.95'
- Stream.decode, Stream.decode_pid, and Stream.decode_proxy now all take an optional function as an arg. See Stream
- Stream.decode_until_found() is now Stream.decode_next()
- Stream.decode_pid() is now Stream.decode_program()
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.
import threefive
- MpegTS
threefive.decode('/path/to/mpegwithscte35.ts')
- Base64
mesg='/DBUAAAAAAAA///wBQb+AAAAAAA+AjxDVUVJAAAACn+/Dy11cm46dXVpZDphYTg1YmJiNi01YzQzLTRiNmEtYmViYi1lZTNiMTNlYjc5OTkRAAB2c6LA'
threefive.decode(mesg)
- Hex
hexed='0xFC302F000000000000FFFFF014054800008F7FEFFE7369C02EFE0052CCF500000000000A0008435545490000013562DBA30A'
threefive.decode(hexed)
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)
Return cue as dict
cue.get()
# Splice Info Section
cue.get_info_section()
# Splice Command
cue.get_command()
# Splice Descriptors
cue.get_descriptors()
Return cue as JSON
jason = cue.get_json()
Print cue 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 a Cue instance for a SCTE-35 packet. |
Stream.decode_program(the_program,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(tsdata)
sp.decode()
-
Pass in custom function
-
func should match the interface
func(cue)
-
example
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()
- Returns a threefive.Cue instance when a SCTE-35 packet is found.
import sys
from threefive import Stream
def display(cue):
print(f'\033[92m{cue.command.name}\033[00m')
print(f'{cue.packet_data}')
def do():
with open(sys.argv[1],'rb') as tsdata:
sp = Stream(tsdata)
while tsdata:
cue = sp.decode_next()
if not cue :
sys.exit()
display(cue)
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.25.tar.gz
(17.1 kB
view hashes)
Built Distribution
threefive-2.2.25-py3-none-any.whl
(16.2 kB
view hashes)
Close
Hashes for threefive-2.2.25-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 11166546e430837cd7f627242ffa45b2e12bc0f82701b77e8e212daca8ee7cd1 |
|
MD5 | 066e24b645a17e016ed850b036f759aa |
|
BLAKE2b-256 | 80bb5cdcaee7e601dc93304ccf9b4f3047eedc0c942b0c5ed6f29df66367db00 |