-
Notifications
You must be signed in to change notification settings - Fork 30
Latest ffmpeg and threefive and SCTE-35 Info
futzu wrote.. "I don't know how to stop ffmpeg from changing the SCTE35 stream type to 0x6."
FYI - I did some experiments with this and it seems to be a limitation of FFmpeg's TS muxer.
If I use the NUT container (FFmpeg's proprietary container format), the -tag:d can be used to set the type. In theory, this tag should also be capable of setting the type via a fourcc value, but that does not seem to be supported for data streams. Hex or decimal work with a NUT container though.
In this case, the stream description was changed from scte_35 to none.
$ ffmpeg -hide_banner -i "https://futzu.com/xaa.ts" -map 0:v:0 -codec:v copy -streamid 0:0x101 -map 0:a:0 -codec:a copy -streamid 1:0x102 -map 0:d:0 -codec:d:0 copy -streamid 2:0x103 -tag:d:0 "0x86" -f nut OUTFILE.nut -y
# or
$ ffmpeg -hide_banner -i "https://futzu.com/xaa.ts" -map 0:v:0 -codec:v copy -streamid 0:0x101 -map 0:a:0 -codec:a copy -streamid 1:0x102 -map 0:d:0 -codec:d:0 copy -streamid 2:0x103 -tag:d:0 "134" -f nut OUTFILE.nut -y
$ ffprobe OUTFILE.nut
Stream #0:0: Video: h264 (Main) (H264 / 0x34363248), yuv420p(tv, bt470bg), 544x576 [SAR 64:33 DAR 544:297], 50 fps, 50 tbr, 90k tbn, 50 tbc
Stream #0:1(eng): Audio: mp2 (P[0][0][0] / 0x0050), 48000 Hz, stereo, s16p, 128 kb/s
Stream #0:2: Data: none ([134][0][0][0] / 0x0086)
If the same command is used with an MPEG-TS container, the FFmpeg muxer overwrites the type to be 0x6. At runtime / console output, it claims it is setting the 0x86, but when probed, the file output is 0x6.
In this case, the stream type was changed from scte_35 to bin_data.
$ ffmpeg -hide_banner -i "https://futzu.com/xaa.ts" -map 0:v:0 -codec:v copy -streamid 0:0x101 -map 0:a:0 -codec:a copy -streamid 1:0x102 -map 0:d:0 -codec:d:0 copy -streamid 2:0x103 -tag:d:0 "0x86" -f mpegts OUTFILE.ts -y
$ ffprobe OUTFILE.ts
Stream #0:0[0x101]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt470bg, top first), 544x576 [SAR 64:33 DAR 544:297], 25 fps, 50 tbr, 90k tbn, 50 tbc
Stream #0:1[0x102](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:2[0x103]: Data: bin_data ([6][0][0][0] / 0x0006)
This is not an issue with threefive, it is purely informational and can be closed. I recognize that threefive successfully works around FFmpeg's limitation. Raising the ticket was just a means of sharing knowledge and narrowing down where FFmpeg was struggling. Neither does the ticket solve the issue because the ultimate goal is setting it in a TS container, not a NUT container. Feel free to close this issue.
All reactions
Replies: 29 comments 40 replies
-tag:d:0 "0x86"
So that's how it works...
I tried using -tag, but I didn't know how to specify the stream.
I've never used the NUT container, I'm going to have to check it out.
I've been contemplating adding some code to change
a stream type in the PMT, that's where I get the stream type.
I don't know where the fourcc tag is stored in mpegts, that probably should set too though.
I'm going to make this a discussion, because I just noticed there was a option to do that,
and in hopes that you'll help me figure it out.
Have you ever played with mplex?
The information is appreciated man, post anytime you like.
Adrian
All reactions
NUT container is FFmpeg's native container. It is just a very simplistic container that "tries not to mess with stuff". It has no practical use outside of FFmpeg, but it is a great container for just playing with stuff within FFmpeg.
I've been contemplating adding some code to change a stream type in the PMT, that's where I get the stream type.
or just use TS Duck? That's a great tool for PMT mapping and stuff. I use TS Duck and pipe it into threefive... They are very complementary tools. You can do all sorts of TS manipulation.
$ tsp --verbose --input "hls" INPUTURL --processor "rmsplice" --dry-run --continue --processor "pcrextract" --pid "500" --scte35 | python3 -c 'import threefive; threefive.decode()'
Your code would make an an amazing base for a plugin to replace TS Duck's "rmsplice". Your code is way more sophisticated on the SCTE-35 side. TS Duck can do any of the TS manipulation rather well, and the dude who writes it seems like a good sort. If you don't know TS Duck, check it out.
Your code is also more sophisticated than TS Duck, because you have the basis for manifest-based ad markers. I don't think there are any other open-source projects that do ad marker decoding from HLS manifest.
I don't know where the fourcc tag is stored in mpegts, that probably should set too though.
Yeah, I don't know where that is set either.
mplex
I have looked at it in the past. I got scared. I ran away.
Having been a big user of threefive for a couple of years, I was amused to see that you are also the author of scc2vtt in a different repo. SCTE-35 & EIA-608/scc in HLS are two areas where I get very involved. ccextractor is my go-to, but I have played with scc2vtt. Thanks for open-sourcing your code.
Finally, I'm intrigued by where you got https://futzu.com/xaa.ts from - and don't feel like you have to answer. That particular TS stream was created about 2007-2009 in a proof of concept experiment with Channel 4 in the UK to do realtime replacement of ads for a student-focused IPTV service. I recognize the metadata in the stream. I never thought I would see that TS stream over a decade later.
All reactions
I am so sorry, I was not aware of your additional comments, I am just now reading them.
scc2vtt was part on a captioning and subtitle project i was on for about a year and a half. I still have captioning turn on, I like it .
xaa.ts came from that scte35 ffmpeg feature request. I ran the split command on the video, that's why the xaa name
All reactions
-
👍 1
All good, Futzu. There was nothing of meaning that warranted a reply.
I keep an eye on your work in threefive and regularly update to latest - it is so reassuring to see the level of maintenance and features that you put in (like HLS support and your new SDT tables). On behalf of your anonymous user base who who can't even read a line of Python - thanks for making the tool so usable in a plain command line environment.
"Great tool AAAA+++++. Would recommend."
All reactions
@bbgdzxng1 It seems many of my users aren't pythonic, so I'm going to make a command line tool out of the threefive/go version.
What options do you want in a command line tool?
All reactions
Ooops, just seen this. Sorry dude. For me, the simplest would be piping a TS into a threefive.decode() installable binary - although that's the one that is pretty easy anyway once you have your head around python.
What separates threefive from the rest is actually the HLS handling. The industry is separated into two groups...
(1) the broadcasters who deal with SCTE-35 as solely a data track. They operate in a TS domain. They are typically responsible for putting the markers in the stream with expensive kit and want an independent tool to verify that they conform to SCTE-35 best practice. They are typically originators and engineers. I expect many of those users rely on TSDuck's rmsplice, or TSDuck's newer splicemonitor plugin.
(2) The digital-OTT folks who are doing dynamic ad insertion using something like Uplynk, YoSpace, Brightcove Unicorn, GAM/DFP or MediaTailor. They operate in the HLS & manifest domain, generally using one of the non-SCTE-35 ad marker formats CUE-OUT/IN, but also need to understand what is happening in those mystical base-64 SCTE-35 messages. They are consumers of SCTE-35.
It is that second group where threefive really excels. Your toolset is the first single open source tool that acknowledges that SCTE is used in HLS. A use case for a standalone binary would be:
- Feed a master playlist (full URL, not locally hosted) into threefive
- Print a decoded, JSON output of base-64 SCTE markers in the data track
- Print a decoded, JSON output of base-64 SCTE markers in some of the more common vendor specific SCTE markers in the manifest (eg EXT-OATCLS-SCTE35)
- Print any interpreted non-SCTE ad markers in the various non-standard, vendor specific formats
- Install via the 'nice' CLI package managers, ie homebrew / apt / chocolatey
All of the above can be done today with scripting, piping and a combination of threefive / FFmpeg / TS Duck. It is just not very accessible to the non-pythonic user, but it works! And I am a very grateful user.
The trouble is more to do with python, not with your tool. An example is that the user sees threefive on github... Wow, that looks amazing.
- Ok, now I wanna play with it.
- Oh crap, I gotta install python on my mac.
- Hang on, python comes with my mac. Cool, Python 2.7.
- But I should be using Python3. Ok, learn how to install that with homebrew. Ok, now I have 2 pythons and I gotta play with my environment variables in my bash profiles
- Ok, now pip. This looks neat. What's the difference between pip and pip3? A few more hours go by. (pip is super neat, btw)
- Where does pip install stuff? I'm not running as admin, oh crap, where has pip put all the stuff I wanted. Some weird error messages keep appearing about upgrading pip, even through I've just upgraded pip. Oh well.
- Ok, I just got me head around pip and python... But I'm told I should be using pypy
- Oh no, I'm on an M1 mac and pypy is not there just yet. Back to python3.
- Right, now how do I invoke a python command?
I exaggerate for the sake of it, because your tl;dr of "Up and Running in Less Than 7 Seconds" was actually the most useful snippet I have ever seen in a python project because it provides (a) how to install (b) a hosted sample and (c) a reference output. Big kudos! Most of the above moans are not threefive, but are rather the daunting nature of the python-pip-pypy ecosystem.
I pressed on through, because I really like your stuff, but I suspect there is a similar demographic of non-pythonic users who kinda just give up. But there is the Uplynk, YoSpace, Brightcove Unicorn, GAM/DFP or MediaTailor userbase who just want to validate or monitor ad insertion and a command-line tool may suit them.
As a developer of what is fundamentally a library, the user's scripting / python learning curve is not your problem, and you are doing all this stuff for free - so please don't interpret this as anything more than a very satisfied and grateful user explaining their journey.
threefive is a library of functions that enables an enlightened developer to do pretty much anything in the SCTE-35 domain. But there is another less enlightened user group who are more bash/tool/binary focused. Some projects separate this into the library (for devs), eg https://github.com/x42/libltc and the tool (for users), eg https://github.com/x42/ltc-tools. Or libav (the library, not the confusing fork) vs FFmpeg the tool.
Does that help?
All reactions
-
😄 2
Yes it does. I'm going to do a stand alone binary with threefive/go. It is stupid fast.
All reactions
Ive been thinking about the monitoring thing, expect something soon.
All reactions
Finally, I'm intrigued by where you got https://futzu.com/xaa.ts from - and don't feel like you have to answer. That particular TS stream was created about 2007-2009 in a proof of concept experiment with Channel 4 in the UK to do realtime replacement of ads for a student-focused IPTV service. I recognize the metadata in the stream. I never thought I would see that TS stream over a decade later.
I never gave you an answer, I think I found that video on a ffmpeg feature request or bug report or something.
cli tools
You got me thinking about cli tools, I am about to bundle some cli tools together.
- a threefive cli
- a keyframe detector cli
- x9k3 hls segmenter cli
- a hls m3u8 and segment parser cli
- gumd , a multicast sender daemon cli
- re_cc, a continuity counter restamping cli
All of them use the reader function from threefive. Meaning they all support files, http(s), multicast, and udp URIs,
they also support reading from stdin, so you can pipe stuff in.
All reactions
As a separate comment to the above, which is what I checked back here to share...another kind developer has proposed a patch to FFmpeg for SCTE-35 passthrough. I thought it was relevant to the original topic about 0x86 stream type in MPEG-TS muxer and wanted to share with you http://ffmpeg.org/pipermail/ffmpeg-devel/2021-November/thread.html#287613. Who knows whether the patch will be accepted, but I can be pretty sure that threefive would be the test case for validating that FFmpeg patch. And if it isn't used as the test case, it should be!
On inspection, the proposed patch of the FFmpeg maining list may only work with one of -copyts, -mpegts_copyts 1 or -vsync passthrough is used, and may not not work if one of the timestamp manipulation techniques such as -vsync cfr|vfr|drop, -avoid_negative_ts -start_at_zero, -use_wallclock_as_timestamps, -output_ts_offset, setpts= filter or -bsf:v setts= filter is used. It would also be limited to MPEG-TS output. So the patch may get some pushback due to interaction of other FFmpeg internal functions. But that should all come out of testing, ideally using your awesome threefive.
There have been many SCTE-35 patches proposed to FFmpeg over the years, but none-of them have made it to stable, but maybe this is the start of something.
As ever, thank-you!
All reactions
I get the feeling the ffmpeg guys don't care much for SCTE35... I don't really know.
I need to check that out. Thank you.
You might like this example.
https://github.com/futzu/scte35-threefive/blob/master/examples/stream/cue2vtt.py
All reactions
Thanks futzu - I saw that cue2vtt.py a few weeks ago - and it looks very useful for debugging. I have not played with it fully - but I really like the way you are thinking. I don't trust whether any of the webVTT players are frame accurate or not, but even semi-accurate visualization is very helpful for quick and dirty. So thanks!
Most of my world is ad markers in a segmented HLS stream... and the one feature that FFmpeg, MVP and libav are lacking on is the playback of segmented webVTT within HLS. But I remux the HLS chunks into a single TS with TSDuck, run your cue2vtt and play the webVTT alongside the remuxed TS file, much like you do with mplayer, which pick ups the vtt subs because it has a common filename to the media.
I'm surprised (and relieved) that noone ever published a formal standard for SCTE-35 into a generic webVTT metadata track. We have webVTT captions, webVTT chapters, webVTT generic metadata but fortunately no standards-body has defined a method for communicating SCTE-35 via webVTT between systems. I say relieved because there more than enough ways of passing ad-insertion cues between systems already. Using webVTT for system>human visualization is very nice.
I was trying to work out a method of writing the (decoded) SCTE-35 from either threefive or TS Duck's splice_monitor to a named pipe/mkfifo, feed the named pipe to FFmpeg's metadata filter and then use FFmpeg's drawtext filter to overlay the frame metadata containing the decoded SCTE message over the video, but it all relied on pipes and writes (because ultimately, I'm just a monkey with a typewriter rather than a programmer).
At present, I use FFmpeg's drawtext to overlay the PTS on the video, and compare the PTS in the threefive decode. It is a manual process and non-realtime, but good enough for a bear of little brain.
Your vtt method is a useful non-realtime visualizer and a lot more elegant than my attempt. Thanks.
All reactions
I am surprised too. I was trying to do the same thing with ffmpeg,and driving myself nuts. Updated the cue2vtt.py last night. Mplayer doesnt recognize the webVTT formating, so everything is aligned center. I am thinking about combining it with mpegts.js project so I can play the video in a webpage with formatted webvtt subtitles.
I may do one in ASS subtitles, partly forthe formatting, but mostly just for the jokes. :)
All reactions
Lots of great stuff coming from the SoftWorks crew on subtitle rendering in FFmpeg's libav. I have been lurking in ffmpeg-devel and there was a huge amount of activity in Nov around subtitle frame handling and conversion. As far as I read it, it amounts to subtitle frame handling and a -filter:s and I think a subtitle API. http://ffmpeg.org/pipermail/ffmpeg-devel/2021-November/thread.html#288221. It looks to be a pretty substantial overhaul, subject to code review. One to watch.
With current stable and a -strict experimental flag you can unlock some of the HLS+webVTT functionality at least to a point that you can see the demuxer acknowledge webVTT in debug, but it is still experimental and non-functional.
$ ffmpeg -strict experimental -protocol_whitelist "http,https,tls,tcp" -format_whitelist "hls,mpegts,webvtt" -allowed_extensions ALL -i https://example.com/master-containing-webvtt.m3u8 -map 0 -f null -
If and when anything hits mainstream FFmpeg, I'll let you know.
All reactions
Speaking of HLS, check out x9k3.
All reactions
kabuki can change the stream type back to 0x86 (scte35)
All reactions
Sorry, I did not see your comment. I have been watching kabuki for a month. Very cool, Adrian. Very cool.
And x93k has been progressing nicely. So nice to see that there's now an open-source solution for inserting SCTE messages in streams. I have been watching that too.
Loving cuei, btw.
I hope you are well, sir.
All reactions
I there a way to hack a fix into ffmpeg for this? I'm digging through the code and having trouble finding where this occurs.
Got this far but lose track:
https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/mpegts.c#L2478
I've read through kabuki but my python is so rusty. I don't really need to make a durable fix but need to run a live remux to test downstream scte35 haling.
Thanks
All reactions
Ive never really looked at ffmpeg's code but what if I update kabuki so you can pipe a stream through it?
I did that last week for SuperKabuki and it works well.
Then you could do
{ ffmpeg command goes here} - | kabuki -o outfile.ts
Would that solve your problem?
All reactions
I updated kabuki, git pull you some.
version is 0.0.3
a@debian:~$ pypy3 kabuki.py -v 0.0.3 a@debian:~$
Here's the input
a@debian:~$ ffprobe pv.ts -hide_banner [mpegts @ 0x55ddbc4045c0] start time for stream 5 is not set in estimate_timings_from_pts Input #0, mpegts, from 'pv.ts': Duration: 00:00:20.33, start: 1.400000, bitrate: 17696 kb/s Program 1 Metadata: service_name : Service01 service_provider: FFmpeg Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn Stream #0:1[0x101]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:2[0x102]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:3[0x103]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:4[0x104]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:5[0x105]: Data: bin_data ([6][0][0][0] / 0x0006) Unsupported codec with id 98314 for input stream 5 a@debian:~$
- then I ran this command with the updated kabuki.py
a@debian:~$ cat pv.ts | pypy3 kabuki.py -p 0x105 | ffplay -hide_banner -
- output
261 pid match Input #0, mpegts, from 'pipe:': 0KB vq= 0KB sq= 0B f=0/0 Duration: N/A, start: 1.400000, bitrate: N/A Program 1 Metadata: service_name : Service01 service_provider: FFmpeg Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn Stream #0:1[0x101]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:2[0x102]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:3[0x103]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:4[0x104]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:5[0x105]: Data: scte_35 17.30 A-V: -0.019 fd= 0 aq= 32KB vq= 2498KB sq= 0B f=0/0
- to write to a file
a@debian:~$ cat pv.ts | pypy3 kabuki2.py -p 0x105 -o kout.ts 261 pid match
ffprobe -hide_banner kout.ts Input #0, mpegts, from 'kout.ts': Duration: 00:00:20.24, start: 1.400000, bitrate: 17650 kb/s Program 1 Metadata: service_name : Service01 service_provider: FFmpeg Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn Stream #0:1[0x101]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:2[0x102]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:3[0x103]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:4[0x104]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:5[0x105]: Data: scte_35 Unsupported codec with id 98305 for input stream 5
so you can do something like
ffmpeg -i mpegts/pcrvid.ts -map 0 -c copy -f mpegts - | pypy3 kabuki.py -p 0x105 | ffplay -
All reactions
Fighting the install of new_reader on arch.
python ~/bin/kabuki.py -v
0.0.3
pypy3 ~/bin/kabuki.py -v
Traceback (most recent call last):
File "/home/mikeg/bin/kabuki.py", line 7, in <module>
from new_reader import reader
ModuleNotFoundError: No module named 'new_reader'
Dunno if that has an impact. I have to do a lot of piping (hls source):
ffmpeg -re -i http://x.x.x.x:xx/720/funroads720SCTE35.m3u8 -map 0 -c copy -f mpegts - | python3 ~/bin/kabuki.py -p 0x103 | ffmpeg -i pipe: -map 0 -c copy -f mpegts udp://127.0.0.1:2000
ffprobe udp://127.0.0.1:2000
Input #0, mpegts, from 'udp://127.0.0.1:2000':
Duration: N/A, start: 4.683844, bitrate: N/A
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 59.94 fps, 59.94 tbr, 90k tbn
Stream #0:1[0x101]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 131 kb/s
Stream #0:2[0x102]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 7 kb/s
Stream #0:3[0x103]: Data: bin_data ([6][0][0][0] / 0x0006)
I will revisit try to get this running on Centos7 and/or Debian. Looks promising though.
All reactions
I need to restream the fixed stream, so I'll try to add unicast output.
All reactions
Fighting the install of new_reader on arch.
python ~/bin/kabuki.py -v 0.0.3 pypy3 ~/bin/kabuki.py -v Traceback (most recent call last): File "/home/mikeg/bin/kabuki.py", line 7, in <module> from new_reader import reader ModuleNotFoundError: No module named 'new_reader'Dunno if that has an impact. I have to do a lot of piping (hls source):
ffmpeg -re -i http://x.x.x.x:xx/720/funroads720SCTE35.m3u8 -map 0 -c copy -f mpegts - | python3 ~/bin/kabuki.py -p 0x103 | ffmpeg -i pipe: -map 0 -c copy -f mpegts udp://127.0.0.1:2000 ffprobe udp://127.0.0.1:2000 Input #0, mpegts, from 'udp://127.0.0.1:2000': Duration: N/A, start: 4.683844, bitrate: N/A Program 1 Metadata: service_name : Service01 service_provider: FFmpeg Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 59.94 fps, 59.94 tbr, 90k tbn Stream #0:1[0x101]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 131 kb/s Stream #0:2[0x102]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 7 kb/s Stream #0:3[0x103]: Data: bin_data ([6][0][0][0] / 0x0006)I will revisit try to get this running on Centos7 and/or Debian. Looks promising though.
pip3 install new_reader
Tell me if that doesnt work for you.
All reactions
https://github.com/futzu/gumd , gumd does multicast, and it's real easy to use.
I just tried it and I was able to read the stream as UDP
cat pv.ts | pypy3 ./kabuki.py -p 0x105 | gumd -a 127.0.0.1:2000
in another terminal I ran
ffplay udp://127.0.0.1:2000
and it worked just fine.
a@debian:~/build/clean/x9k3$ ffplay udp://127.0.0.1:2000 Input #0, mpegts, from 'udp://127.0.0.1:2000':0KB sq= 0B f=0/0 Duration: N/A, start: 1.400000, bitrate: N/A Program 1 Metadata: service_name : Service01 service_provider: FFmpeg Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn Stream #0:1[0x101]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:2[0x102]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:3[0x103]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:4[0x104]: Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 256 kb/s Stream #0:5[0x105]: Data: scte_35
All reactions
I had to rename kabuki six2scte35 so I could make it a pkg.
https://github.com/futzu/six2scte35
pip3 install six2scte35 gumd or pypy3 -mpip install six2scte35 gumd
then you can do something like
ffmpeg -re -i http://x.x.x.x:xx/720/funroads720SCTE35.m3u8 -map 0 -c copy -f mpegts - | six2scte35 -p 0x105 | gumd -a 127.0.0.1:2000
That's about as concise I can make it.
All reactions
Good God Man, don't leave me in suspense :)
All reactions
Worked like charm.
ffmpeg -re -i http://x.x.x.x:xx/720/funroads720SCTE35.m3u8 -map 0 -c copy -f mpegts -pkt_size 1316 -flush_packets 0 - | six2scte35 -p 0x103 | gumd -a x.x.x.x:3001
Probe gave me:
Input #0, mpegts, from 'udp://x.x.x.x:3001':
Duration: N/A, start: 4.676511, bitrate: N/A
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 59.94 fps, 59.94 tbr, 90k tbn
Stream #0:1[0x101]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 131 kb/s
Stream #0:2[0x102]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 7 kb/s
Stream #0:3[0x103]: Data: scte_35
All reactions
Cool. I didn't know gumd could do that until I tried it yesterday. gumd also does 1316 packet size by default.
I am glad you got it working,
Adrian
All reactions
Hey I got a message about binding to a specific interface, I was thinking that maybe an issue and I should make it so you can specify the interface, I will try update it tonight, but it will probably be tomorrow.
All reactions
Some changes I think you'll dig.
pypy3 gums.py -i ~/mpegts/udp.livetv.ts -b 192.168.12.160 -u -a 192.168.12.160:4444 Stream: udp://192.168.12.160:4444 Source: 192.168.12.160:43594
- I dropped the port for bind address
- The Source ip and port are values directly from the socket
self.sock.getsockname() - UDP sockets are now non-blocking
- I changed the name to gums.
- bin/gumd and bin/gums scripts are both available and both use gums.
usage: gums [-h] [-i INPUT] [-a ADDR] [-u] [-b BIND_ADDR] [-t TTL] [-v] optional arguments: -h, --help show this help message and exit -i INPUT, --input INPUT like "/home/a/vid.ts" or "udp://@235.35.3.5:3535" or "https://futzu.com/xaa.ts" -a ADDR, --addr ADDR Destination IP:Port like "227.1.3.10:4310" -b BIND_ADDR, --bind_addr BIND_ADDR Local IP to bind to like "192.168.1.34". Default is 0.0.0.0 -t TTL, --ttl TTL Multicast TTL 1 - 255 -u, --unicast Use Unicast instead of Multicast -v, --version Show version
All reactions
-
👀 1
In C we just test if multicast address, no need for extra arg:
if ((inet_addr(address) & 0x000000F0) == 0x000000E0)
Python might have to range compare. Less stuff for users to figure out, the easier.
If you want more optional features to add:
Source-specific multicast (SSM) receive. https://en.wikipedia.org/wiki/Source-specific_multicast
RTP handling (sending is easy). https://en.wikipedia.org/wiki/Real-time_Transport_Protocol
SSM we use for backup systems. Some broadcast plants send redundant streams from multiple sources and the client can switch between them as needed (usually for redundancy purposes).
RTP is just a re-ordering protocol. It's most edffective in SMPTE 2022-7. Dual identical RTP streams, client reads both and if any ordered packet is missing, is grabbed from the other RTP stream. RTP requires buffering which can introduce unwanted jitter.
All reactions
All reactions
Hi futzu, i had use this ..
ffmpeg -re -i http://x.x.x.x:xx/720/funroads720SCTE35.m3u8 -map 0 -c copy -f mpegts - | six2scte35 -p 0x105 | gumd -a 127.0.0.1:2000
its running well, but no PCR detected ..
Can you help me for this issue..
All reactions
Sorry, I'm just seeing this. Which program is saying no PCR detected?
Cut and paste the errors for me.
All reactions
I'm trying to use threefive sixfix on a TS file but encounter the following error:
File "/home/ade/venv_t2tools/bin/threefive", line 386, in <module>
chk_mpegts_map()
File "/home/ade/venv_t2tools/bin/threefive", line 244, in chk_mpegts_map
mpegts_map[key](arg)
File "/home/ade/venv_t2tools/lib/python3.12/site-packages/threefive/sixfix.py", line 176, in sixfix
sixed = s1.decode(func=passed)
^^^^^^^^^^^^^^^^^^^^^^
File "/home/ade/venv_t2tools/lib/python3.12/site-packages/threefive/sixfix.py", line 26, in decode
super().decode(func=passed)
File "/home/ade/venv_t2tools/lib/python3.12/site-packages/threefive/stream.py", line 261, in decode
cue = self._parse(pkt)
^^^^^^^^^^^^^^^^
File "/home/ade/venv_t2tools/lib/python3.12/site-packages/threefive/stream.py", line 491, in _parse
pid = self._parse_info(pkt)
^^^^^^^^^^^^^^^^^^^^^
File "/home/ade/venv_t2tools/lib/python3.12/site-packages/threefive/stream.py", line 486, in _parse_info
self._parse_tables(pkt, pid)
File "/home/ade/venv_t2tools/lib/python3.12/site-packages/threefive/stream.py", line 472, in _parse_tables
return self._parse_pmt(pay, pid)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ade/venv_t2tools/lib/python3.12/site-packages/threefive/stream.py", line 648, in _parse_pmt
pay, seclen, program_number = self._mk_pmt_payload(pay, pid)
Looking at the code it's unclear why _mk_pmt_payload is failing but it seems like _parse_pmt is expecting a tuple but is being returned a bool? Should _mk_pmt_payload be returning a tuple with program_number = False?
(Full disclosure I'm no great Python programmer)
Unfortunately I cannot send you the specific file, it's proprietary. But I have seen this with several different capture files we use internally. Is it possible to run threefive in a debug mode to I can send you further info?
All reactions
All reactions
WAIT,
you have the code jacked up
self._mk_pmt_payload(pay, pid) is not called with sixfix.
File "/home/ade/venv_t2tools/lib/python3.12/site-packages/threefive/stream.py", line 648, in _parse_pmt
pay, seclen, program_number = self._mk_pmt_payload(pay, pid)
sixfix overrides _parse_pmt and it doesn't call _mk_pmt_payload
def _parse_pmt(self, pay, pid): """ parse program maps for streams """ pay = self._chk_payload(pay, pid) if pay: seclen = self._parse_length(pay[1], pay[2]) n_seclen = seclen + 6 if self._section_incomplete(pay, pid, seclen): return False program_number = self._parse_program(pay[3], pay[4]) ...
All reactions
You have rewritten my code and won't show me your video. What part of the video is proprietary?
The _parse_pmt for sixfix is the most important part, and you removed it.
Of course it doesn't work now.
You should
pip3 install threefive3
try it with threefive3 , leave the code alone, and if it doesn't work, it's on your end.
The error you showed is not even possible unless you change the code around.
All reactions
I definitely didn't rewrite your code. This was what I found when I looked at the version I had installed. I'm running in a venv:
I attached the output from installing and running both threefive and threefive3: session.log
Maybe I have an outdated version somehow? But the call stack seems to be showing the code installed in the venv.
Yes. I 101% agree not being able to send you a file is frustrating. Apologies, I work for a large media company who have a lot of lawyers and care a lot about "intellectual property". If this turns out to be more than some weird installation issue I will work on getting you something but that may take a while.
All reactions
I made the only change I could think that might help you, pip up to threefive v3.0.9.
That is the best I can do blindfolded.
All reactions
Did it work?
I did a build just for you, it would be nice if let me know if it solved your problem.
All reactions
Thanks for spending the time on this. I appreciate it. I'm going to look at it this evening (as in now).
I understand it's very limiting not having the video. Please don't expend any more of your time on this. I think I have enough pointers to dig into this and figure it out, which was my initial intent.
I'll let you know if the new build give me any more insights.
All reactions
I got your build and see the fix you added, which fixes the code in _mk_pmt_payload. The new threefive3 no longer crashes. It returns "No bin data SCTE-35 streams were found." This is a much better. Thanks!
I spent the evening looking into this further as the original TS contained a SCTE track before I remuxed it the FFmpeg, so should be found as a 0x06 track by sixfix. I'm pretty sure that the issue is related to the PMT being very large. The PMT describes 34 streams in total; 1 video, 1 data (SCTE-35) and 32 audio.
threefive3 show displays a partial PMT which seems incorrect.
python3 bin/threefive3 show output_34streams.ts
Program: 1
Service: Service01
Provider: FFmpeg
Pid: None
Pcr Pid: None
Streams:
Pid Type
ffprobe outputs the entire PMT. I've tested this with other files with smaller PMTs, for these threefive3 and FFmpeg agree.
This is simply a progress report. I don't have a concrete repro file I can send you and I wouldn't want you to devote any more time to this. I will continue looking at it over the weekend and see if I can come up with something more definitive and/or a fix.
All reactions
threefive handles multi-packet pmts though, I first ran into that several years ago
def _section_incomplete(self, pay, pid, seclen): # + 3 for the bytes before section starts if (seclen + 3) > len(pay): self.maps.partial[pid] = pay return True return False
def _mk_pmt_payload(self, pay, pid): seclen = False program_number = False pay = self._chk_partial(pay, pid, self.PMT_TID) <--- # this checks if there is a previous incomplete PMT if not pay: # if there is it the old data is prepended to pay and returned return False, False, False seclen = self._parse_length(pay[1], pay[2]) <--- # then I check the section length to see if I have all the pieces if self._section_incomplete(pay, pid, seclen): <--- # if it is still incomplete it stores the data in the Srtream.maps.partial return False, False, False program_number = self._parse_program(pay[3], pay[4]) return pay, seclen, program_number
About a year ago I noticed ffmpeg started padding in the front of the AFC instead of the payload, so I added code to deal with that.
def _unpad_afc(self, pkt): if self._afc_flag(pkt[3]): pkt = pkt[:4] + self._unpad(pkt[4:]) return pkt def _unpad(self, bites): pad = 255 one = 1 if not bites: return b"" if bites[0] in [pad]: self._unpad(bites[one:]) return bites
Since it stopped blowing up , that means the issue occurs in either
self._chk_partial
def _chk_partial(self, pay, pid, sep): if pid in self.maps.partial: pay = self.maps.partial.pop(pid) + pay return self._split_by_idx(pay, sep)
or
self.section_incomplete
def _section_incomplete(self, pay, pid, seclen): # + 3 for the bytes before section starts if (seclen + 3) > len(pay): self.maps.partial[pid] = pay return True return False
When ffmpeg started padding the SCTE-35 packets in the beginning of the AFC,
I started checking the SCTE-35 packets for pes start codes with the SCTE-35 TID,
because when they pad the AFC like that, the TID shows up at the start of the AFC
right after the PES start code and then again at the start of the payload.
I was splitting on the first instance of the SCTE-35 TID
I wrote about it here:
https://github.com/futzu/threefive/blob/master/ffrewrite.md
The second image has a red part, that's the AFC,
\x00\x00\x01 is the PES start code, and \xfc is the SCTE-35 TID
if you notice, the pay, the green part, starts with \xfc.
I was splitting on the first SCTE-35 TID, in the AFC rather than the one
at the start of the payload.
So I added this method to check the SCTE-35 packets
def _strip_scte35_pes(self, pkt): pay = self._parse_payload(pkt) if self.SCTE35_PES_START in pay: # print2(f"# Stripping PES Header from SCTE35 @ {self.pid2pts(pid)}") pay = pay.split(self.SCTE35_PES_START, 1)[-1] peslen = pay[4] + 5 # PES header length pay = pay[peslen:] return pay
You can check if they are doing the same thing with PMT,
I said it was PES start code + TID,which is not really accurate,
it's not the TID it's the stream identifier , which for SCTE-35, the TID and stream id are both \xfc.
I'd look af the PMT packets, the only way it's going to fail like the SCTE-35 did is if
you can find \x00\x00\x01\x02 in the AFC of the PMT packet, that's my best guess.
All reactions
I just checked a bunch of PMT packets, no PES start codes.
I have absolutely no idea what's causing the issue.
All reactions
Damn it Man!
You're right, I'm doing the multi-packet tables wrong.
Give me a minute and I'll come up with a fix.
All reactions
I've spent all day on it , and I can't spend any more time on it. To do it with multi-packet tables, I have to collect all the pmt packets process them, add the CUEI descriptor,change the stream types , then split the big payload up into smaller payloads then calculate all the headers vars, calculate the crcs, continuity counters, and add the new headers to the new payloads and then reinsert them.
That's a lot of extra work and I've already spent at least ten hours on this. I can't do it anytime soon man. Sorry.
All reactions
You're probably only using a little bit of the second packet, you might be able to trim it down a little and get it all in one packet. Trim out some extra descriptors . Each stream uses 5 bytes in the PMT packet, plus whatever descriptors you have. With three or four streams, it only takes about 70 bytes of the 188 bytes in a PMT packet, you should be able to have 10 streams in one packet. If you split into two programs it would work too.
All reactions
OK. That all makes sense. PMTs with lots of audio channels is something I deal with a lot because we have a lot of European sources. But from the perspective of threefive3 it seems completely reasonable to not support it. As you pointed out re-writing the stream across multi-packets is tricky.
As least I understand the problem now. Thanks for all your help on this and the suggested work around which I'll start to consider next week.
All reactions
Look at the section length of the PMT and see if it's over 183.
I've had multi-packet PATs and SCTE-35, but not PMT I don't believe.
I have to add 27 streams to the program before it spreads the table over multiple packets, and Europe only recognizes 22 languages :),
I think I have a better approach I was going to try,
but I'm really not sure we have diagnosed the problem correctly and you haven't given me enough info to recreate your scenario.
when I parse a packet that is part of a split table
- slice off the the header
- read the section length out of the payload, let's say the sec len is 200,
- if the table is split so I store the payload in the partial map.
- When I get next packet , the first thing i do is check the partial map ,
- if I have a partial, I prepend it to the new payload,
- check the sec len again,
- then parse the combined payload.
with the combined payload ,
- I can split it into two packets
- copy everything except the crc from the second packet header to the first.
- calc a new crc
I always wonder why a continuity countinuity can be repeated or incremented, I believe this type of thing is why.
Print the PMT payloads, if it's not split, they will all be the same. If it's split, you'll see at least two distinct payloads.
The second one will be almost entirely '\xFF'.
At the beginning of _parse_pmt, just print the payload.
All reactions
If you want to hire me , I can do it, it will take about a week.
If you're doing what I think, I can also show you a better way to do it.
All reactions
@amiller-isp
you do know you can share streams between programs right?
These two programs share SCTE-35 and Video streams
but have different audio.
Input #0, mpegts, from 'sixfixed-too.ts': Duration: N/A, start: 1.466733, bitrate: N/A Program 1 Metadata: service_name : One service_provider: FFmpeg Stream #0:0[0x100]: Data: scte_35 Stream #0:1[0x101]): Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 64 kb/s Stream #0:2[0x102]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, progressive), 640x360 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn Program 2 Metadata: service_name : Too service_provider: FFmpeg Stream #0:0[0x100]: Data: scte_35 Stream #0:2[0x102]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, progressive), 640x360 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn Stream #0:3[0x103]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 64 kb/s
All reactions
The TS has a total of 34 streams, including video and SCTE-35. So I have more than 27. The more I think about this the more I consider it to be a weird edge case. As you can see there are some very non-EMEA languages included here.
Input #0, mpegts, from 'multi_audio.ts':
Duration: 00:01:52.24, start: 90327.922322, bitrate: 24592 kb/s
Program 2
Stream #0:0[0x6f]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 50 tbr, 90k tbn
Stream #0:1[0x79](QIS): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:2[0x7a](ENG): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:3[0x7b](GER): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:4[0x7c](FRE): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:5[0x7d](SWE): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:6[0x7e](FIN): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:7[0x7f](DAN): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:8[0x80](NOR): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:9[0x81](ITA): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:10[0x82](TUR): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:11[0x8d]: Data: scte_35
Stream #0:12[0xe7](SPA): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:13[0xe8](POR): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:14[0xe9](DUT): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:15[0xea](POL): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:16[0xeb](RUS): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:17[0xec](RUM): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:18[0xed](GRE): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:19[0xee](SRP): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:20[0xef](HUN): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:21[0xf0](CZE): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:22[0xf1](BUL): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:23[0xf2](CHI): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:24[0xf3](JPN): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:25[0xf4](KOR): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:26[0xf5](THA): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:27[0xf6](VIE): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:28[0xf7](ARA): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:29[0xf8](EST): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:30[0xf9](HIN): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:31[0xfa](HEB): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:32[0xfb](SLV): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Stream #0:33[0xfc](LAV): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s
Unsupported codec with id 98305 for input stream 11
What I'm trying to do it take some pretty large source captures and truncate them for use by some of our other tools, which in turn expect a single program with multiple content streams. It's pretty important to preserve the original layout as much as possible. I was simply intending to use sixfix to correct the FFmpeg re-muxing issue with SCTE-35 streams.
Now we think it's a PMT parsing issue I'll try and get you a TS fragment which will repro this. It will be very small and likely not include any video. If I can do that I'll attach it here. I'll try and get this done later tonight.
All reactions
a@fu:~/build5/scte35/scte35$ ./scte352 show plus.ts plus.ts Program: 1 Service: Service01 Provider: FFmpeg Pid: 4096 Pcr Pid: 257 Streams: Pid Type 256 [0x100] 0x6 MPEG-2 binary data 257 [0x101] 0x1b H.264 258 [0x102] 0xf ADTS AAC 259 [0x103] 0x6 MPEG-2 binary data 260 [0x104] 0x15 ID3 261 [0x105] 0x6 MPEG-2 binary data 262 [0x106] 0x6 MPEG-2 binary data 263 [0x107] 0x15 ID3 264 [0x108] 0x1b H.264 265 [0x109] 0xf ADTS AAC 266 [0x10a] 0x1b H.264 267 [0x10b] 0xf ADTS AAC 268 [0x10c] 0x6 MPEG-2 binary data 269 [0x10d] 0x6 MPEG-2 binary data 270 [0x10e] 0x15 ID3 271 [0x10f] 0x1b H.264 272 [0x110] 0xf ADTS AAC 273 [0x111] 0x6 MPEG-2 binary data 274 [0x112] 0x1b H.264 275 [0x113] 0xf ADTS AAC 276 [0x114] 0x6 MPEG-2 binary data a@fu:~/build5/scte35/scte35$ ./scte352 show sixfixed-plus.ts sixfixed-plus.ts Program: 1 Service: Service01 Provider: FFmpeg Pid: 4096 Pcr Pid: 257 Streams: Pid Type 2 [0x2] 0xf ADTS AAC # <---- this is wrong but the rest is right. 256 [0x100] 0x86 SCTE-35 257 [0x101] 0x1b H.264 258 [0x102] 0xf ADTS AAC 259 [0x103] 0x86 SCTE-35 260 [0x104] 0x15 ID3 261 [0x105] 0x6 MPEG-2 binary data 262 [0x106] 0x6 MPEG-2 binary data 263 [0x107] 0x15 ID3 264 [0x108] 0x1b H.264 265 [0x109] 0xf ADTS AAC 266 [0x10a] 0x1b H.264 267 [0x10b] 0xf ADTS AAC 268 [0x10c] 0x86 SCTE-35 269 [0x10d] 0x6 MPEG-2 binary data 270 [0x10e] 0x15 ID3 271 [0x10f] 0x1b H.264 272 [0x110] 0xf ADTS AAC 273 [0x111] 0x86 SCTE-35 274 [0x112] 0x1b H.264 275 [0x113] 0xf ADTS AAC 276 [0x114] 0x86 SCTE-35
All reactions
I'm not going to add that to threefive3, it took about 500 lines of code and doing that in real time slows things down and it's just a rough draft.
All reactions
I am just showing you I can do it. I have no intention of adding to threefive3. In five years you're the only person that's asked for it, and I'm not going to add 500 lines of code and complexity to threefive3 for just one person.
All reactions
I think that was my suggestion too. You might want to document that large PMTs aren't supported though. Thanks for looking into it.
All reactions
I'm also contemplating taking this up with the FFmpeg devs. Not full SCTE-25 support, just fixing the re-muxing issue. In the past people have tried to get this fixed and created patches for it but for some reason it's never made it into the main branch. I need to have a look at the FFmpeg muxer and see what's required but there were some patches submitted a couple of years back that I could probably use as a starting point.
If I make any headway or figure out anything WRT your comments above I'll update here.
All reactions
@amiller-isp Did you try my patched FFmpeg? It works perfectly . Good God man.
All reactions
@amiller-isp I wrote a patch for ffmpeg, it's not perfect, but it's pretty good.
watch this:
ffprobe a sixfixed file
copy the codecs with ffmpeg
ffprobe the new file
All reactions
All reactions
This is even better, this is a patched version of ffmpeg that allows you copy over SCTE-35 streams in FFmpeg.
https://github.com/superkabuki/FFmpeg_SCTE35
@amiller-isp check it out man.
All reactions
page not found error while browsing https://github.com/superkabuki/FFmpeg_SCTE35