fix: implement audio duration retrieval and add tests

This commit is contained in:
Laisky.Cai
2025-01-08 03:55:02 +00:00
parent c1a0471e73
commit e17017eb4a
8 changed files with 162 additions and 75 deletions

View File

@@ -3,6 +3,7 @@ package helper
import (
"bytes"
"context"
"fmt"
"io"
"os"
"os/exec"
@@ -29,8 +30,15 @@ func SaveTmpFile(filename string, data io.Reader) (string, error) {
// GetAudioDuration returns the duration of an audio file in seconds.
func GetAudioDuration(ctx context.Context, filename string) (float64, error) {
// print file info for debug
fstat, err := os.Stat(filename)
if err != nil {
return 0, errors.Wrap(err, "failed to get audio duration")
}
fmt.Printf("file name: %s, size: %d\n", filename, fstat.Size())
// ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {{input}}
c := exec.CommandContext(ctx, "ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", filename)
c := exec.CommandContext(ctx, "/usr/bin/ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", filename)
output, err := c.Output()
if err != nil {
return 0, errors.Wrap(err, "failed to get audio duration")

View File

@@ -0,0 +1,37 @@
package helper
import (
"context"
"io"
"net/http"
"os"
"testing"
"github.com/stretchr/testify/require"
)
func TestGetAudioDuration(t *testing.T) {
t.Run("should return correct duration for a valid audio file", func(t *testing.T) {
tmpFile, err := os.CreateTemp("", "test_audio*.mp3")
require.NoError(t, err)
defer os.Remove(tmpFile.Name())
// download test audio file
resp, err := http.Get("https://s3.laisky.com/uploads/2025/01/audio-sample.m4a")
require.NoError(t, err)
defer resp.Body.Close()
_, err = io.Copy(tmpFile, resp.Body)
require.NoError(t, err)
require.NoError(t, tmpFile.Close())
duration, err := GetAudioDuration(context.Background(), tmpFile.Name())
require.NoError(t, err)
require.Equal(t, duration, 3.904)
})
t.Run("should return an error for a non-existent file", func(t *testing.T) {
_, err := GetAudioDuration(context.Background(), "non_existent_file.mp3")
require.Error(t, err)
})
}