Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement looping, demuxer options #420

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

iameli-streams
Copy link

So -stream_loop doesn't work when provided as a demuxer option, as it's implemented in https://github.com/FFmpeg/FFMpeg/blob/master/fftools/ffmpeg_demux.c and we handle our own demuxing. Thankfully, this seemed to be relatively easy to port over using the preexisting work that we have for handling discontinuity. Lightly tested.

Demuxer options: Pretty straightforward, follows the same syntax as the output muxer options.

My use case: I've already got a livestream being sliced up into a bunch of C2PA-signed MP4 files. But now I need to turn them back into an MKV stream. To do this I'm using a hack on top of ffmpeg's concat muxer, looks like this on the command line:

ffmpeg \
  -stream_loop -1 \
  -safe 0 \
  -protocol_whitelist file,http,https,tcp,tls \
  -i http://127.0.0.1:9090/playback/0xf081d6383777482868faa8d5534a5f1a7777bee8/concat \
  -map 0 \
  -c copy \
  -y output.mkv

And that concat file looks like this:

ffconcat version 1.0
file 'http://127.0.0.1:9090/playback/0xf081d6383777482868faa8d5534a5f1a7777bee8/latest.mp4'
file 'http://127.0.0.1:9090/playback/0xf081d6383777482868faa8d5534a5f1a7777bee8/latest.mp4'

And those latest.mp4 files get 301 redirected to the correct MP4 files. Works great!

Pretty straightforward, follows the same syntax
as the output muxer options.
So -stream_loop doesn't work when provided as a
demuxer option, as it's implemented in https://github.com/FFmpeg/FFMpeg/blob/master/fftools/ffmpeg_demux.c
and we handle our own demuxing. Thankfully, this
seemed to be relatively easy to port over using
the preexisting work that we have for handling
discontinuity. Lightly tested.
@j0sh
Copy link
Collaborator

j0sh commented Aug 29, 2024

I love to see improvements like this, thanks @iameli !

The demuxer changes LGTM, it might be nice to have a test case exercising that. One scenario where I think it would be needed to specify the demuxer is for m3u8 files that don't have a standard extension - see the ffmpeg code (hit this during the ffmpeg 7 upgrade; see the diff for the TestTranscoder_FomatOptions testcase)

The looping changes look good too but I am curious how it would behave with non-seekable inputs like most non-HTTP network protocols, pipes, etc. Other than that it would be nice to have tests for those too: check that the output is as expected etc for both seekable and non-seekable inputs. For non-seekable it would still be good to codify the behavior even if it is explicitly not supported.

@iameli-streams
Copy link
Author

Thanks for taking a look @j0sh!

I'm having trouble getting that test working, I've tried a couple environments...

root@e230e4d291c9:/home/iameli/code/lpms# go test -coverprofile cover.out -run ^TestTranscoder_FormatOptions$ ./ffmpeg/... 2>&1 | tee test.log
?   	github.com/livepeer/lpms/ffmpeg/proto	[no test files]
ERROR: encoder.c:220] Unable to guess output format : Invalid argument
ERROR: transcoder.c:238] Unable to open output : Invalid argument
E0831 12:15:07.179209   37135 ffmpeg.go:1015] Transcoder Return : Invalid argument
--- FAIL: TestTranscoder_FormatOptions (0.51s)
    ffmpeg_test.go:1637: Invalid argument
    ffmpeg_test.go:35: + ffprobe -loglevel warning -show_format test.flv
        + grep format_name=flv
        test.flv: No such file or directory
        
    ffmpeg_test.go:35: + ffprobe -loglevel warning -show_entries format=format_name,duration actually_mpegts.flv
        + ffprobe -loglevel warning -show_entries format=format_name,duration actually_mp4.flv
        + cat
        + diff -u actually_mpegts.out test.out
        + diff -u actually_mp4.out expected_mp4.out
        --- actually_mp4.out	2024-08-31 12:15:07.459846342 -0700
        +++ expected_mp4.out	2024-08-31 12:15:07.463846331 -0700
        @@ -1,4 +1,4 @@
         [FORMAT]
         format_name=mov,mp4,m4a,3gp,3g2,mj2
        -duration=8.033000
        +duration=8.032667
         [/FORMAT]
        
    ffmpeg_test.go:35: + ffprobe -loglevel warning -show_entries format=format_name,duration actually_mpegts_2.flv
        + ffprobe -loglevel warning -show_entries format=format_name,duration actually_mp4_2.flv
        + diff -u actually_mpegts_2.out test.out
        + diff -u actually_mp4_2.out expected_mp4.out
        --- actually_mp4_2.out	2024-08-31 12:15:07.570846055 -0700
        +++ expected_mp4.out	2024-08-31 12:15:07.463846331 -0700
        @@ -1,4 +1,4 @@
         [FORMAT]
         format_name=mov,mp4,m4a,3gp,3g2,mj2
        -duration=8.033000
        +duration=8.032667
         [/FORMAT]
        
FAIL
	github.com/livepeer/lpms/ffmpeg	coverage: 39.3% of statements
FAIL	github.com/livepeer/lpms/ffmpeg	0.520s
FAIL
root@e230e4d291c9:/home/iameli/code/lpms# cat test.log 
?   	github.com/livepeer/lpms/ffmpeg/proto	[no test files]
ERROR: encoder.c:220] Unable to guess output format : Invalid argument
ERROR: transcoder.c:238] Unable to open output : Invalid argument
E0831 12:15:07.179209   37135 ffmpeg.go:1015] Transcoder Return : Invalid argument
--- FAIL: TestTranscoder_FormatOptions (0.51s)
    ffmpeg_test.go:1637: Invalid argument
    ffmpeg_test.go:35: + ffprobe -loglevel warning -show_format test.flv
        + grep format_name=flv
        test.flv: No such file or directory
        
    ffmpeg_test.go:35: + ffprobe -loglevel warning -show_entries format=format_name,duration actually_mpegts.flv
        + ffprobe -loglevel warning -show_entries format=format_name,duration actually_mp4.flv
        + cat
        + diff -u actually_mpegts.out test.out
        + diff -u actually_mp4.out expected_mp4.out
        --- actually_mp4.out	2024-08-31 12:15:07.459846342 -0700
        +++ expected_mp4.out	2024-08-31 12:15:07.463846331 -0700
        @@ -1,4 +1,4 @@
         [FORMAT]
         format_name=mov,mp4,m4a,3gp,3g2,mj2
        -duration=8.033000
        +duration=8.032667
         [/FORMAT]
        
    ffmpeg_test.go:35: + ffprobe -loglevel warning -show_entries format=format_name,duration actually_mpegts_2.flv
        + ffprobe -loglevel warning -show_entries format=format_name,duration actually_mp4_2.flv
        + diff -u actually_mpegts_2.out test.out
        + diff -u actually_mp4_2.out expected_mp4.out
        --- actually_mp4_2.out	2024-08-31 12:15:07.570846055 -0700
        +++ expected_mp4.out	2024-08-31 12:15:07.463846331 -0700
        @@ -1,4 +1,4 @@
         [FORMAT]
         format_name=mov,mp4,m4a,3gp,3g2,mj2
        -duration=8.033000
        +duration=8.032667
         [/FORMAT]
        
FAIL
	github.com/livepeer/lpms/ffmpeg	coverage: 39.3% of statements
FAIL	github.com/livepeer/lpms/ffmpeg	0.520s
FAIL
root@e230e4d291c9:/home/iameli/code/lpms#

@j0sh
Copy link
Collaborator

j0sh commented Aug 31, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants