avframes/main.go

110 lines
1.8 KiB
Go
Raw Normal View History

2021-01-25 08:03:24 +00:00
package main
import (
"bufio"
2021-01-25 18:35:18 +00:00
"errors"
2021-01-25 08:03:24 +00:00
"fmt"
"io"
"log"
"os"
)
const fname = "/home/rob/share/home-office/example.mp3"
type (
AudioVersionId int
LayerIndex int
header uint32
)
const (
AudioVersionMPEG25 AudioVersionId = iota
AudioVersionReserved
AudioVersionMPEG2
AudioVersionMPEG1
)
2021-01-25 08:03:24 +00:00
2021-01-25 18:35:18 +00:00
const (
LayerIndexReserved LayerIndex = iota
LayerIndexIII
LayerIndexII
LayerIndexI
2021-01-25 18:35:18 +00:00
)
func (h header) AudioVersionId() AudioVersionId {
b := h >> 8
if b&0x18 == 0x18 {
return AudioVersionMPEG1
}
if b&0x10 == 0x10 {
return AudioVersionMPEG2
}
if b&0x8 == 0x8 {
return AudioVersionReserved
}
return AudioVersionMPEG25
}
func (h header) LayerIndex() LayerIndex {
b := h >> 8
if b&0x6 == 0x6 {
return LayerIndexI
}
if b&0x4 == 0x4 {
return LayerIndexII
}
if b&0x2 == 0x2 {
return LayerIndexIII
}
return LayerIndexReserved
}
2021-01-25 08:03:24 +00:00
func main() {
f, err := os.Open(fname)
if err != nil {
log.Fatal(err)
}
bufreader := bufio.NewReader(f)
buf := make([]byte, 4)
2021-01-25 08:03:24 +00:00
var i int
for {
_, err := io.ReadFull(bufreader, buf)
if err != nil {
2021-01-25 18:35:18 +00:00
if err == io.EOF {
break
}
2021-01-25 08:03:24 +00:00
log.Fatal(err)
}
header, err := newHeaderFromBytes(buf)
2021-01-25 08:03:24 +00:00
2021-01-25 18:35:18 +00:00
if err == nil {
fmt.Printf("Got header: %08X, audio version: %d\n", header, header.AudioVersionId())
2021-01-25 18:35:18 +00:00
}
2021-01-25 08:03:24 +00:00
i++
2021-01-25 18:35:18 +00:00
bufreader.Discard(3)
2021-01-25 08:03:24 +00:00
}
}
func newHeaderFromBytes(buf []byte) (header, error) {
2021-01-25 18:35:18 +00:00
if len(buf) < 4 {
return 0, errors.New("insufficient bytes")
}
if buf[0] != 0xFF || buf[1]&0xE0 != 0xE0 {
return 0, errors.New("no header")
}
// always little-endian for now
n := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24
return newHeader(n)
}
2021-01-25 18:35:18 +00:00
// TODO use unsafe here? https://codereview.stackexchange.com/a/60161
func newHeader(n uint32) (header, error) {
2021-01-25 18:35:18 +00:00
return header(n), nil
2021-01-25 08:03:24 +00:00
}