mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-09-26 20:31:11 +08:00
Update ffmpeg pkg for reading files and parsing ffmpeg version
This commit is contained in:
@@ -49,7 +49,7 @@ var defaults = map[string]string{
|
|||||||
"global": "-hide_banner",
|
"global": "-hide_banner",
|
||||||
|
|
||||||
// inputs
|
// inputs
|
||||||
"file": "-re -readrate_initial_burst 0.001 -i {input}",
|
"file": "-re -i {input}",
|
||||||
"http": "-fflags nobuffer -flags low_delay -i {input}",
|
"http": "-fflags nobuffer -flags low_delay -i {input}",
|
||||||
"rtsp": "-fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i {input}",
|
"rtsp": "-fflags nobuffer -flags low_delay -timeout 5000000 -user_agent go2rtc/ffmpeg -rtsp_flags prefer_tcp -i {input}",
|
||||||
|
|
||||||
@@ -151,9 +151,10 @@ func inputTemplate(name, s string, query url.Values) string {
|
|||||||
func parseArgs(s string) *ffmpeg.Args {
|
func parseArgs(s string) *ffmpeg.Args {
|
||||||
// init FFmpeg arguments
|
// init FFmpeg arguments
|
||||||
args := &ffmpeg.Args{
|
args := &ffmpeg.Args{
|
||||||
Bin: defaults["bin"],
|
Bin: defaults["bin"],
|
||||||
Global: defaults["global"],
|
Global: defaults["global"],
|
||||||
Output: defaults["output"],
|
Output: defaults["output"],
|
||||||
|
Version: verAV,
|
||||||
}
|
}
|
||||||
|
|
||||||
var query url.Values
|
var query url.Values
|
||||||
|
@@ -3,6 +3,7 @@ package ffmpeg
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -292,3 +293,23 @@ func TestDrawText(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVersion(t *testing.T) {
|
||||||
|
verAV = ffmpeg.Version61
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
source string
|
||||||
|
expect string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
source: "/media/bbb.mp4",
|
||||||
|
expect: `ffmpeg -hide_banner -readrate_initial_burst 0.001 -re -i /media/bbb.mp4 -c copy -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {output}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
args := parseArgs(test.source)
|
||||||
|
require.Equal(t, test.expect, args.String())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1,68 +1,47 @@
|
|||||||
package ffmpeg
|
package ffmpeg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var checkMu sync.Mutex
|
var verMu sync.Mutex
|
||||||
var checkErr error
|
var verErr error
|
||||||
var checkVer string
|
var verFF string
|
||||||
|
var verAV string
|
||||||
const (
|
|
||||||
FFmpeg50 = "59. 16"
|
|
||||||
FFmpeg51 = "59. 27"
|
|
||||||
FFmpeg60 = "60. 3"
|
|
||||||
FFmpeg61 = "60. 16"
|
|
||||||
FFmpeg70 = "61. 1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Version() (string, error) {
|
func Version() (string, error) {
|
||||||
checkMu.Lock()
|
verMu.Lock()
|
||||||
defer checkMu.Unlock()
|
defer verMu.Unlock()
|
||||||
|
|
||||||
if checkVer != "" {
|
if verFF != "" {
|
||||||
return checkVer, checkErr
|
return verFF, verErr
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command(defaults["bin"], "-version")
|
cmd := exec.Command(defaults["bin"], "-version")
|
||||||
b, err := cmd.Output()
|
b, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
checkVer = "-"
|
verFF = "-"
|
||||||
checkErr = err
|
verErr = err
|
||||||
return checkVer, checkErr
|
return verFF, verErr
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(b) < 100 {
|
verFF, verAV = ffmpeg.ParseVersion(b)
|
||||||
checkVer = "?"
|
|
||||||
return checkVer, nil
|
if verFF == "" {
|
||||||
|
verFF = "?"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ffmpeg version n7.0-30-g8b0fe91754-20240520 Copyright (c) 2000-2024 the FFmpeg developers
|
// better to compare libavformat, because nightly/master builds
|
||||||
b = b[15:]
|
if verAV != "" && verAV < ffmpeg.Version50 {
|
||||||
if i := bytes.IndexByte(b, ' '); i > 0 {
|
verErr = errors.New("ffmpeg: unsupported version: " + verFF)
|
||||||
checkVer = string(b[:i])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// libavformat 60. 16.100 / 60. 16.100
|
log.Debug().Str("version", verFF).Str("libavformat", verAV).Msgf("[ffmpeg] bin")
|
||||||
if i := strings.Index(string(b), "libavformat"); i > 0 {
|
|
||||||
// better to compare libavformat, because nightly/master builds
|
|
||||||
libav := string(b[i+15 : i+25])
|
|
||||||
if libav < FFmpeg50 {
|
|
||||||
checkErr = errors.New("ffmpeg: unsupported version: " + checkVer)
|
|
||||||
return checkVer, checkErr
|
|
||||||
}
|
|
||||||
if libav < FFmpeg61 && strings.Contains(defaults["file"], "readrate_initial_burst") {
|
|
||||||
defaults["file"] = "-re -i {input}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug().Str("version", checkVer).Msgf("[ffmpeg] bin")
|
return verFF, verErr
|
||||||
|
|
||||||
return checkVer, nil
|
|
||||||
}
|
}
|
||||||
|
@@ -67,7 +67,7 @@ func GetInputTTS(src string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
input := `-re -readrate_initial_burst 0.001 -f lavfi -i "flite=text='` + query.Get("text") + `'`
|
input := `-re -f lavfi -i "flite=text='` + query.Get("text") + `'`
|
||||||
|
|
||||||
// ffmpeg -f lavfi -i flite=list_voices=1
|
// ffmpeg -f lavfi -i flite=list_voices=1
|
||||||
// awb, kal, kal16, rms, slt
|
// awb, kal, kal16, rms, slt
|
||||||
|
@@ -6,6 +6,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// correlation of libavformat versions with ffmpeg versions
|
||||||
|
const (
|
||||||
|
Version50 = "59. 16"
|
||||||
|
Version51 = "59. 27"
|
||||||
|
Version60 = "60. 3"
|
||||||
|
Version61 = "60. 16"
|
||||||
|
Version70 = "61. 1"
|
||||||
|
)
|
||||||
|
|
||||||
type Args struct {
|
type Args struct {
|
||||||
Bin string // ffmpeg
|
Bin string // ffmpeg
|
||||||
Global string // -hide_banner -v error
|
Global string // -hide_banner -v error
|
||||||
@@ -13,6 +22,7 @@ type Args struct {
|
|||||||
Codecs []string // -c:v libx264 -g:v 30 -preset:v ultrafast -tune:v zerolatency
|
Codecs []string // -c:v libx264 -g:v 30 -preset:v ultrafast -tune:v zerolatency
|
||||||
Filters []string // scale=1920:1080
|
Filters []string // scale=1920:1080
|
||||||
Output string // -f rtsp {output}
|
Output string // -f rtsp {output}
|
||||||
|
Version string // libavformat version, it's more reliable than the ffmpeg version
|
||||||
|
|
||||||
Video, Audio int // count of Video and Audio params
|
Video, Audio int // count of Video and Audio params
|
||||||
}
|
}
|
||||||
@@ -52,6 +62,11 @@ func (a *Args) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
b.WriteByte(' ')
|
b.WriteByte(' ')
|
||||||
|
// starting from FFmpeg 6.1 readrate=1 has default initial bust 0.5 sec
|
||||||
|
// it might make us miss the first couple seconds of the file
|
||||||
|
if strings.HasPrefix(a.Input, "-re ") && a.Version >= Version61 {
|
||||||
|
b.WriteString("-readrate_initial_burst 0.001 ")
|
||||||
|
}
|
||||||
b.WriteString(a.Input)
|
b.WriteString(a.Input)
|
||||||
|
|
||||||
multimode := a.Video > 1 || a.Audio > 1
|
multimode := a.Video > 1 || a.Audio > 1
|
||||||
@@ -91,3 +106,18 @@ func (a *Args) String() string {
|
|||||||
|
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ParseVersion(b []byte) (ffmpeg string, libavformat string) {
|
||||||
|
if len(b) > 100 {
|
||||||
|
// ffmpeg version n7.0-30-g8b0fe91754-20240520 Copyright (c) 2000-2024 the FFmpeg developers
|
||||||
|
if i := bytes.IndexByte(b[15:], ' '); i > 0 {
|
||||||
|
ffmpeg = string(b[15 : 15+i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// libavformat 60. 16.100 / 60. 16.100
|
||||||
|
if i := strings.Index(string(b), "libavformat"); i > 0 {
|
||||||
|
libavformat = string(b[i+15 : i+25])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user