-
Notifications
You must be signed in to change notification settings - Fork 30
I am relatively new to Python programming so forgive my ignorance, but I am using the code from the test file '35.py':
`import sys
import threefive
if name == "main":
if len(sys.argv) > 1:
arg = sys.argv[1]
else:
arg = sys.stdin.buffer
strm = threefive.Stream(arg)
strm.decode()`
This works for me in that when passing a .ts file as a command line argument I get SCTE35 decoded and printed back to screen, however the output that comes back that I am writing into my textfile is not valid JSON. This is because there are no commas between successive objects. I have tried using sed and regex to wrangle some commas into those gaps, as well as trying to use the get_json function as part of threefive but cannot get this to work. This is an example of what I get back right now:
{ "info_section": { "table_id": "0xfc", "section_syntax_indicator": false, "private": false, "sap_type": "0x3", "sap_details": "No Sap Type", "section_length": 17, "protocol_version": 0, "encrypted_packet": false, "encryption_algorithm": 0, "pts_adjustment_ticks": 0, "pts_adjustment": 0.0, "cw_index": "0x0", "tier": "0xfff", "splice_command_length": 0, "splice_command_type": 7, "descriptor_loop_length": 0, "crc": "0x7f44f86a" }, "command": { "command_length": 0, "command_type": 7, "name": "Bandwidth Reservation" }, "descriptors": [], "packet_data": { "pid": "0x97e", "program": 140, "pts_ticks": 560784705, "pts": 6230.941167 } } { "info_section": { "table_id": "0xfc", "section_syntax_indicator": false, "private": false, "sap_type": "0x3", "sap_details": "No Sap Type", "section_length": 17, "protocol_version": 0, "encrypted_packet": false, "encryption_algorithm": 0, "pts_adjustment_ticks": 0, "pts_adjustment": 0.0, "cw_index": "0x0", "tier": "0xfff", "splice_command_length": 0, "splice_command_type": 7, "descriptor_loop_length": 0, "crc": "0x7f44f86a" }, "command": { "command_length": 0, "command_type": 7, "name": "Bandwidth Reservation" }, "descriptors": [], "packet_data": { "pid": "0x97e", "program": 140, "pts_ticks": 560784705, "pts": 6230.941167 } }
What I would like is for there to be a comma in the space between the two objects:
{ "info_section": { "table_id": "0xfc", "section_syntax_indicator": false, "private": false, "sap_type": "0x3", "sap_details": "No Sap Type", "section_length": 17, "protocol_version": 0, "encrypted_packet": false, "encryption_algorithm": 0, "pts_adjustment_ticks": 0, "pts_adjustment": 0.0, "cw_index": "0x0", "tier": "0xfff", "splice_command_length": 0, "splice_command_type": 7, "descriptor_loop_length": 0, "crc": "0x7f44f86a" }, "command": { "command_length": 0, "command_type": 7, "name": "Bandwidth Reservation" }, "descriptors": [], "packet_data": { "pid": "0x97e", "program": 140, "pts_ticks": 560784705, "pts": 6230.941167 } }, <-- comma here
{ "info_section": { "table_id": "0xfc", "section_syntax_indicator": false, "private": false, "sap_type": "0x3", "sap_details": "No Sap Type", "section_length": 17, "protocol_version": 0, "encrypted_packet": false, "encryption_algorithm": 0, "pts_adjustment_ticks": 0, "pts_adjustment": 0.0, "cw_index": "0x0", "tier": "0xfff", "splice_command_length": 0, "splice_command_type": 7, "descriptor_loop_length": 0, "crc": "0x7f44f86a" }, "command": { "command_length": 0, "command_type": 7, "name": "Bandwidth Reservation" }, "descriptors": [], "packet_data": { "pid": "0x97e", "program": 140, "pts_ticks": 560784705, "pts": 6230.941167 } }
All reactions
Replies: 14 comments 13 replies
Generally, you process cues individually when they are found, it is not meant to return a collection of cues.
You can change that if you feel the need.
threefive.Stream.decode() can accept a function to be run when a cue is found.
cut and paste this into myfile.py
#!/usr/bin/env python3 import json import sys from threefive import Stream cue_list = [] def add_cue(cue): cue_list.append(cue.get()) if __name__== '__main__': strm = Stream(sys.argv[1]) strm.decode(func=add_cue) print(json.dumps(cue_list))
then do
python3 myfile.py video.ts
and it will print it all together.
All reactions
-
👍 1
if you prefer using sed, this will add commas
sed -e '2,$s/^{/,{/' test.json
All reactions
@A-Snell
Talk to me Goose, did that fix it for you?
All reactions
All reactions
Closing the loop and asking one more thing...
Firstly, here's the output I settled on:
import json
import sys
from threefive import Stream
cue_list = []
def add_cue(cue):
cue_list.append(cue.get())
if __name__== '__main__':
strm = Stream(sys.argv[1])
filename=sys.argv[1]
print("strm File: "+str(filename))
strm.decode(func=add_cue)
jsonForFile=(json.dumps((cue_list), indent=4))
print("JSON: "+str(jsonForFile))
if jsonForFile and len(jsonForFile) >= 10:
with open(str(filename)+"-SCTE-35-DECODE.json", "w") as myfile:
myfile.write(str(jsonForFile))
myfile.close
else:
with open(str(filename)+"-SCTE-35-DECODE.json", "w") as myfile:
myfile.write(str("DID NOT FIND ANY SCTE DATA IN THE CAPTURE"))
myfile.close
And the question: I have run MPTS' through this and am getting a lot of PIDs I don't care about. Is there a way to filter the parsing to only look at a specific PID or to only display a PID I care about natively? If not then I'll likely just run the JSON through JQ and do a search and remove that way. Thanks!
All reactions
Use the python shell, this is good python thing to know
a@debian:~/build/clean/clean/clean/scte35-threefive$ pypy3 Python 3.9.16 (7.3.11+dfsg-2, Feb 06 2023, 16:52:03) [PyPy 7.3.11 with GCC 12.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>>> from threefive import Stream >>>> help(Stream) # this will show you all the methods and vars in the Stream class >>>> help(Stream.decode_program) # You can also specify a particular method Help on function decode_program in module threefive.stream: decode_program(self, the_program, func=show_cue) Stream.decode_program limits SCTE35 parsing to a specific MPEGTS program.
So you can specify a program to parse and ignore the others.
use Stream.show to see the Programs.
>>>> from threefive import Stream >>>> st = Stream("/home/a/mpegts/plp0.ts") >>>> st.show() Program: 1010 # A Program Number Service: 01 Provider: Pid: 1010 Pcr Pid: 1011 Streams: # PIDS in this program Pid: 1011[0x3f3] Type: 0x1b AVC Video Pid: 1012[0x3f4] Type: 0x3 Unknown Pid: 1014[0x3f6] Type: 0x6 Unknown Pid: 1015[0x3f7] Type: 0x86 SCTE35 Data Program: 1030 # Another Program Number. Service: 03 Provider: Pid: 1030 Pcr Pid: 1031 Streams: # Pids in this Program Pid: 1031[0x407] Type: 0x1b AVC Video Pid: 1032[0x408] Type: 0x3 Unknown Pid: 1034[0x40a] Type: 0x6 Unknown Pid: 1035[0x40b] Type: 0x86 SCTE35 Data
call Strrean.decode_proxy wit h the program that contains the pid you want to parse
>>>> from threefive import Stream >>>> st =Stream("/home/a/mpegts/plp0.ts") >>>> st.decode_program(the_program=1010) # Parse the Prgram 1010 that has SCTE-35 in Pid 1015
All reactions
try it like this
#!/usr/bin/env python3 import json import sys from threefive import Stream cue_list = [] def add_cue(cue): cue_list.append(cue.get()) def get_args(): filename = None if len(sys.argv) > 1: filename = sys.argv[1] the_program = 1 # 1 is the default Program if len(sys.argv) > 2: the_program = int(sys.argv[2]) # Second arg is the_program return filename, the_program def get_json(filename, the_program): strm = Stream(filename) print(f"strm File: {filename}") # f-strings are super cool strm.decode_program(the_program=the_program, func=add_cue) jsonForFile = json.dumps((cue_list), indent=4) print(f"JSON: {jsonForFile}") return jsonForFile def write_json(filename, data): err_mesg = "DID NOT FIND ANY SCTE DATA IN THE CAPTURE for Program {the_program}" if len(data) < 10: data = err_mesg if "/" in filename: filename = filename.rsplit("/", 1)[1] outfile = f"{filename}-SCTE-35-DECODE.json" # f-strings are super cool with open(outfile, "w") as myfile: myfile.write(data) # myfile.close() is not needed if you use "with" if __name__ == "__main__": filename, the_program = get_args() data = get_json(filename, the_program) write_json(filename, data)
All reactions
run it like with the video and program as args.
python3 this.py video.ts 1010
All reactions
Thanks very much Adrian. I was able to get that sample working, however for my purposes there are sometimes multiple SCTE 35 PIDs in a single program, so I have ended up parsing all and then using jq to go in afterwards and strip out all of the info_sections that match my selected PID. Which is a little bit inefficient but it works. Using your program selection method here is not going to be precise enough for my use case.
Something else I noticed last week when running this was the packet_data/pts_ticks field was not accurate for the two capture files I was running it against. For the first of the files, the values did not make sense. Packet 1 and 3 are correct in the context of the stream, but the rest of the PTS values seem to be way off:
cat capture1.ts-SCTE-35-DECODE-PID-0x1b.json | jq -r '.packet_data.pts_ticks' 6060070106 4064427735 6073052997 8589934479 4064461769 2990719945 2990719945 4295001476
And for the 2nd capture, the time_signal messages were all the same value (4194303) and the splice_inserts 4095:
cat capture2.ts-SCTE-35-DECODE-PID-0x100.json | jq -r '.packet_data.pts_ticks' 4194303 4095 4194303 4194303 4095 4194303 4194303 4194303
Not sure if this looks familiar at all.
All reactions
Here are some sections from that first file:
{ "info_section": { "table_id": "0xfc", "section_syntax_indicator": false, "private": false, "sap_type": "0x3", "sap_details": "No Sap Type", "section_length": 57, "protocol_version": 0, "encrypted_packet": false, "encryption_algorithm": 0, "pts_adjustment_ticks": 0, "pts_adjustment": 0, "cw_index": "0x0", "tier": "0xfff", "splice_command_length": 5, "splice_command_type": 6, "descriptor_loop_length": 35, "crc": "0x8ecb90ea" }, "command": { "command_length": 5, "command_type": 6, "name": "Time Signal", "time_specified_flag": true, "pts_time": 67337.315489, "pts_time_ticks": 6060358394 }, "descriptors": [ { "tag": 2, "descriptor_length": 33, "name": "Segmentation Descriptor", "identifier": "CUEI", "components": [], "segmentation_event_id": "0xdce93", "segmentation_event_cancel_indicator": false, "program_segmentation_flag": true, "segmentation_duration_flag": true, "delivery_not_restricted_flag": true, "segmentation_duration": 150.133467, "segmentation_duration_ticks": 13512012, "segmentation_message": "Provider Advertisement Start", "segmentation_upid_type": 12, "segmentation_upid_type_name": "MPU", "segmentation_upid_length": 13, "segmentation_upid": { "format_identifier": 825767736, "private_data": "0x36395f3030335f3031" }, "segmentation_type_id": 48, "segment_num": 1, "segments_expected": 1 } ], "packet_data": { "pid": "0x1b", "program": 1, "pts_ticks": 6060070106, "pts": 67334.112289 } } { "info_section": { "table_id": "0xfc", "section_syntax_indicator": false, "private": false, "sap_type": "0x3", "sap_details": "No Sap Type", "section_length": 49, "protocol_version": 0, "encrypted_packet": false, "encryption_algorithm": 0, "pts_adjustment_ticks": 0, "pts_adjustment": 0, "cw_index": "0x0", "tier": "0x1", "splice_command_length": 20, "splice_command_type": 5, "descriptor_loop_length": 12, "crc": "0xcbdd9818" }, "command": { "command_length": 20, "command_type": 5, "name": "Splice Insert", "time_specified_flag": true, "pts_time": 67483.458156, "pts_time_ticks": 6073511234, "break_auto_return": true, "break_duration": 600, "break_duration_ticks": 54000000, "splice_event_id": 3221225476, "splice_event_cancel_indicator": false, "out_of_network_indicator": true, "program_splice_flag": true, "duration_flag": true, "splice_immediate_flag": false, "unique_program_id": 0, "avail_num": 0, "avail_expected": 0 }, "descriptors": [ { "tag": 1, "descriptor_length": 10, "name": "DTMF Descriptor", "identifier": "CUEI", "preroll": 0, "dtmf_count": 4, "dtmf_chars": [ "4", "9", "4", "*" ] } ], "packet_data": { "pid": "0x1b", "program": 1, "pts_ticks": 4064427735, "pts": 45160.308167 } } { "info_section": { "table_id": "0xfc", "section_syntax_indicator": false, "private": false, "sap_type": "0x3", "sap_details": "No Sap Type", "section_length": 53, "protocol_version": 0, "encrypted_packet": false, "encryption_algorithm": 0, "pts_adjustment_ticks": 0, "pts_adjustment": 0, "cw_index": "0x0", "tier": "0xfff", "splice_command_length": 5, "splice_command_type": 6, "descriptor_loop_length": 31, "crc": "0x8dbbd665" }, "command": { "command_length": 5, "command_type": 6, "name": "Time Signal", "time_specified_flag": true, "pts_time": 67483.461489, "pts_time_ticks": 6073511534 }, "descriptors": [ { "tag": 2, "descriptor_length": 29, "name": "Segmentation Descriptor", "identifier": "CUEI", "components": [], "segmentation_event_id": "0xdceee", "segmentation_event_cancel_indicator": false, "program_segmentation_flag": true, "segmentation_duration_flag": true, "delivery_not_restricted_flag": true, "segmentation_duration": 60.033367, "segmentation_duration_ticks": 5403003, "segmentation_message": "Distributor Advertisement Start", "segmentation_upid_type": 12, "segmentation_upid_type_name": "MPU", "segmentation_upid_length": 9, "segmentation_upid": { "format_identifier": 1768843365, "private_data": "0x7269746564" }, "segmentation_type_id": 50, "segment_num": 1, "segments_expected": 1 } ], "packet_data": { "pid": "0x1b", "program": 1, "pts_ticks": 6073052997, "pts": 67478.366633 } }
All reactions
Hang on , let me try something for you.
All reactions
try this:
python3 -mpip install --upgrade threefive
try this 35.py like
python3 35.py video.ts 100 101 103
100 101 and 103 are the scte-35 pids you want to parse. If no pids are listed all pids are parsed.
- 35.py
#!/usr/bin/env python3 import json import sys from threefive import Stream cue_list = [] def add_cue(cue): cue_list.append(cue.get()) def get_args(): filename = None scte35_pids=[] if len(sys.argv) > 1: filename = sys.argv[1] if len(sys.argv) > 2: hexed = False for i in sys.argv[2:]: if i.startswith("0x") or i.startswith("0x"): hexed =True if hexed: scte35_pids = [int(i,16) for i in sys.argv[2:]] else: scte35_pids =[int(str(i)) for i in sys.argv[2:]] return filename,scte35_pids def get_json(filename, scte35_pids): strm = Stream(filename) print(f"strm File: {filename}") # f-strings are super cool print(f'SCTE-35 Pids: {scte35_pids}') strm.decode_pids(scte35_pids=scte35_pids, func=add_cue) jsonForFile = json.dumps((cue_list), indent=4) print(f"JSON: {jsonForFile}") return jsonForFile def write_json(filename, data,scte35_pids): err_mesg = f"DID NOT FIND ANY SCTE DATA IN THE CAPTURE for Pids {scte35_pids}" if len(data) < 10: data = err_mesg if "/" in filename: filename = filename.rsplit("/", 1)[1] outfile = f"{filename}-SCTE-35-DECODE.json" # f-strings are super cool with open(outfile, "w") as myfile: myfile.write(data) # myfile.close() is not needed if you use "with" if __name__ == "__main__": filename, scte35_pids = get_args() data = get_json(filename, scte35_pids) write_json(filename, data,scte35_pids)
All reactions
Hey Adrian, this worked exactly as designed, thanks so much for deploying this so quickly. I am almost certain I will not be the only person that benefits from this.
All reactions
How did it go?
All reactions
Sorry, I was travelling over the weekend, I will try to test this before the end of the week Adrian. Cheers!
All reactions
Also curious if you have any thoughts on the pts_time being well off from reality that threeFive is writing for each info_section?
All reactions
Also curious if you have any thoughts on the pts_time being well off from reality that threeFive is writing for each info_section?
huh?
All reactions
Are you talking about the in the pts from the packet data and pts from the splice command?
"command": { "command_length": 5, "command_type": 6, "name": "Time Signal", "time_specified_flag": true, "pts_time": 67483.461489, "pts_time_ticks": 6073511534 }, "packet_data": { "pid": "0x1b", "program": 1, "pts_ticks": 6073052997, "pts": 67478.366633 } }
Generally SCTE-35 packets are added 4 seconds before the actual splice time.
The packet was inserted at 67478.366633 for the splice at 67483.461489, that's normal.
Keep in mind, that PTS values are hard-coded in the SCTE-35, meaning that if you re-encode and change your PTS, , the SCTE-35 PTS does NOT update. In my opinion, that is a major flaw in the spec.
( ffmpeg restamps the PTS unless you include the -copyts switch)
All reactions
My question was that of the pts_ticks field in the packet_data that you have copied above:
"packet_data": { "pid": "0x1b", "program": 1, "pts_ticks": 6073052997, "pts": 67478.366633 } }
My point was that for a couple of the info_sections in my decode, the value here seems to be correct, but the software is mis-reading the value for all other info sections. I.e. the value in this field is way off of the value in the actual SCTE 35 pts_time field, which makes the prerolls seem to be extremely long (like hours).
All of this does raise a good question - how does this field get populated? Do you just find the nearest video packet and grab the PTS from there? Or is it computing a value using some other logic?
Thanks again,
Alex
All reactions
The field is not populated, it's parsed from your SCTE-35 You may have the wrong values in it, but I assure you, threefive is not reading it incorrectly.
As I explained in my last comment,
Keep in mind, that PTS values are hard-coded in the SCTE-35, meaning that if you re-encode the video and change your PTS, , the SCTE-35 PTS does NOT update. In my opinion, that is a major flaw in the spec.
( ffmpeg restamps the PTS unless you include the -copyts switch)
All reactions
Are you talking about like this one ?
{ "info_section": { "table_id": "0xfc", "section_syntax_indicator": false, "private": false, "sap_type": "0x3", "sap_details": "No Sap Type", "section_length": 49, "protocol_version": 0, "encrypted_packet": false, "encryption_algorithm": 0, "pts_adjustment_ticks": 0, "pts_adjustment": 0, "cw_index": "0x0", "tier": "0x1", "splice_command_length": 20, "splice_command_type": 5, "descriptor_loop_length": 12, "crc": "0xcbdd9818" }, "command": { "command_length": 20, "command_type": 5, "name": "Splice Insert", "time_specified_flag": true,
"pts_time": 67483.458156,
"pts_time_ticks": 6073511234, "break_auto_return": true, "break_duration": 600, "break_duration_ticks": 54000000, "splice_event_id": 3221225476, "splice_event_cancel_indicator": false, "out_of_network_indicator": true, "program_splice_flag": true, "duration_flag": true, "splice_immediate_flag": false, "unique_program_id": 0, "avail_num": 0, "avail_expected": 0 }, "descriptors": [ { "tag": 1, "descriptor_length": 10, "name": "DTMF Descriptor", "identifier": "CUEI", "preroll": 0, "dtmf_count": 4, "dtmf_chars": [ "4", "9", "4", "*" ] } ], "packet_data": { "pid": "0x1b", "program": 1, "pts_ticks": 4064427735, "pts": 45160.308167 } }
- Make sure you are using the latest threefive, 2.3.91 I think.
All reactions
I was talking about the highlighted fields yes. You can see in my example how far off of each other those PTS' are in adjacent packets, which is not consistent with the PTS of the actual TS.
My comment was that this is often inconsistent and I was wondering if you knew why. I will have to update threeFive on the server that hosts it (can take some effort, it is air-gapped in BAU) and let you know how I get on.
Thanks for your assistance here Adrian.
All reactions
Of course you have to update your system, I added code specifically for you.
I could be several different things causing that.
Update your system and then verify that threefive is the issue before you bring it to me.
All reactions
Thanks, yes I have got it loaded locally where I can test (WSL/Ubuntu).
I have updated my version:
~/dev/ts-tools$ python3 -mpip install --upgrade threefive
Requirement already up-to-date: threefive in /home/asnell/.local/lib/python3.8/site-packages (2.3.91)
Requirement already satisfied, skipping upgrade: new-reader>=0.1.7 in /home/asnell/.local/lib/python3.8/site-packages (from threefive) (0.1.7)
Requirement already satisfied, skipping upgrade: pyaes in /home/asnell/.local/lib/python3.8/site-packages (from threefive) (1.6.1)
And run it against a captured TS, where threeFive-testing.py is a direct copy from your previous comment (#74 (comment))
The JSON that comes out of that command has PTS values that make sense in the pts_time_ticks field specifically in all cases. \
Here is the list of the fields in question for the segmentation_messages in this break:
Provider Advertisement End
pts_time_ticks: 282310529
pts_time: 281502279
Distributor Advertisement Start
pts_time_ticks: 282310529
pts_time: 281862279
Provider Placement Opportunity Start
pts_time_ticks: 282310529
pts_time: 6212051315
Provider Placement Opportunity End
pts_time_ticks: 287715929
pts_time: 7516194565
Distributor Advertisement End
pts_time_ticks: 287715929
pts_time: 287177351
Provider Advertisement Start
pts_time_ticks: 287715929
pts_time: 287418631
Provider Advertisement End
pts_time_ticks: 289067279
pts_time: 288257352
Break End
pts_time_ticks: 289067279
pts_time: 288766978
Chapter Start
pts_time_ticks: 289067279
pts_time: 6212017281
If I look at the pts_ticks field data for each message compared to the pts_time_ticks field, they all look relatively close (3-10 seconds or so when converted, which is the pre-roll) apart from a couple. For example, the "Provider Placement Opportunity Start" message:
{
"info_section": {
"table_id": "0xfc",
"section_syntax_indicator": false,
"private": false,
"sap_type": "0x3",
"sap_details": "No Sap Type",
"section_length": 59,
"protocol_version": 0,
"encrypted_packet": false,
"encryption_algorithm": 0,
"pts_adjustment_ticks": 0,
"pts_adjustment": 0.0,
"cw_index": "0x0",
"tier": "0xfff",
"splice_command_length": 5,
"splice_command_type": 6,
"descriptor_loop_length": 37,
"crc": "0x201ad0b4"
},
"command": {
"command_length": 5,
"command_type": 6,
"name": "Time Signal",
"time_specified_flag": true,
"pts_time": 3136.783656,
"pts_time_ticks": 282310529
},
"descriptors": [
{
"tag": 2,
"descriptor_length": 35,
"name": "Segmentation Descriptor",
"identifier": "CUEI",
"components": [],
"segmentation_event_id": "0x6403fe",
"segmentation_event_cancel_indicator": false,
"program_segmentation_flag": true,
"segmentation_duration_flag": true,
"delivery_not_restricted_flag": true,
"segmentation_duration": 60.0,
"segmentation_duration_ticks": 5400000,
"segmentation_message": "Provider Placement Opportunity Start",
"segmentation_upid_type": 12,
"segmentation_upid_type_name": "MPU",
"segmentation_upid_length": 15,
"segmentation_upid": {
"format_identifier": 1145656131,
"private_data": "0x4c57554743443141313548"
},
"segmentation_type_id": 52,
"segment_num": 1,
"segments_expected": 1,
"sub_segment_num": 0,
"sub_segments_expected": 0
}
],
"packet_data": {
"pid": "0x1b",
"program": 1,
"pts_ticks": 6212051315,
"pts": 69022.792389
}
}
And the last message is a chapter start for the start of the segment after the break. Look at the two PTS fields here:
{
"info_section": {
"table_id": "0xfc",
"section_syntax_indicator": false,
"private": false,
"sap_type": "0x3",
"sap_details": "No Sap Type",
"section_length": 69,
"protocol_version": 0,
"encrypted_packet": false,
"encryption_algorithm": 0,
"pts_adjustment_ticks": 0,
"pts_adjustment": 0.0,
"cw_index": "0x0",
"tier": "0xfff",
"splice_command_length": 5,
"splice_command_type": 6,
"descriptor_loop_length": 47,
"crc": "0x53ce239d"
},
"command": {
"command_length": 5,
"command_type": 6,
"name": "Time Signal",
"time_specified_flag": true,
"pts_time": 3211.858656,
"pts_time_ticks": 289067279
},
"descriptors": [
{
"tag": 2,
"descriptor_length": 45,
"name": "Segmentation Descriptor",
"identifier": "CUEI",
"components": [],
"segmentation_event_id": "0x640425",
"segmentation_event_cancel_indicator": false,
"program_segmentation_flag": true,
"segmentation_duration_flag": true,
"delivery_not_restricted_flag": true,
"segmentation_duration": 415.0,
"segmentation_duration_ticks": 37350000,
"segmentation_message": "Chapter Start",
"segmentation_upid_type": 12,
"segmentation_upid_type_name": "MPU",
"segmentation_upid_length": 25,
"segmentation_upid": {
"format_identifier": 1145656131,
"private_data": "0x3134333332305f3232385f30325f303031412d3034"
},
"segmentation_type_id": 32,
"segment_num": 4,
"segments_expected": 6
}
],
"packet_data": {
"pid": "0x1b",
"program": 1,
"pts_ticks": 6212017281,
"pts": 69022.414233
}
}
Provider Placement Opportunity Start
"pts_time_ticks": 282310529
"pts_ticks": 6212051315
282310529 -ひく 6212051315 =わ -ひく5929740786
Chapter Start
"pts_time_ticks": 289067279
"pts_ticks": 6212017281
289067279 -ひく 6212017281 =わ -ひく5922950002
If I compare that to the first message of the series, here's what we see:
Provider Advertisement End
pts_time_ticks: 282310529
pts_time: 281502279
282310529 -ひく 281502279 =わ 808250 / 90000 = 8.9 seconds, which is how far in advance of the splice point this message appears in the TS.
My question on this timing relationship then is how does the pts_ticks field get populated? That is not a field in the SCTE 35 (unless I am missing something), so threeFive must be either computing it or grabbing the next nearest PTS it can find in the stream? For all other messages, the pts_ticks field is around the pre-roll time, which makes sense.
Hopefully that explains what I am seeing. Thanks very much!
All reactions
Dude, you are wearing me out,
SCTE-35 returns ticks for PTS, to make life easier, threefive includes the PTS as seconds and as ticks.
threefive also includes PacketData, which is not a part of the SCTE-35 spec either.
I said verifty that it is a threefive issue before you bring it to me and you haven't shown me any proof that there is an error in threefive, I don't know what you expect me to do, I cant really tell you anything without seeing the stream,
and I dont want to see the stream unless you can show the issue is with threefive,
I'm not trying to be a dick, but I am spending a lot of my time helping you solve your problems,
I have my own problems to solve.
All reactions
I am just trying to understand how that packet_data / pts field gets populated, nothing more. You are not obligated to do anything. I tried to trace it through the .py files but it's beyond my comprehension. We can leave the discussion here, I am grateful for your help and hope to be able to contribute more meaningfully one day.
All reactions
Latest Version is 2.3.91 (PTS fix for long AFC and Stream.decode_pids)