Streaming an audio file from Beep isn't hard at all. Something like this should do (it plays all supported formats, but you can easily figure out how it works):
package main
import (
// Actual audio library
"github.com/faiface/beep"
// Audio codecs
"github.com/faiface/beep/flac"
"github.com/faiface/beep/mp3"
"github.com/faiface/beep/vorbis"
"github.com/faiface/beep/wav"
// Required for actually playing the audio (makes it much easier at least)
"github.com/faiface/beep/speaker"
// Mime-type detection (I do this so we don't need to check audio extensions)
"github.com/zRedShift/mimemagic"
// Formatted output
"fmt"
// Required to open files
"os"
// Parse command-line arguments
"flag"
// Figure out buffer speed
"time"
)
func main() {
// Parse command-line arguments (files)
flag.Parse()
// Figure out our mime type
mime, err := mimemagic.MatchFilePath(flag.Arg(0), -1)
if err != nil {
fmt.Printf("Can't identify mime type for file %s: %s\n", flag.Arg(0), err)
os.Exit(1)
}
switch mime.MediaType() {
// Is this MP3?
case "audio/mpeg":
case "audio/MPA":
case "audio/mpa-robust":
PlayMP3(flag.Arg(0))
// Is this flac?
case "audio/flac":
PlayFLAC(flag.Arg(0))
// Is this vorbis?
case "application/ogg":
case "audio/ogg":
case "audio/vorbis":
case "audio/vorbis-config":
case "audio/x-vorbis+ogg":
PlayVorbis(flag.Arg(0))
// Is this wav?
case "audio/vnd.wave":
case "audio/wave":
case "audio/x-wav":
PlayWAV(flag.Arg(0))
default:
// We don't know!
fmt.Printf("Unknown mime type %s (media %s, subtype %s, comment %s, acronym %s, expanded acronym %s, icon %s, gen. icon %s)\n", mime.MediaType(), mime.Media, mime.Subtype, mime.Comment, mime.Acronym, mime.ExpandedAcronym, mime.Icon, mime.GenericIcon)
os.Exit(1)
}
}
// Below is a lot of repetitive code
// Plays MP3 files
func PlayMP3(file string) {
// Open file
f, err := os.Open(file)
if err != nil {
fmt.Printf("Can't open file %s: %s\n", file, err)
os.Exit(1)
}
// Parse file codec data
streamer, format, err := mp3.Decode(f)
if err != nil {
fmt.Printf("Can't decode MP3 file %s: %s\n", err)
os.Exit(1)
}
defer streamer.Close()
fmt.Printf("Decoded MP3 file with sr %d, %d channels, %d precision\n", format.SampleRate, format.NumChannels, format.Precision)
// Initialize speaker
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
// Wait until we're done playing (speaker.Play is asynchronous)
done := make(chan bool)
speaker.Play(beep.Seq(streamer, beep.Callback(func() {
done <- true
})))
<-done
}
// Pretty much the same as above
func PlayFLAC(file string) {
f, err := os.Open(file)
if err != nil {
fmt.Printf("Can't open file %s: %s\n", file, err)
os.Exit(1)
}
streamer, format, err := flac.Decode(f)
if err != nil {
fmt.Printf("Can't decode FLAC file %s: %s\n", err)
os.Exit(1)
}
defer streamer.Close()
fmt.Printf("Decoded FLAC file with sr %d, %d channels, %d precision\n", format.SampleRate, format.NumChannels, format.Precision)
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
done := make(chan bool)
speaker.Play(beep.Seq(streamer, beep.Callback(func() {
done <- true
})))
<-done
}
func PlayVorbis(file string) {
f, err := os.Open(file)
if err != nil {
fmt.Printf("Can't open file %s: %s\n", file, err)
os.Exit(1)
}
streamer, format, err := vorbis.Decode(f)
if err != nil {
fmt.Printf("Can't decode Vorbis file %s: %s\n", err)
os.Exit(1)
}
defer streamer.Close()
fmt.Printf("Decoded Vorbis file with sr %d, %d channels, %d precision\n", format.SampleRate, format.NumChannels, format.Precision)
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
done := make(chan bool)
speaker.Play(beep.Seq(streamer, beep.Callback(func() {
done <- true
})))
<-done
}
func PlayWAV(file string) {
f, err := os.Open(file)
if err != nil {
fmt.Printf("Can't open file %s: %s\n", file, err)
os.Exit(1)
}
streamer, format, err := wav.Decode(f)
if err != nil {
fmt.Printf("Can't decode WAV file %s: %s\n", err)
os.Exit(1)
}
defer streamer.Close()
fmt.Printf("Decoded WAV file with sr %d, %d channels, %d precision\n", format.SampleRate, format.NumChannels, format.Precision)
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
done := make(chan bool)
speaker.Play(beep.Seq(streamer, beep.Callback(func() {
done <- true
})))
<-done
}
You can see what this code does in the beep tutorial, its where I figured it out. (heh, this code could definitely be drastically simplified.)
"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question." — Charles Babbage.
My Github