core/app/fftest/main.go
2025-04-09 14:06:20 +02:00

181 lines
3.4 KiB
Go

package main
import (
"encoding/json"
"flag"
"fmt"
"log/slog"
"os"
"sync"
"github.com/datarhei/core/v16/ffmpeg"
"github.com/datarhei/core/v16/ffmpeg/parse"
"github.com/datarhei/core/v16/resources"
"github.com/sergi/go-diff/diffmatchpatch"
)
type fftest struct {
name string
what string
init []string
test []string
cleanup []string
}
func main() {
abinary := ""
bbinary := ""
flag.StringVar(&abinary, "aversion", "", "version A of ffmpeg")
flag.StringVar(&bbinary, "bversion", "", "version B of ffmpeg")
flag.Parse()
if len(abinary) == 0 || len(bbinary) == 0 {
slog.Error("aversion and bversion must be given")
os.Exit(1)
}
r, err := resources.New(resources.Config{})
if err != nil {
slog.Error("failed resources", "error", err)
os.Exit(1)
}
a, err := ffmpeg.New(ffmpeg.Config{
Binary: abinary,
Resource: r,
})
if err != nil {
slog.Error("failed ffmpeg binary", "error", err)
os.Exit(1)
}
b, err := ffmpeg.New(ffmpeg.Config{
Binary: bbinary,
Resource: r,
})
if err != nil {
slog.Error("failed ffmpeg binary", "error", err)
os.Exit(1)
}
tests := []fftest{
{
name: "version",
test: []string{
"-i",
},
what: "prelude",
},
{
name: "final duration with vframes",
init: []string{
"-t", "30", "-f", "lavfi", "-i", "testsrc2", "-codec:v", "libx264", "-preset", "ultrafast", "-y", "file.mp4",
},
test: []string{
"-i", "file.mp4", "-codec:v", "copy", "-f", "null", "-", "-vframes", "1", "-f", "null", "-",
},
cleanup: []string{"file.mp4"},
what: "progress",
},
}
dmp := diffmatchpatch.New()
for _, test := range tests {
fmt.Printf("---- %s ----\n", test.name)
pa, err := run_test(a, test)
if err != nil {
fmt.Printf("test %s with %s failed: %v\n", test.name, abinary, err)
continue
}
pb, err := run_test(b, test)
if err != nil {
fmt.Printf("test %s with %s failed: %v\n", test.name, bbinary, err)
continue
}
jpa, _ := json.MarshalIndent(pa, "", " ")
jpb, _ := json.MarshalIndent(pb, "", " ")
diffs := dmp.DiffMain(string(jpa), string(jpb), false)
fmt.Println(dmp.DiffPrettyText(diffs))
}
}
func run_test(ff ffmpeg.FFmpeg, test fftest) (any, error) {
defer func() {
for _, file := range test.cleanup {
os.Remove(file)
}
}()
parser := parse.New(parse.Config{
LogHistory: 1,
})
wg := sync.WaitGroup{}
if len(test.init) != 0 {
wg.Add(1)
p, err := ff.New(ffmpeg.ProcessConfig{
Args: test.init,
Parser: parse.New(parse.Config{}),
OnExit: func(string) {
wg.Done()
},
})
if err != nil {
return parse.Progress{}, err
}
p.Start()
wg.Wait()
status := p.Status()
if status.States.Finished != 1 {
return parse.Progress{}, fmt.Errorf("init failed: %s", parser.LastLogline())
}
}
wg.Add(1)
p, err := ff.New(ffmpeg.ProcessConfig{
Args: test.test,
Parser: parser,
OnExit: func(string) {
wg.Done()
},
})
if err != nil {
return parse.Progress{}, err
}
p.Start()
wg.Wait()
status := p.Status()
if status.States.Finished != 1 {
return parse.Progress{}, fmt.Errorf("test failed: %s", parser.LastLogline())
}
report := parser.ReportHistory()
if len(report) < 1 {
return parse.Progress{}, fmt.Errorf("no report available")
}
if test.what == "progress" {
return report[len(report)-1].Progress, nil
} else if test.what == "prelude" {
return report[len(report)-1].Prelude, nil
}
return parse.Progress{}, fmt.Errorf("no proper what provided")
}