Skip to content

Commit

Permalink
Update ffmpeg pkg for reading files and parsing ffmpeg version
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexxIT committed May 24, 2024
1 parent ff39e2e commit bf3f81c
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 46 deletions.
9 changes: 5 additions & 4 deletions internal/ffmpeg/ffmpeg.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ var defaults = map[string]string{
"global": "-hide_banner",

// inputs
"file": "-re -readrate_initial_burst 0.001 -i {input}",
"file": "-re -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}",

Expand Down Expand Up @@ -151,9 +151,10 @@ func inputTemplate(name, s string, query url.Values) string {
func parseArgs(s string) *ffmpeg.Args {
// init FFmpeg arguments
args := &ffmpeg.Args{
Bin: defaults["bin"],
Global: defaults["global"],
Output: defaults["output"],
Bin: defaults["bin"],
Global: defaults["global"],
Output: defaults["output"],
Version: verAV,
}

var query url.Values
Expand Down
21 changes: 21 additions & 0 deletions internal/ffmpeg/ffmpeg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ffmpeg
import (
"testing"

"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -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())
})
}
}
61 changes: 20 additions & 41 deletions internal/ffmpeg/version.go
Original file line number Diff line number Diff line change
@@ -1,68 +1,47 @@
package ffmpeg

import (
"bytes"
"errors"
"os/exec"
"strings"
"sync"

"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
"github.com/rs/zerolog/log"
)

var checkMu sync.Mutex
var checkErr error
var checkVer string

const (
FFmpeg50 = "59. 16"
FFmpeg51 = "59. 27"
FFmpeg60 = "60. 3"
FFmpeg61 = "60. 16"
FFmpeg70 = "61. 1"
)
var verMu sync.Mutex
var verErr error
var verFF string
var verAV string

func Version() (string, error) {
checkMu.Lock()
defer checkMu.Unlock()
verMu.Lock()
defer verMu.Unlock()

if checkVer != "" {
return checkVer, checkErr
if verFF != "" {
return verFF, verErr
}

cmd := exec.Command(defaults["bin"], "-version")
b, err := cmd.Output()
if err != nil {
checkVer = "-"
checkErr = err
return checkVer, checkErr
verFF = "-"
verErr = err
return verFF, verErr
}

if len(b) < 100 {
checkVer = "?"
return checkVer, nil
}
verFF, verAV = ffmpeg.ParseVersion(b)

// ffmpeg version n7.0-30-g8b0fe91754-20240520 Copyright (c) 2000-2024 the FFmpeg developers
b = b[15:]
if i := bytes.IndexByte(b, ' '); i > 0 {
checkVer = string(b[:i])
if verFF == "" {
verFF = "?"
}

// libavformat 60. 16.100 / 60. 16.100
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}"
}
// better to compare libavformat, because nightly/master builds
if verAV != "" && verAV < ffmpeg.Version50 {
verErr = errors.New("ffmpeg: unsupported version: " + verFF)
}

log.Debug().Str("version", checkVer).Msgf("[ffmpeg] bin")
log.Debug().Str("version", verFF).Str("libavformat", verAV).Msgf("[ffmpeg] bin")

return checkVer, nil
return verFF, verErr
}
2 changes: 1 addition & 1 deletion internal/ffmpeg/virtual/virtual.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func GetInputTTS(src string) string {
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
// awb, kal, kal16, rms, slt
Expand Down
30 changes: 30 additions & 0 deletions pkg/ffmpeg/ffmpeg.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,23 @@ import (
"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 {
Bin string // ffmpeg
Global string // -hide_banner -v error
Input string // -re -stream_loop -1 -i /media/bunny.mp4
Codecs []string // -c:v libx264 -g:v 30 -preset:v ultrafast -tune:v zerolatency
Filters []string // scale=1920:1080
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
}
Expand Down Expand Up @@ -52,6 +62,11 @@ func (a *Args) String() string {
}

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)

multimode := a.Video > 1 || a.Audio > 1
Expand Down Expand Up @@ -91,3 +106,18 @@ func (a *Args) String() 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
}

0 comments on commit bf3f81c

Please sign in to comment.