Refactored track_player.go
This commit is contained in:
parent
bdefd6d2fb
commit
7905937c37
17
pkg/model.go
17
pkg/model.go
@ -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))
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user