ffmpeg_test.go (2031B)
1 package test 2 3 import ( 4 "bytes" 5 "os/exec" 6 "testing" 7 8 "git.sr.ht/~jackmordaunt/nativeaudio" 9 ) 10 11 // requireTools skips the test unless every named program is on PATH. 12 func requireTools(t *testing.T, names ...string) { 13 t.Helper() 14 for _, n := range names { 15 if _, err := exec.LookPath(n); err != nil { 16 t.Skipf("%s not installed", n) 17 } 18 } 19 } 20 21 // TestFFmpegLoadAndDecode exercises the ffmpeg fallback on every 22 // platform that has ffmpeg, regardless of which native decoder is in use. 23 // The reference PCM was produced by ffmpeg, so output should match within 24 // the same tolerance as the native decoders, and Load and Decode must 25 // agree with each other exactly. 26 func TestFFmpegLoadAndDecode(t *testing.T) { 27 requireTools(t, "ffmpeg", "ffprobe") 28 want := nativeaudio.Format{SampleRate: 44100, Channels: 2, BytesPerSample: 2} 29 30 loaded, f, err := nativeaudio.FFmpegLoad("compressed.m4a") 31 if err != nil { 32 t.Fatalf("FFmpegLoad: %v", err) 33 } 34 if f != want { 35 t.Fatalf("FFmpegLoad format: want %+v, got %+v", want, f) 36 } 37 // The reference PCM came from one particular ffmpeg build, and 38 // versions disagree about how many priming samples an AAC stream 39 // contributes, so the lengths need not match to the byte. CI found 40 // this: a different ffmpeg produced 3068 fewer bytes out of five 41 // megabytes. Check the length is close enough that a genuinely wrong 42 // decode still fails, and leave sample-exact comparison to the native 43 // backends, which are compared against their own reference. 44 if diff := abs(len(loaded) - len(uncompressed)); diff > len(uncompressed)/100 { 45 t.Errorf("FFmpegLoad produced %d bytes, reference has %d, differing by more than one percent", 46 len(loaded), len(uncompressed)) 47 } 48 49 decoded, f, err := nativeaudio.FFmpegDecode(compressed) 50 if err != nil { 51 t.Fatalf("FFmpegDecode: %v", err) 52 } 53 if f != want { 54 t.Fatalf("FFmpegDecode format: want %+v, got %+v", want, f) 55 } 56 if !bytes.Equal(decoded, loaded) { 57 t.Fatal("FFmpegDecode output differs from FFmpegLoad output for the same data") 58 } 59 }