avframes/main.go

76 lines
1.6 KiB
Go

package main
import (
"bufio"
"errors"
"fmt"
"io"
"log"
"os"
)
const fname = "/home/rob/home-office/example.mp3"
const (
maskSync = 0b11111111111000000000000000000000
maskVersion = 0b00000000000110000000000000000000
maskLayer = 0b00000000000001100000000000000000
maskProtection = 0b00000000000000010000000000000000
maskBitrate = 0b00000000000000001111000000000000
maskSamplerate = 0b00000000000000000000110000000000
maskPadding = 0b00000000000000000000001000000000
maskPrivate = 0b00000000000000000000000100000000
maskChannelMode = 0b00000000000000000000000011000000
maskExtension = 0b00000000000000000000000000110000
maskCopyright = 0b00000000000000000000000000001000
maskOriginal = 0b00000000000000000000000000000100
maskEmphasis = 0b00000000000000000000000000000011
)
type header uint32
func main() {
f, err := os.Open(fname)
if err != nil {
log.Fatal(err)
}
bufreader := bufio.NewReader(f)
buf := make([]byte, 4)
var i int
for {
_, err := io.ReadFull(bufreader, buf)
if err != nil {
if err == io.EOF {
break
}
log.Fatal(err)
}
header, err := newHeader(buf)
if err == nil {
fmt.Printf("Got header: %08X\n", header)
}
i++
bufreader.Discard(3)
}
}
// TODO use unsafe here? https://codereview.stackexchange.com/a/60161
func newHeader(buf []byte) (header, error) {
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 header(n), nil
}