Refactored track_player.go

This commit is contained in:
strNophix 2022-03-21 18:51:04 +01:00
parent bdefd6d2fb
commit 7905937c37
3 changed files with 50 additions and 40 deletions

View File

@ -1,10 +1,10 @@
package gomus package gomus
import ( import (
"fmt" "time"
"os"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/faiface/beep/speaker"
) )
var ( var (
@ -20,10 +20,10 @@ type Model struct {
cursor int cursor int
currentlyPlaying int currentlyPlaying int
trackPlayer TrackPlayer
trackIndex trackIndex
trackPlayerView trackPlayerView trackPlayerView
} }
func NewModel(args ModelArgs) Model { func NewModel(args ModelArgs) Model {
@ -35,7 +35,7 @@ func NewModel(args ModelArgs) Model {
currentlyPlaying: 0, currentlyPlaying: 0,
trackIndex: ti, trackIndex: ti,
trackPlayer: trackPlayer{}, TrackPlayer: TrackPlayer{},
trackPlayerView: tpv, trackPlayerView: tpv,
} }
@ -55,12 +55,15 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case tea.KeyMsg: case tea.KeyMsg:
switch msg.String() { switch msg.String() {
case "ctrl+c", "q": case "ctrl+c", "q":
m.trackPlayer.close() m.TrackPlayer.Close()
return m, tea.Quit return m, tea.Quit
case "enter": case "enter":
t := m.trackPlayerView.trackList.SelectedItem().(track) t := m.trackPlayerView.trackList.SelectedItem().(track)
cmds = append(cmds, newTrackChangeCmd(t)) cmds = append(cmds, newTrackChangeCmd(t))
m.trackPlayer.play(t.getReader()) stream, format, err := t.GetStream()
check(err)
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
m.TrackPlayer.Play(&stream)
case " ": case " ":
pauseState := m.TrackPlayer.TogglePause() pauseState := m.TrackPlayer.TogglePause()
cmds = append(cmds, newTrackPauseCmd(pauseState)) cmds = append(cmds, newTrackPauseCmd(pauseState))

View File

@ -2,48 +2,52 @@ package gomus
import ( import (
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/faiface/beep"
bflac "github.com/faiface/beep/flac"
"github.com/mewkiz/flac" "github.com/mewkiz/flac"
"github.com/mewkiz/flac/meta" "github.com/mewkiz/flac/meta"
) )
type track struct { type track struct {
name string Name string
artist string Artist string
trackPath string TrackPath string
} }
func (t track) FilterValue() string { return "" } func (t track) FilterValue() string { return "" }
func (t track) fullName() string { return fmt.Sprintf("%s - %s", t.Artist, t.Name) }
func (t track) fullName() string { func (t track) GetStream() (beep.StreamSeekCloser, beep.Format, error) {
return fmt.Sprintf("%s - %s", t.artist, t.name) f, err := os.Open(t.TrackPath)
}
func (t track) getReader() io.Reader {
f, err := os.Open(t.trackPath)
check(err) check(err)
return f if strings.HasSuffix(t.TrackPath, ".flac") {
streamer, format, err := bflac.Decode(f)
check(err)
return streamer, format, nil
}
return nil, beep.Format{}, fmt.Errorf("Could not parse track")
} }
func trackFromFlac(path string) track { func TrackFromFlac(path string) track {
s, err := flac.ParseFile(path) s, err := flac.ParseFile(path)
check(err) check(err)
t := track{trackPath: path} t := track{TrackPath: path}
for _, block := range s.Blocks { for _, block := range s.Blocks {
if block.Header.Type == meta.TypeVorbisComment { if block.Header.Type == meta.TypeVorbisComment {
c := block.Body.(*meta.VorbisComment) c := block.Body.(*meta.VorbisComment)
for _, tag := range c.Tags { for _, tag := range c.Tags {
if tag[0] == "ARTIST" { if tag[0] == "ARTIST" {
t.artist = tag[1] t.Artist = tag[1]
} else if tag[0] == "TITLE" { } else if tag[0] == "TITLE" {
t.name = tag[1] t.Name = tag[1]
} }
} }
} }
@ -64,7 +68,7 @@ func NewDirTrackIndex(path string) trackIndex {
for _, file := range files { for _, file := range files {
if !file.IsDir() && strings.HasSuffix(file.Name(), ".flac") { if !file.IsDir() && strings.HasSuffix(file.Name(), ".flac") {
p := filepath.Join(path, file.Name()) p := filepath.Join(path, file.Name())
tracks = append(tracks, trackFromFlac(p)) tracks = append(tracks, TrackFromFlac(p))
} }
} }

View File

@ -1,32 +1,35 @@
package gomus package gomus
import ( import (
"io"
"time"
"github.com/faiface/beep" "github.com/faiface/beep"
"github.com/faiface/beep/flac"
"github.com/faiface/beep/speaker" "github.com/faiface/beep/speaker"
) )
type trackPlayer struct { type TrackPlayer struct {
currentStream beep.StreamSeekCloser streamer *beep.StreamSeekCloser
playerCtrl *beep.Ctrl
} }
func (t trackPlayer) play(reader io.Reader) { func (t *TrackPlayer) Play(streamer *beep.StreamSeekCloser) {
if t.currentStream != nil { if t.streamer != nil {
t.currentStream.Close() t.Close()
} }
streamer, format, err := flac.Decode(reader)
check(err)
err = speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10)) ctrl := &beep.Ctrl{Streamer: beep.Loop(-1, *streamer), Paused: false}
check(err) speaker.Play(ctrl)
speaker.Play(streamer) t.playerCtrl = ctrl
t.currentStream = streamer t.streamer = streamer
} }
func (t trackPlayer) close() { func (t *TrackPlayer) TogglePause() bool {
t.currentStream.Close() speaker.Lock()
newState := !t.playerCtrl.Paused
t.playerCtrl.Paused = newState
speaker.Unlock()
return newState
}
func (t *TrackPlayer) Close() {
(*t.streamer).Close()
} }