diff --git a/internal/ffmpeg/ffmpeg.go b/internal/ffmpeg/ffmpeg.go index 287206d2..0c882db5 100644 --- a/internal/ffmpeg/ffmpeg.go +++ b/internal/ffmpeg/ffmpeg.go @@ -116,7 +116,6 @@ func configTemplate(template string) string { // inputTemplate - select input template from YAML config by template name // if query has input param - select another template by this name // if there is no another template - use input param as template -// After input param processed - remove it to allow a correct parseArgs Codec selection func inputTemplate(name, s string, query url.Values) string { var template string if input := query.Get("input"); input != "" { @@ -124,7 +123,6 @@ func inputTemplate(name, s string, query url.Values) string { } else { template = defaults[name] } - query.Del("input") return strings.Replace(template, "{input}", s, 1) } @@ -199,7 +197,7 @@ func parseArgs(s string) *ffmpeg.Args { // 3. `video` params (support multiple) // 4. `audio` params (support multiple) // 5. `hardware` param - if len(query) != 0 { + if query != nil { // 1. Process raw params for FFmpeg for _, raw := range query["raw"] { // support templates https://github.com/AlexxIT/go2rtc/issues/487 @@ -264,8 +262,6 @@ func parseArgs(s string) *ffmpeg.Args { args.AddCodec("-c:v copy") } } - } else { - args.AddCodec("-vn") } // 4. Process audio codecs @@ -281,8 +277,6 @@ func parseArgs(s string) *ffmpeg.Args { args.AddCodec("-c:a copy") } } - } else { - args.AddCodec("-an") } if query["hardware"] != nil { @@ -290,8 +284,13 @@ func parseArgs(s string) *ffmpeg.Args { } } - if args.Codecs == nil { + switch { + case args.Video == 0 && args.Audio == 0: args.AddCodec("-c copy") + case args.Video == 0: + args.AddCodec("-vn") + case args.Audio == 0: + args.AddCodec("-an") } // transcoding to only mjpeg diff --git a/internal/ffmpeg/ffmpeg_test.go b/internal/ffmpeg/ffmpeg_test.go index fe78c7c9..1e2c1191 100644 --- a/internal/ffmpeg/ffmpeg_test.go +++ b/internal/ffmpeg/ffmpeg_test.go @@ -26,6 +26,10 @@ func TestParseArgsFile(t *testing.T) { // [FILE] video will be output for MJPEG to pipe, audio will be skipped args = parseArgs("/media/bbb.mp4#video=mjpeg") require.Equal(t, `ffmpeg -hide_banner -re -i /media/bbb.mp4 -c:v mjpeg -an -f mjpeg -`, args.String()) + + // https://github.com/AlexxIT/go2rtc/issues/509 + args = parseArgs("ffmpeg:test.mp4#raw=-ss 00:00:20") + require.Equal(t, `ffmpeg -hide_banner -re -i ffmpeg:test.mp4 -ss 00:00:20 -c copy -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) } func TestParseArgsDevice(t *testing.T) { @@ -71,39 +75,39 @@ func TestParseArgsIpCam(t *testing.T) { func TestParseArgsAudio(t *testing.T) { // [AUDIO] audio will be transcoded to AAC, video will be skipped args := parseArgs("rtsp:///example.com#audio=aac") - require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -vn -c:a aac -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) + require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -c:a aac -vn -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) // [AUDIO] audio will be transcoded to AAC/16000, video will be skipped args = parseArgs("rtsp:///example.com#audio=aac/16000") - require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -vn -c:a aac -ar:a 16000 -ac:a 1 -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) + require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -c:a aac -ar:a 16000 -ac:a 1 -vn -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) // [AUDIO] audio will be transcoded to OPUS, video will be skipped args = parseArgs("rtsp:///example.com#audio=opus") - require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -vn -c:a libopus -ar:a 48000 -ac:a 2 -application:a voip -af adelay=0|0 -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) + require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -c:a libopus -ar:a 48000 -ac:a 2 -application:a voip -af adelay=0|0 -vn -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) // [AUDIO] audio will be transcoded to PCMU, video will be skipped args = parseArgs("rtsp:///example.com#audio=pcmu") - require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -vn -c:a pcm_mulaw -ar:a 8000 -ac:a 1 -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) + require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -c:a pcm_mulaw -ar:a 8000 -ac:a 1 -vn -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) // [AUDIO] audio will be transcoded to PCMU/16000, video will be skipped args = parseArgs("rtsp:///example.com#audio=pcmu/16000") - require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -vn -c:a pcm_mulaw -ar:a 16000 -ac:a 1 -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) + require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -c:a pcm_mulaw -ar:a 16000 -ac:a 1 -vn -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) // [AUDIO] audio will be transcoded to PCMU/48000, video will be skipped args = parseArgs("rtsp:///example.com#audio=pcmu/48000") - require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -vn -c:a pcm_mulaw -ar:a 48000 -ac:a 1 -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) + require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -c:a pcm_mulaw -ar:a 48000 -ac:a 1 -vn -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) // [AUDIO] audio will be transcoded to PCMA, video will be skipped args = parseArgs("rtsp:///example.com#audio=pcma") - require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -vn -c:a pcm_alaw -ar:a 8000 -ac:a 1 -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) + require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -c:a pcm_alaw -ar:a 8000 -ac:a 1 -vn -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) // [AUDIO] audio will be transcoded to PCMA/16000, video will be skipped args = parseArgs("rtsp:///example.com#audio=pcma/16000") - require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -vn -c:a pcm_alaw -ar:a 16000 -ac:a 1 -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) + require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -c:a pcm_alaw -ar:a 16000 -ac:a 1 -vn -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) // [AUDIO] audio will be transcoded to PCMA/48000, video will be skipped args = parseArgs("rtsp:///example.com#audio=pcma/48000") - require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -vn -c:a pcm_alaw -ar:a 48000 -ac:a 1 -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) + require.Equal(t, `ffmpeg -hide_banner -allowed_media_types audio -fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i rtsp:///example.com -c:a pcm_alaw -ar:a 48000 -ac:a 1 -vn -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`, args.String()) } func TestParseArgsHwVaapi(t *testing.T) {