playback.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package main
  2. import (
  3. "errors"
  4. "log"
  5. "os"
  6. "path/filepath"
  7. "time"
  8. "github.com/faiface/beep"
  9. "github.com/faiface/beep/effects"
  10. "github.com/faiface/beep/flac"
  11. "github.com/faiface/beep/mp3"
  12. "github.com/faiface/beep/speaker"
  13. "github.com/faiface/beep/wav"
  14. )
  15. var globalStopFlag bool = false
  16. var playingSongData SongData
  17. func playFile(filename string) error {
  18. if !fileExists(filename) {
  19. return errors.New("File not exists")
  20. }
  21. f, err := os.Open(filename)
  22. if err != nil {
  23. log.Fatal(err)
  24. }
  25. ext := filepath.Ext(filename)
  26. var streamer beep.StreamSeekCloser
  27. var format beep.Format
  28. if ext == ".mp3" {
  29. streamer, format, err = mp3.Decode(f)
  30. } else if ext == ".flac" {
  31. streamer, format, err = flac.Decode(f)
  32. } else if ext == ".wav" {
  33. streamer, format, err = wav.Decode(f)
  34. } else {
  35. return errors.New("Not supported file format.")
  36. }
  37. if err != nil {
  38. return err
  39. }
  40. defer streamer.Close()
  41. //Create a new speaker object
  42. speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
  43. ctrl := &beep.Ctrl{
  44. Streamer: beep.Loop(1, streamer),
  45. Paused: false,
  46. }
  47. volume := &effects.Volume{
  48. Streamer: ctrl,
  49. Base: 2,
  50. Volume: 0,
  51. Silent: false,
  52. }
  53. //Start the playback counter for loop controls
  54. playbackCounter := 0
  55. for deviceStatus.Loop == true || playbackCounter == 0 {
  56. done := make(chan bool)
  57. speaker.Play(beep.Seq(volume, beep.Callback(func() {
  58. done <- true
  59. })))
  60. breakOut := false
  61. go func() {
  62. for {
  63. speaker.Lock()
  64. ctrl.Paused = !deviceStatus.Playing
  65. volume.Volume = deviceStatus.Gain
  66. volume.Silent = deviceStatus.Mute
  67. speaker.Unlock()
  68. //If the playback finished or the global stopflag is set to true
  69. if breakOut == true || globalStopFlag == true {
  70. globalStopFlag = false
  71. speaker.Clear()
  72. break
  73. }
  74. }
  75. }()
  76. //Playback finish. Breakout of the loop
  77. <-done
  78. breakOut = true
  79. //Play again if loop is enabled.
  80. playbackCounter++
  81. }
  82. log.Println("Playback finished")
  83. deviceStatus.Status = "ready"
  84. return nil
  85. }