reveil/main.go

125 lines
2.2 KiB
Go

package main
import (
"flag"
"io"
"log"
"math/rand"
"net/http"
"os"
"time"
"github.com/faiface/beep"
"github.com/faiface/beep/effects"
"github.com/faiface/beep/speaker"
"github.com/faiface/beep/flac"
"github.com/faiface/beep/mp3"
)
const (
SampleRate = beep.SampleRate(48000)
)
func loadFile(path string) (s beep.Streamer, err error) {
var format beep.Format
for _, decoder := range []func(io.ReadCloser) (beep.StreamSeekCloser, beep.Format, error){flac.Decode, mp3.Decode} {
var fd *os.File
fd, err = os.Open(path)
if err != nil {
return
}
// Try decoding as FLAC
s, format, err = decoder(fd)
if err == nil {
break
}
}
if err != nil {
return
}
if format.SampleRate != SampleRate {
s = beep.Resample(3, format.SampleRate, SampleRate, s)
}
return
}
func main() {
var bind = flag.String("bind", "127.0.0.1:8080", "Bind port/socket")
flag.Parse()
if len(flag.Args()) < 2 {
log.Println("missing required argument: input file name")
return
}
rand.Seed(time.Now().Unix())
playlist := []beep.Streamer{}
// Load playlist
for _, arg := range flag.Args() {
s, err := loadFile(arg)
if err != nil {
log.Printf("Unable to load %s: %s", arg, err)
}
playlist = append(playlist, s)
}
// Shuffle the playlist
rand.Shuffle(len(playlist), func(i, j int) {
playlist[i], playlist[j] = playlist[j], playlist[i]
})
// Create infinite stream
playedItem := -1
stream := beep.Iterate(func() beep.Streamer {
playedItem += 1
if playedItem > len(playlist) {
playedItem = 0
}
return playlist[playedItem]
})
stop := make(chan struct{})
// Prepare stop via http
http.HandleFunc("/stop", func(w http.ResponseWriter, _ *http.Request) {
w.Write([]byte("Ok"))
close(stop)
})
go func() {
log.Fatal(http.ListenAndServe(*bind, nil))
}()
// Prepare sound player
speaker.Init(SampleRate, SampleRate.N(time.Second/10))
volume := &effects.Volume{stream, 10, -2, false}
speaker.Play(volume)
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
launched := time.Now()
loop:
for {
select{
case <-stop:
break loop
case t := <-ticker.C:
if volume.Volume < 0 {
volume.Volume += 0.01
}
if t.Sub(launched) > 1 * time.Hour {
break loop
}
}
}
}