package main import ( "errors" "log" "os" "path/filepath" "time" "github.com/faiface/beep" "github.com/faiface/beep/effects" "github.com/faiface/beep/flac" "github.com/faiface/beep/mp3" "github.com/faiface/beep/speaker" "github.com/faiface/beep/wav" ) var globalStopFlag bool = false var playingSongData SongData func playFile(filename string) error { if !fileExists(filename) { return errors.New("File not exists") } f, err := os.Open(filename) if err != nil { log.Fatal(err) } ext := filepath.Ext(filename) var streamer beep.StreamSeekCloser var format beep.Format if ext == ".mp3" { streamer, format, err = mp3.Decode(f) } else if ext == ".flac" { streamer, format, err = flac.Decode(f) } else if ext == ".wav" { streamer, format, err = wav.Decode(f) } else { return errors.New("Not supported file format.") } if err != nil { return err } defer streamer.Close() //Create a new speaker object speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10)) ctrl := &beep.Ctrl{ Streamer: beep.Loop(1, streamer), Paused: false, } volume := &effects.Volume{ Streamer: ctrl, Base: 2, Volume: 0, Silent: false, } //Start the playback counter for loop controls playbackCounter := 0 for deviceStatus.Loop == true || playbackCounter == 0 { done := make(chan bool) speaker.Play(beep.Seq(volume, beep.Callback(func() { done <- true }))) breakOut := false go func() { for { speaker.Lock() ctrl.Paused = !deviceStatus.Playing volume.Volume = deviceStatus.Gain volume.Silent = deviceStatus.Mute speaker.Unlock() //If the playback finished or the global stopflag is set to true if breakOut == true || globalStopFlag == true { globalStopFlag = false speaker.Clear() break } } }() //Playback finish. Breakout of the loop <-done breakOut = true //Play again if loop is enabled. playbackCounter++ } log.Println("Playback finished") deviceStatus.Status = "ready" return nil }