Files
yellowjacket/backend/metadata/duration.go
T

51 lines
1.1 KiB
Go

package metadata
import (
"fmt"
"os"
"path/filepath"
)
// getTrackDuration returns the duration of an audio file in
// milliseconds together with its audio stream properties. For MP3
// files it uses a fast header-only parser (Xing/VBRI/CBR); for FLAC
// it reads the StreamInfo block; for other formats it falls back to
// beep which is already O(1) for OGG and WAV.
//
// The file position is undefined after this call.
func getTrackDuration(
f *os.File,
) (int64, *AudioProperties, error) {
ext := filepath.Ext(f.Name())
switch ext {
case ".mp3":
return getMP3Duration(f)
case ".flac":
return getFlacDuration(f)
}
// OGG and WAV: beep's Decode() + Len() is already cheap
// (reads headers/metadata only, no full audio decode).
streamer, format, err := DecodeFile(f)
if err != nil {
return 0, nil, fmt.Errorf(
"error decoding file: %w", err,
)
}
lengthMillis := int64(
float64(streamer.Len()*1000) /
float64(format.SampleRate),
)
_ = streamer.Close()
props := &AudioProperties{
SampleRate: int(format.SampleRate),
BitDepth: format.Precision * 8,
Channels: format.NumChannels,
}
return lengthMillis, props, nil
}