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.
Files changed (29) hide show
  1. {threefive-2.4.43/threefive.egg-info → threefive-2.4.45}/PKG-INFO +8 -11
  2. {threefive-2.4.43 → threefive-2.4.45}/README.md +7 -10
  3. {threefive-2.4.43 → threefive-2.4.45}/threefive/stream.py +38 -36
  4. {threefive-2.4.43 → threefive-2.4.45}/threefive/upids.py +6 -5
  5. {threefive-2.4.43 → threefive-2.4.45}/threefive/version.py +1 -1
  6. {threefive-2.4.43 → threefive-2.4.45/threefive.egg-info}/PKG-INFO +8 -11
  7. {threefive-2.4.43 → threefive-2.4.45}/LICENSE +0 -0
  8. {threefive-2.4.43 → threefive-2.4.45}/bin/threefive +0 -0
  9. {threefive-2.4.43 → threefive-2.4.45}/setup.cfg +0 -0
  10. {threefive-2.4.43 → threefive-2.4.45}/setup.py +0 -0
  11. {threefive-2.4.43 → threefive-2.4.45}/threefive/__init__.py +0 -0
  12. {threefive-2.4.43 → threefive-2.4.45}/threefive/base.py +0 -0
  13. {threefive-2.4.43 → threefive-2.4.45}/threefive/bitn.py +0 -0
  14. {threefive-2.4.43 → threefive-2.4.45}/threefive/commands.py +0 -0
  15. {threefive-2.4.43 → threefive-2.4.45}/threefive/crc.py +0 -0
  16. {threefive-2.4.43 → threefive-2.4.45}/threefive/cue.py +0 -0
  17. {threefive-2.4.43 → threefive-2.4.45}/threefive/decode.py +0 -0
  18. {threefive-2.4.43 → threefive-2.4.45}/threefive/descriptors.py +0 -0
  19. {threefive-2.4.43 → threefive-2.4.45}/threefive/encode.py +0 -0
  20. {threefive-2.4.43 → threefive-2.4.45}/threefive/packetdata.py +0 -0
  21. {threefive-2.4.43 → threefive-2.4.45}/threefive/section.py +0 -0
  22. {threefive-2.4.43 → threefive-2.4.45}/threefive/segment.py +0 -0
  23. {threefive-2.4.43 → threefive-2.4.45}/threefive/segmentation.py +0 -0
  24. {threefive-2.4.43 → threefive-2.4.45}/threefive/smoketest.py +0 -0
  25. {threefive-2.4.43 → threefive-2.4.45}/threefive/stuff.py +0 -0
  26. {threefive-2.4.43 → threefive-2.4.45}/threefive.egg-info/SOURCES.txt +0 -0
  27. {threefive-2.4.43 → threefive-2.4.45}/threefive.egg-info/dependency_links.txt +0 -0
  28. {threefive-2.4.43 → threefive-2.4.45}/threefive.egg-info/requires.txt +0 -0
  29. {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.43
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
- ![image](https://github.com/futzu/SCTE-35_threefive/assets/52701496/9439f55e-586e-4feb-8a73-4cdede53fac5)
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`.`43`
37
- * this is the 277th release of threefive
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
- ![image](https://github.com/futzu/SCTE-35_threefive/assets/52701496/9439f55e-586e-4feb-8a73-4cdede53fac5)
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`.`43`
21
- * this is the 277th release of threefive
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: "AAC LATM",
21
+ 0x11: "AAC LATM",
22
22
  0x15: "ID3 Timed Meta Data",
23
23
  0x1B: "AVC Video H.264",
24
- 0x1c: "AAC",
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
- 0xdb: "HLS Encrypted H.264",
36
- 0xcf: "HLS Encrypted AAC",
37
- 0xc1: "HLS Encrypted AC3",
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 = b"\x00\x00\x01\xfc"
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 = pkt[6] << 25
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: # and self.info:
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
- # if self._pcr_flag(pkt):
542
- # self._parse_pcr(pkt,pid)
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 = self.maps.last[pid]
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
- pre, post = seg_upid[3:].split("/", 1)
137
- nbin.add_int(int(pre), 16)
138
- nbin.add_hex(post.replace("-", ""), 80)
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):
@@ -2,4 +2,4 @@
2
2
  threefive.version
3
3
  from the cli tool run: threefive version
4
4
  """
5
- version='2.4.43'
5
+ version='2.4.45'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: threefive
3
- Version: 2.4.43
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
- ![image](https://github.com/futzu/SCTE-35_threefive/assets/52701496/9439f55e-586e-4feb-8a73-4cdede53fac5)
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`.`43`
37
- * this is the 277th release of threefive
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