stillbox/cmd/calls/audio.go
2024-08-04 23:50:14 -04:00

78 lines
1.2 KiB
Go

package main
import (
"fmt"
"time"
"dynatron.me/x/stillbox/internal/minimp3"
"github.com/hajimehoshi/oto"
)
type Player struct {
ctx *oto.Context
sampleRate int
channels int
}
func NewPlayer() *Player {
p := &Player{}
return p
}
func (p *Player) initOto(samp, channels int) error {
if samp != p.sampleRate || channels != p.channels {
if p.ctx != nil {
err := p.ctx.Close()
if err != nil {
return err
}
}
var err error
if p.ctx, err = oto.NewContext(samp, channels, 2, 1024); err != nil {
return err
}
}
return nil
}
func (p *Player) playMP3(audio []byte) error {
var dec *minimp3.Decoder
var data []byte
var err error
if dec, data, err = minimp3.DecodeFull(audio); err != nil {
return err
}
err = p.initOto(dec.SampleRate, dec.Channels)
if err != nil {
return err
}
var player = p.ctx.NewPlayer()
player.Write(data)
<-time.After(time.Second)
dec.Close()
if err = player.Close(); err != nil {
return err
}
return nil
}
func (p *Player) Play(audio []byte, mimeType string) error {
switch mimeType {
case "audio/mpeg":
return p.playMP3(audio)
case "audio/wav":
panic("wav not implemented yet")
default:
return fmt.Errorf("unknown format %s", mimeType)
}
return nil
}