threefive 2.4.43__tar.gz → 2.4.45__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-2.4.43/threefive.egg-info → threefive-2.4.45}/PKG-INFO +8 -11
- {threefive-2.4.43 → threefive-2.4.45}/README.md +7 -10
- {threefive-2.4.43 → threefive-2.4.45}/threefive/stream.py +38 -36
- {threefive-2.4.43 → threefive-2.4.45}/threefive/upids.py +6 -5
- {threefive-2.4.43 → threefive-2.4.45}/threefive/version.py +1 -1
- {threefive-2.4.43 → threefive-2.4.45/threefive.egg-info}/PKG-INFO +8 -11
- {threefive-2.4.43 → threefive-2.4.45}/LICENSE +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/bin/threefive +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/setup.cfg +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/setup.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/__init__.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/base.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/bitn.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/commands.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/crc.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/cue.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/decode.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/descriptors.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/encode.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/packetdata.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/section.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/segment.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/segmentation.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/smoketest.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive/stuff.py +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive.egg-info/SOURCES.txt +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive.egg-info/dependency_links.txt +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive.egg-info/requires.txt +0 -0
- {threefive-2.4.43 → threefive-2.4.45}/threefive.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: threefive
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.45
|
|
4
4
|
Summary: The Undisputed Heavyweight Champion of SCTE-35.
|
|
5
5
|
Home-page: https://github.com/futzu/threefive
|
|
6
6
|
Author: Adrian and a Cast of Thousands.
|
|
@@ -15,16 +15,8 @@ Description-Content-Type: text/markdown
|
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-

|
|
19
|
-
|
|
20
|
-
###
|
|
21
|
-
###
|
|
22
|
-
###
|
|
23
|
-
|
|
24
18
|
# threefive is the highest rated SCTE-35 parser. Ever.
|
|
25
19
|
|
|
26
|
-
<br>
|
|
27
|
-
|
|
28
20
|
|
|
29
21
|
<br> `Parses` __SCTE-35__ from multiple streams in `MPEGTS` and `Multiple Program Transport Streams`
|
|
30
22
|
<br> `Parses` __SCTE-35__ from Cues encoded in`Base64`, `Bytes`, `Hex`, `Integers`.
|
|
@@ -33,9 +25,14 @@ License-File: LICENSE
|
|
|
33
25
|
|
|
34
26
|
|
|
35
27
|
___
|
|
36
|
-
# Latest __threefive__ version is `2`.`4`.`
|
|
37
|
-
* this is the
|
|
28
|
+
# Latest __threefive__ version is `2`.`4`.`45`
|
|
29
|
+
* this is the 279th release of threefive
|
|
38
30
|
* Cyclomatic Complexity Score 1.99
|
|
31
|
+
* EIDR UPIDs are now in compact binary format
|
|
32
|
+
* Stream class now includes PCR timestamps
|
|
33
|
+
* Stream class now logs PAT, PMT, and SDT changes
|
|
34
|
+
* SCTE-35 PES Packets are now properly handled
|
|
35
|
+
|
|
39
36
|
---
|
|
40
37
|
|
|
41
38
|
|
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-

