2023-08-19 10:35:09 +02:00
|
|
|
package player
|
2023-08-05 15:17:24 +02:00
|
|
|
|
|
|
|
import (
|
2023-08-19 10:35:09 +02:00
|
|
|
"net/http"
|
2023-08-05 15:17:24 +02:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/faiface/beep"
|
2023-08-19 10:35:09 +02:00
|
|
|
"github.com/faiface/beep/mp3"
|
2023-08-05 15:17:24 +02:00
|
|
|
"github.com/faiface/beep/speaker"
|
|
|
|
)
|
|
|
|
|
2023-08-19 10:35:09 +02:00
|
|
|
type Station struct {
|
|
|
|
Name string
|
|
|
|
URL string
|
|
|
|
}
|
|
|
|
|
2023-08-05 15:17:24 +02:00
|
|
|
type Player struct {
|
|
|
|
oldStreamer beep.StreamCloser
|
|
|
|
oldCtrl *beep.Ctrl
|
|
|
|
mixer *beep.Mixer
|
2023-08-19 11:10:35 +02:00
|
|
|
sr beep.SampleRate
|
2023-08-05 15:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewPlayer() *Player {
|
|
|
|
return &Player{
|
|
|
|
mixer: &beep.Mixer{},
|
2023-08-19 11:10:35 +02:00
|
|
|
sr: beep.SampleRate(48000),
|
2023-08-05 15:17:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Player) Init() error {
|
2023-08-19 11:10:35 +02:00
|
|
|
|
|
|
|
if err := speaker.Init(p.sr, p.sr.N(time.Second/10)); err != nil {
|
2023-08-05 15:17:24 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
speaker.Play(p.mixer)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-08-19 10:35:09 +02:00
|
|
|
func (p *Player) Select(station Station) error {
|
|
|
|
res, err := http.Get(station.URL)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-08-19 11:10:35 +02:00
|
|
|
streamer, format, err := mp3.Decode(res.Body)
|
2023-08-19 10:35:09 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-08-19 11:10:35 +02:00
|
|
|
resampled := Resample(4, format.SampleRate, p.sr, streamer)
|
|
|
|
|
|
|
|
p.PlayStream(resampled)
|
2023-08-19 10:35:09 +02:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Player) PlayStream(streamer beep.StreamCloser) {
|
2023-08-05 15:17:24 +02:00
|
|
|
ctrl := &beep.Ctrl{
|
|
|
|
Streamer: streamer,
|
|
|
|
}
|
|
|
|
p.mixer.Add(ctrl)
|
|
|
|
|
|
|
|
speaker.Lock()
|
|
|
|
|
|
|
|
if p.oldCtrl != nil {
|
|
|
|
p.oldCtrl.Paused = true
|
|
|
|
p.oldCtrl.Streamer = nil
|
|
|
|
p.oldStreamer.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
ctrl.Paused = true
|
|
|
|
ctrl.Streamer = streamer
|
|
|
|
ctrl.Paused = false
|
|
|
|
|
|
|
|
speaker.Unlock()
|
|
|
|
|
|
|
|
p.oldCtrl = ctrl
|
|
|
|
p.oldStreamer = streamer
|
|
|
|
}
|