diff --git a/transcode/testdata/5s.flac b/transcode/testdata/5s.flac new file mode 100644 index 0000000..75b894e Binary files /dev/null and b/transcode/testdata/5s.flac differ diff --git a/transcode/transcode.go b/transcode/transcode.go index d895ef0..d5b9fe1 100644 --- a/transcode/transcode.go +++ b/transcode/transcode.go @@ -46,6 +46,8 @@ var ( Opus128RGLoud = NewProfile("audio/ogg", "opus", 128, `ffmpeg -v 0 -i -ss -map 0:a:0 -vn -b:a -c:a libopus -vbr on -af "aresample=96000:resampler=soxr, volume=replaygain=track:replaygain_preamp=15dB:replaygain_noclip=0, alimiter=level=disabled, asidedata=mode=delete:type=REPLAYGAIN" -metadata replaygain_album_gain= -metadata replaygain_album_peak= -metadata replaygain_track_gain= -metadata replaygain_track_peak= -metadata r128_album_gain= -metadata r128_track_gain= -f opus -`) Opus192 = NewProfile("audio/ogg", "opus", 192, `ffmpeg -v 0 -i -ss -map 0:a:0 -vn -b:a -c:a libopus -vbr on -f opus -`) + + PCM16le = NewProfile("audio/wav", "wav", 0, `ffmpeg -v 0 -i -ss -c:a pcm_s16le -ac 2 -ar 48000 -f s16le -`) ) type BitRate uint // kilobits/s diff --git a/transcode/transcode_test.go b/transcode/transcode_test.go new file mode 100644 index 0000000..5deddb7 --- /dev/null +++ b/transcode/transcode_test.go @@ -0,0 +1,53 @@ +package transcode_test + +import ( + "bytes" + "io" + "net/http" + "net/http/httptest" + "os/exec" + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.senan.xyz/gonic/transcode" +) + +// TestTranscode starts a web server that transcodes a 5s FLAC file to PCM audio. A client +// consumes the result over a 5 second period. +func TestTranscode(t *testing.T) { + t.Parallel() + + if _, err := exec.LookPath("ffmpeg"); err != nil { + t.Skip("ffmpeg not in PATH") + } + + tr := transcode.NewFFmpegTranscoder() + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + require.NoError(t, tr.Transcode(r.Context(), transcode.PCM16le, "testdata/5s.flac", w)) + f, ok := w.(http.Flusher) + require.True(t, ok) + f.Flush() + })) + defer server.Close() + + resp, err := server.Client().Get(server.URL) + require.NoError(t, err) + defer resp.Body.Close() + + const sampleRate, bytesPerSample, numChannels = 48_000, 2, 2 + const bytesPerSec = sampleRate * bytesPerSample * numChannels + + var buf bytes.Buffer + for { + n, err := io.Copy(&buf, io.LimitReader(resp.Body, bytesPerSec)) + require.NoError(t, err) + if n == 0 { + break + } + time.Sleep(1 * time.Second) + } + + // we should have 5 seconds of PCM data + require.Equal(t, 5*bytesPerSec, buf.Len()) +}