|
|
3
|
-
|
|
4
|
-
###
|
|
5
|
-
###
|
|
6
|
-
###
|
|
7
|
-
|
|
8
2
|
# threefive is the highest rated SCTE-35 parser. Ever.
|
|
9
3
|
|
|
10
|
-
<br>
|
|
11
|
-
|
|
12
4
|
|
|
13
5
|
<br> `Parses` __SCTE-35__ from multiple streams in `MPEGTS` and `Multiple Program Transport Streams`
|
|
14
6
|
<br> `Parses` __SCTE-35__ from Cues encoded in`Base64`, `Bytes`, `Hex`, `Integers`.
|
|
@@ -17,9 +9,14 @@
|
|
|
17
9
|
|
|
18
10
|
|
|
19
11
|
___
|
|
20
|
-
# Latest __threefive__ version is `2`.`4`.`
|
|
21
|
-
* this is the
|
|
12
|
+
# Latest __threefive__ version is `2`.`4`.`45`
|
|
13
|
+
* this is the 279th release of threefive
|
|
22
14
|
* Cyclomatic Complexity Score 1.99
|
|
15
|
+
* EIDR UPIDs are now in compact binary format
|
|
16
|
+
* Stream class now includes PCR timestamps
|
|
17
|
+
* Stream class now logs PAT, PMT, and SDT changes
|
|
18
|
+
* SCTE-35 PES Packets are now properly handled
|
|
19
|
+
|
|
23
20
|
---
|
|
24
21
|
|
|
25
22
|
|
|
@@ -18,10 +18,10 @@ streamtype_map = {
|
|
|
18
18
|
0x06: "PES Packets/Private Data",
|
|
19
19
|
0x0F: "AAC Audio",
|
|
20
20
|
0x10: "MPEG4",
|
|
21
|
-
0x11:
|
|
21
|
+
0x11: "AAC LATM",
|
|
22
22
|
0x15: "ID3 Timed Meta Data",
|
|
23
23
|
0x1B: "AVC Video H.264",
|
|
24
|
-
|
|
24
|
+
0x1C: "AAC",
|
|
25
25
|
0x20: "H264",
|
|
26
26
|
0x21: "JPEG2000",
|
|
27
27
|
0x24: "HEVC",
|
|
@@ -32,9 +32,9 @@ streamtype_map = {
|
|
|
32
32
|
0x84: "AAC HE v2 Audio",
|
|
33
33
|
0x86: "SCTE35 Data",
|
|
34
34
|
0xC0: "Unknown",
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
0xDB: "HLS Encrypted H.264",
|
|
36
|
+
0xCF: "HLS Encrypted AAC",
|
|
37
|
+
0xC1: "HLS Encrypted AC3",
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
|
|
@@ -156,7 +156,7 @@ class Stream:
|
|
|
156
156
|
_SDT_TID = SDT_TID = b"\x42"
|
|
157
157
|
ROLLOVER = 8589934591 # 95443.717678
|
|
158
158
|
ROLLOVER9K = 95443.717678
|
|
159
|
-
SCTE35_PES_START
|
|
159
|
+
SCTE35_PES_START = b"\x00\x00\x01\xfc"
|
|
160
160
|
|
|
161
161
|
def __init__(self, tsdata, show_null=True):
|
|
162
162
|
"""
|
|
@@ -316,13 +316,13 @@ class Stream:
|
|
|
316
316
|
displays streams that will be
|
|
317
317
|
parsed for SCTE-35.
|
|
318
318
|
"""
|
|
319
|
-
pkt_count =0
|
|
319
|
+
pkt_count = 0
|
|
320
320
|
self.info = True
|
|
321
321
|
while not self.maps.prgm.items():
|
|
322
322
|
data = self._tsdata.read(self.PACKET_SIZE * 100)
|
|
323
323
|
while data:
|
|
324
324
|
pkt = data[:188]
|
|
325
|
-
pkt_count +=1
|
|
325
|
+
pkt_count += 1
|
|
326
326
|
data = data[188:]
|
|
327
327
|
self._parse_info(pkt)
|
|
328
328
|
print2(f"Read {pkt_count} packets")
|
|
@@ -341,8 +341,8 @@ class Stream:
|
|
|
341
341
|
print2("PID , PTS")
|
|
342
342
|
for pkt in iter(partial(self._tsdata.read, self.PACKET_SIZE), b""):
|
|
343
343
|
self._parse(pkt)
|
|
344
|
-
pid = self._parse_pid(pkt[1],pkt[2])
|
|
345
|
-
if self.pcr_pid_pts(pkt,pid):
|
|
344
|
+
pid = self._parse_pid(pkt[1], pkt[2])
|
|
345
|
+
if self.pcr_pid_pts(pkt, pid):
|
|
346
346
|
_ = {
|
|
347
347
|
print2(f"{pid} , {self.as_90k(pts)}")
|
|
348
348
|
for pgrm, pts in self.maps.prgm_pts.items()
|
|
@@ -393,7 +393,7 @@ class Stream:
|
|
|
393
393
|
# uses pay not pkt
|
|
394
394
|
return pay[7] & 0x80
|
|
395
395
|
|
|
396
|
-
def pcr_pid_pts(self,pkt,pid):
|
|
396
|
+
def pcr_pid_pts(self, pkt, pid):
|
|
397
397
|
"""
|
|
398
398
|
If it has pts and it's the pcr_pid,
|
|
399
399
|
return True
|
|
@@ -438,7 +438,7 @@ class Stream:
|
|
|
438
438
|
last_cc = self.maps.pid_cc[pid]
|
|
439
439
|
good = (last_cc, ((last_cc + 1) % 16))
|
|
440
440
|
if c_c not in good:
|
|
441
|
-
print2(f"BAD --> pid:\t{hex(pid)}\tlast cc:\t{last_cc}\tcc:\t{c_c}")
|
|
441
|
+
print2(f" # BAD --> pid:\t{hex(pid)}\tlast cc:\t{last_cc}\tcc:\t{c_c}")
|
|
442
442
|
self.maps.pid_cc[pid] = c_c
|
|
443
443
|
|
|
444
444
|
def _parse_pts(self, pkt, pid):
|
|
@@ -465,9 +465,9 @@ class Stream:
|
|
|
465
465
|
"""
|
|
466
466
|
return self.maps.prgm_pts
|
|
467
467
|
|
|
468
|
-
def _parse_pcr(self,pkt,pid):
|
|
468
|
+
def _parse_pcr(self, pkt, pid):
|
|
469
469
|
if self._afc_flag(pkt[3]):
|
|
470
|
-
pcr
|
|
470
|
+
pcr = pkt[6] << 25
|
|
471
471
|
pcr |= pkt[7] << 17
|
|
472
472
|
pcr |= pkt[8] << 9
|
|
473
473
|
pcr |= pkt[9] << 1
|
|
@@ -475,13 +475,12 @@ class Stream:
|
|
|
475
475
|
prgm = self.pid2prgm(pid)
|
|
476
476
|
self.maps.prgm_pcr[prgm] = pcr
|
|
477
477
|
|
|
478
|
-
|
|
479
|
-
def _unpad_afc(self,pkt):
|
|
478
|
+
def _unpad_afc(self, pkt):
|
|
480
479
|
if self._afc_flag(pkt[3]):
|
|
481
|
-
pkt= pkt[:4] + self._unpad(pkt[4:])
|
|
480
|
+
pkt = pkt[:4] + self._unpad(pkt[4:])
|
|
482
481
|
return pkt
|
|
483
482
|
|
|
484
|
-
def _unpad(self,bites):
|
|
483
|
+
def _unpad(self, bites):
|
|
485
484
|
pad = 255
|
|
486
485
|
one = 1
|
|
487
486
|
while bites[0] in [pad]:
|
|
@@ -499,10 +498,10 @@ class Stream:
|
|
|
499
498
|
head_size += afl + 1 # +1 for afl byte
|
|
500
499
|
return pkt[head_size:]
|
|
501
500
|
|
|
502
|
-
def _changed(self,what,pid):
|
|
501
|
+
def _changed(self, what, pid):
|
|
503
502
|
pts = self.pid2pts(pid)
|
|
504
503
|
if pts:
|
|
505
|
-
effed = f"\n{what} changed @ {pts}\n"
|
|
504
|
+
effed = f"\n# {what} changed @ {pts}\n"
|
|
506
505
|
print2(effed)
|
|
507
506
|
|
|
508
507
|
def _parse_tables(self, pkt, pid):
|
|
@@ -515,15 +514,16 @@ class Stream:
|
|
|
515
514
|
if self._same_as_last(pay, pid):
|
|
516
515
|
return False
|
|
517
516
|
if pid in self.pids.pmt:
|
|
518
|
-
self._changed("PMT",pid)
|
|
517
|
+
self._changed("PMT", pid)
|
|
519
518
|
return self._parse_pmt(pay, pid)
|
|
520
519
|
if pid == self.pids.PAT_PID:
|
|
521
|
-
self._changed("PAT",pid)
|
|
520
|
+
self._changed("PAT", pid)
|
|
522
521
|
return self._parse_pat(pay)
|
|
523
|
-
if pid == self.pids.SDT_PID:
|
|
524
|
-
self._changed("SDT",pid)
|
|
522
|
+
if pid == self.pids.SDT_PID: # and self.info:
|
|
523
|
+
self._changed("SDT", pid)
|
|
525
524
|
return self._parse_sdt(pay)
|
|
526
525
|
return False
|
|
526
|
+
|
|
527
527
|
def _parse_info(self, pkt):
|
|
528
528
|
"""
|
|
529
529
|
_parse_info parses the packet for tables
|
|
@@ -537,10 +537,10 @@ class Stream:
|
|
|
537
537
|
def _parse(self, pkt):
|
|
538
538
|
cue = False
|
|
539
539
|
pid = self._parse_info(pkt)
|
|
540
|
-
#self._parse_cc(pkt, pid)
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
if self.pcr_pid_pts(pkt,pid):
|
|
540
|
+
# self._parse_cc(pkt, pid)
|
|
541
|
+
if self._pcr_flag(pkt):
|
|
542
|
+
self._parse_pcr(pkt, pid)
|
|
543
|
+
if self.pcr_pid_pts(pkt, pid):
|
|
544
544
|
self._parse_pts(pkt, pid)
|
|
545
545
|
if pid in self.pids.scte35:
|
|
546
546
|
cue = self._parse_scte35(pkt, pid)
|
|
@@ -552,9 +552,9 @@ class Stream:
|
|
|
552
552
|
return self._split_by_idx(pay, sep)
|
|
553
553
|
|
|
554
554
|
def _same_as_last(self, pay, pid):
|
|
555
|
-
old =
|
|
555
|
+
old = ""
|
|
556
556
|
if pid in self.maps.last:
|
|
557
|
-
old
|
|
557
|
+
old = self.maps.last[pid]
|
|
558
558
|
self.maps.last[pid] = pay
|
|
559
559
|
return old == self.maps.last[pid]
|
|
560
560
|
|
|
@@ -573,6 +573,13 @@ class Stream:
|
|
|
573
573
|
return cue
|
|
574
574
|
return False
|
|
575
575
|
|
|
576
|
+
def _strip_scte35_pes(self, pay, pid):
|
|
577
|
+
if self.SCTE35_PES_START in pay:
|
|
578
|
+
print2(f"# Stripping PES Header from SCTE35 @ {self.pid2pts(pid)}")
|
|
579
|
+
pay = pay.split(self.SCTE35_PES_START, 1)[1]
|
|
580
|
+
pay = self._split_by_idx(pay, self.SCTE35_TID)
|
|
581
|
+
return pay
|
|
582
|
+
|
|
576
583
|
def _parse_scte35(self, pkt, pid):
|
|
577
584
|
"""
|
|
578
585
|
parse a scte35 cue from one or more packets
|
|
@@ -580,6 +587,7 @@ class Stream:
|
|
|
580
587
|
if self.the_scte35_pids and pid not in self.the_scte35_pids:
|
|
581
588
|
return False
|
|
582
589
|
pay = self._parse_payload(pkt)
|
|
590
|
+
pay = self._strip_scte35_pes(pay, pid)
|
|
583
591
|
if not pay:
|
|
584
592
|
return False
|
|
585
593
|
pay = self._chk_partial(pay, pid, self.SCTE35_TID)
|
|
@@ -588,15 +596,9 @@ class Stream:
|
|
|
588
596
|
return False
|
|
589
597
|
if pay[13] == self.show_null:
|
|
590
598
|
return False
|
|
591
|
-
split = pay.split(self.SCTE35_TID)
|
|
592
|
-
pay = self.SCTE35_TID+split[-1]
|
|
593
|
-
|
|
594
599
|
seclen = self._parse_length(pay[1], pay[2])
|
|
595
600
|
if self._section_incomplete(pay, pid, seclen):
|
|
596
601
|
return False
|
|
597
|
-
pay = self.SCTE35_TID+split[-1]
|
|
598
|
-
if len(pay) <3:
|
|
599
|
-
return False
|
|
600
602
|
pay = pay[: seclen + 3]
|
|
601
603
|
cue = self._parse_cue(pay, pid)
|
|
602
604
|
return cue
|
|
@@ -118,8 +118,6 @@ class Eidr(Upid):
|
|
|
118
118
|
"""
|
|
119
119
|
decode Eidr Upid
|
|
120
120
|
"""
|
|
121
|
-
# if self.upid_length != 12:
|
|
122
|
-
# return f"upid_length is {self.upid_length} should be 12 bytes."
|
|
123
121
|
pre = self.bitbin.as_hex(16)
|
|
124
122
|
post = []
|
|
125
123
|
# switch to compact binary format
|
|
@@ -133,9 +131,12 @@ class Eidr(Upid):
|
|
|
133
131
|
"""
|
|
134
132
|
encode Eidr Upid
|
|
135
133
|
"""
|
|
136
|
-
|
|
137
|
-
nbin.
|
|
138
|
-
|
|
134
|
+
# switch to compact binary format
|
|
135
|
+
nbin.add_hex(seg_upid[:6], 16)
|
|
136
|
+
substring = seg_upid[6:]
|
|
137
|
+
for i in substring:
|
|
138
|
+
hexed = f"0x{i}"
|
|
139
|
+
nbin.add_hex(hexed, 4)
|
|
139
140
|
|
|
140
141
|
|
|
141
142
|
class Isan(Upid):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: threefive
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.45
|
|
4
4
|
Summary: The Undisputed Heavyweight Champion of SCTE-35.
|
|
5
5
|
Home-page: https://github.com/futzu/threefive
|
|
6
6
|
Author: Adrian and a Cast of Thousands.
|
|
@@ -15,16 +15,8 @@ Description-Content-Type: text/markdown
|
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-

|
|
19
|
-
|
|
20
|
-
###
|
|
21
|
-
###
|
|
22
|
-
###
|
|
23
|
-
|
|
24
18
|
# threefive is the highest rated SCTE-35 parser. Ever.
|
|
25
19
|
|
|
26
|
-
<br>
|
|
27
|
-
|
|
28
20
|
|
|
29
21
|
<br> `Parses` __SCTE-35__ from multiple streams in `MPEGTS` and `Multiple Program Transport Streams`
|
|
30
22
|
<br> `Parses` __SCTE-35__ from Cues encoded in`Base64`, `Bytes`, `Hex`, `Integers`.
|
|
@@ -33,9 +25,14 @@ License-File: LICENSE
|
|
|
33
25
|
|
|
34
26
|
|
|
35
27
|
___
|
|
36
|
-
# Latest __threefive__ version is `2`.`4`.`
|
|
37
|
-
* this is the
|
|
28
|
+
# Latest __threefive__ version is `2`.`4`.`45`
|
|
29
|
+
* this is the 279th release of threefive
|
|
38
30
|
* Cyclomatic Complexity Score 1.99
|
|
31
|
+
* EIDR UPIDs are now in compact binary format
|
|
32
|
+
* Stream class now includes PCR timestamps
|
|
33
|
+
* Stream class now logs PAT, PMT, and SDT changes
|
|
34
|
+
* SCTE-35 PES Packets are now properly handled
|
|
35
|
+
|
|
39
36
|
---
|
|
40
37
|
|
|
41
38
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|