181 lines
3.4 KiB
Go
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")
|
|
}
|