Added volume controls
This commit is contained in:
parent
8eb850d9fe
commit
8fc218ac2d
@ -21,3 +21,13 @@ func newTrackPauseCmd(isPaused bool) tea.Cmd {
|
|||||||
return trackPauseMsg{isPaused}
|
return trackPauseMsg{isPaused}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type trackVolumeMsg struct {
|
||||||
|
volume float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTrackVolumeCmd(volume float64) tea.Cmd {
|
||||||
|
return func() tea.Msg {
|
||||||
|
return trackVolumeMsg{volume}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
36
pkg/model.go
36
pkg/model.go
@ -21,6 +21,7 @@ type Model struct {
|
|||||||
currentlyPlaying int
|
currentlyPlaying int
|
||||||
|
|
||||||
TrackPlayer
|
TrackPlayer
|
||||||
|
TrackPlayerEffects
|
||||||
trackIndex
|
trackIndex
|
||||||
|
|
||||||
trackPlayerView
|
trackPlayerView
|
||||||
@ -36,6 +37,7 @@ func NewModel(args ModelArgs) Model {
|
|||||||
|
|
||||||
trackIndex: ti,
|
trackIndex: ti,
|
||||||
TrackPlayer: TrackPlayer{},
|
TrackPlayer: TrackPlayer{},
|
||||||
|
TrackPlayerEffects: newTrackPlayerEffects(),
|
||||||
|
|
||||||
trackPlayerView: tpv,
|
trackPlayerView: tpv,
|
||||||
}
|
}
|
||||||
@ -59,16 +61,42 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
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))
|
|
||||||
stream, format, err := t.GetStream()
|
stream, format, err := t.GetStream()
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
|
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
|
||||||
m.TrackPlayer.Play(&stream)
|
|
||||||
|
m.TrackPlayer.Play(&stream, &m.TrackPlayerEffects)
|
||||||
|
cmds = append(cmds, newTrackChangeCmd(t))
|
||||||
case " ":
|
case " ":
|
||||||
pauseState := m.TrackPlayer.TogglePause()
|
if m.TrackPlayer.playerCtrl != nil {
|
||||||
cmds = append(cmds, newTrackPauseCmd(pauseState))
|
s := m.TrackPlayer.TogglePause()
|
||||||
|
cmds = append(cmds, newTrackPauseCmd(s))
|
||||||
|
}
|
||||||
|
case "-", "=":
|
||||||
|
v := &m.TrackPlayerEffects.volume
|
||||||
|
|
||||||
|
if msg.String() == "-" {
|
||||||
|
*v -= 0.1
|
||||||
|
if *v < minVolume {
|
||||||
|
*v = minVolume
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*v += 0.1
|
||||||
|
if *v > maxVolume {
|
||||||
|
*v = maxVolume
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.TrackPlayer.playerVol != nil {
|
||||||
|
m.TrackPlayer.SetVolume(*v)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmds = append(cmds, newTrackVolumeCmd(*v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var cmd tea.Cmd
|
var cmd tea.Cmd
|
||||||
m.trackPlayerView, cmd = m.trackPlayerView.Update(msg)
|
m.trackPlayerView, cmd = m.trackPlayerView.Update(msg)
|
||||||
cmds = append(cmds, cmd)
|
cmds = append(cmds, cmd)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package gomus
|
package gomus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss"
|
||||||
)
|
)
|
||||||
@ -14,8 +16,7 @@ var (
|
|||||||
Inherit(statusBarStyle).
|
Inherit(statusBarStyle).
|
||||||
Foreground(lipgloss.Color("#FFFDF5")).
|
Foreground(lipgloss.Color("#FFFDF5")).
|
||||||
Background(lipgloss.Color("#FF5F87")).
|
Background(lipgloss.Color("#FF5F87")).
|
||||||
Padding(0, 1).
|
Padding(0, 1)
|
||||||
MarginRight(1)
|
|
||||||
|
|
||||||
statusText = lipgloss.NewStyle().Inherit(statusBarStyle)
|
statusText = lipgloss.NewStyle().Inherit(statusBarStyle)
|
||||||
)
|
)
|
||||||
@ -23,9 +24,10 @@ var (
|
|||||||
type statusBar struct {
|
type statusBar struct {
|
||||||
isPaused bool
|
isPaused bool
|
||||||
currentTrack track
|
currentTrack track
|
||||||
|
currentVolume float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s statusBar) Init() tea.Cmd {
|
func (s *statusBar) Init() tea.Cmd {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,16 +41,22 @@ func (s statusBar) View() string {
|
|||||||
statusKey = statusStyle.Render("")
|
statusKey = statusStyle.Render("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v := MapFloatBetween(s.currentVolume, minVolume, maxVolume, 0, 100)
|
||||||
|
vs := fmt.Sprintf("vol %d", int(v))
|
||||||
|
|
||||||
statusVal := statusText.Copy().
|
statusVal := statusText.Copy().
|
||||||
Width(termWidth - w(statusKey)).
|
Width(termWidth - w(statusKey) - w(vs) - 2).
|
||||||
Render(s.currentTrack.fullName())
|
Render(s.currentTrack.fullName())
|
||||||
|
|
||||||
|
statusVol := statusStyle.Copy().Align(lipgloss.Right).Width(w(vs) + 2).Render(vs)
|
||||||
|
|
||||||
bar := lipgloss.JoinHorizontal(lipgloss.Top,
|
bar := lipgloss.JoinHorizontal(lipgloss.Top,
|
||||||
statusKey,
|
statusKey,
|
||||||
statusVal,
|
statusVal,
|
||||||
|
statusVol,
|
||||||
)
|
)
|
||||||
|
|
||||||
return statusBarStyle.Width(termWidth).Render(bar)
|
return statusBarStyle.Render(bar)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s statusBar) Update(msg tea.Msg) (statusBar, tea.Cmd) {
|
func (s statusBar) Update(msg tea.Msg) (statusBar, tea.Cmd) {
|
||||||
@ -57,6 +65,8 @@ func (s statusBar) Update(msg tea.Msg) (statusBar, tea.Cmd) {
|
|||||||
s.currentTrack = msg.nextTrack
|
s.currentTrack = msg.nextTrack
|
||||||
case trackPauseMsg:
|
case trackPauseMsg:
|
||||||
s.isPaused = msg.isPaused
|
s.isPaused = msg.isPaused
|
||||||
|
case trackVolumeMsg:
|
||||||
|
s.currentVolume = msg.volume
|
||||||
}
|
}
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
|
@ -2,24 +2,43 @@ package gomus
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/faiface/beep"
|
"github.com/faiface/beep"
|
||||||
|
"github.com/faiface/beep/effects"
|
||||||
"github.com/faiface/beep/speaker"
|
"github.com/faiface/beep/speaker"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
base = 2
|
||||||
|
minVolume = -5
|
||||||
|
maxVolume = 1
|
||||||
|
startVolume = -2
|
||||||
|
)
|
||||||
|
|
||||||
|
type TrackPlayerEffects struct {
|
||||||
|
volume float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTrackPlayerEffects() TrackPlayerEffects {
|
||||||
|
return TrackPlayerEffects{volume: startVolume}
|
||||||
|
}
|
||||||
|
|
||||||
type TrackPlayer struct {
|
type TrackPlayer struct {
|
||||||
streamer *beep.StreamSeekCloser
|
streamer *beep.StreamSeekCloser
|
||||||
playerCtrl *beep.Ctrl
|
playerCtrl *beep.Ctrl
|
||||||
|
playerVol *effects.Volume
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TrackPlayer) Play(streamer *beep.StreamSeekCloser) {
|
func (t *TrackPlayer) Play(streamer *beep.StreamSeekCloser, trackEffects *TrackPlayerEffects) {
|
||||||
if t.streamer != nil {
|
if t.streamer != nil {
|
||||||
t.Close()
|
t.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrl := &beep.Ctrl{Streamer: beep.Loop(-1, *streamer), Paused: false}
|
ctrl := &beep.Ctrl{Streamer: beep.Loop(-1, *streamer), Paused: false}
|
||||||
speaker.Play(ctrl)
|
volume := &effects.Volume{Streamer: ctrl, Base: base, Volume: trackEffects.volume, Silent: false}
|
||||||
|
speaker.Play(volume)
|
||||||
|
|
||||||
t.playerCtrl = ctrl
|
|
||||||
t.streamer = streamer
|
t.streamer = streamer
|
||||||
|
t.playerCtrl = ctrl
|
||||||
|
t.playerVol = volume
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TrackPlayer) TogglePause() bool {
|
func (t *TrackPlayer) TogglePause() bool {
|
||||||
@ -30,6 +49,12 @@ func (t *TrackPlayer) TogglePause() bool {
|
|||||||
return newState
|
return newState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TrackPlayer) SetVolume(volume float64) {
|
||||||
|
speaker.Lock()
|
||||||
|
(*t.playerVol).Volume = volume
|
||||||
|
speaker.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TrackPlayer) Close() {
|
func (t *TrackPlayer) Close() {
|
||||||
(*t.streamer).Close()
|
(*t.streamer).Close()
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,16 @@ func newTrackPlayerView(tracks []track) trackPlayerView {
|
|||||||
c := mapList(tracks, func(t track) list.Item {
|
c := mapList(tracks, func(t track) list.Item {
|
||||||
return t
|
return t
|
||||||
})
|
})
|
||||||
|
|
||||||
l := list.New(c, newTrackListDelegate(), 0, 0)
|
l := list.New(c, newTrackListDelegate(), 0, 0)
|
||||||
l.SetShowTitle(false)
|
l.SetShowTitle(false)
|
||||||
l.SetShowStatusBar(false)
|
l.SetShowStatusBar(false)
|
||||||
l.SetShowHelp(false)
|
l.SetShowHelp(false)
|
||||||
l.SetFilteringEnabled(false)
|
l.SetFilteringEnabled(false)
|
||||||
|
|
||||||
return trackPlayerView{trackList: l}
|
s := statusBar{currentVolume: startVolume}
|
||||||
|
|
||||||
|
return trackPlayerView{trackList: l, statusBar: s}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v trackPlayerView) Init() tea.Cmd {
|
func (v trackPlayerView) Init() tea.Cmd {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user