59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
func detectAudioFormat(path string) (string, error) {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer f.Close()
|
|
b := make([]byte, 64*1024)
|
|
n, err := f.Read(b)
|
|
if err != nil && err != io.EOF {
|
|
return "", err
|
|
}
|
|
b = b[:n]
|
|
if len(b) >= 4 && string(b[:4]) == "fLaC" {
|
|
return "flac", nil
|
|
}
|
|
if len(b) >= 12 && string(b[:4]) == "RIFF" && string(b[8:12]) == "WAVE" {
|
|
return "wav", nil
|
|
}
|
|
if len(b) >= 12 && string(b[:4]) == "FORM" && (string(b[8:12]) == "AIFF" || string(b[8:12]) == "AIFC") {
|
|
return "aiff", nil
|
|
}
|
|
if len(b) >= 4 && string(b[:4]) == "OggS" {
|
|
return "ogg", nil
|
|
}
|
|
if len(b) >= 12 && string(b[4:8]) == "ftyp" {
|
|
return "m4a", nil
|
|
}
|
|
start := 0
|
|
if len(b) >= 10 && string(b[:3]) == "ID3" {
|
|
size := int(b[6]&0x7f)<<21 | int(b[7]&0x7f)<<14 | int(b[8]&0x7f)<<7 | int(b[9]&0x7f)
|
|
start = 10 + size
|
|
if start > len(b) {
|
|
start = 10
|
|
}
|
|
}
|
|
for i := start; i+4 <= len(b) && i < start+4096; i++ {
|
|
if b[i] == 0xff && b[i+1]&0xe0 == 0xe0 {
|
|
h := binary.BigEndian.Uint32(b[i : i+4])
|
|
layer := (h >> 17) & 3
|
|
if layer == 1 {
|
|
return "mp3", nil
|
|
}
|
|
if b[i+1]&0x06 == 0x06 {
|
|
return "aac", nil
|
|
}
|
|
}
|
|
}
|
|
return "", errors.New("unknown audio format")
|
|
}
|