implement skip current song

This commit is contained in:
raziman 2020-06-23 18:42:18 +08:00
parent fcc9309886
commit f95bf27681
4 changed files with 53 additions and 35 deletions

View File

@ -23,7 +23,6 @@ type Song struct {
position string
}
type Player struct {
queue []string
IsRunning bool
@ -31,9 +30,13 @@ type Player struct {
current string
format *beep.Format
isSkipped bool
done chan bool
// to control the _volume internally
_volume *effects.Volume
volume float64
resampler *beep.Resampler
position time.Duration
length time.Duration
currentSong Song
@ -66,7 +69,7 @@ func (p *Player) Pop() (string, error) {
// remove song from the queue
func (p *Player) Remove(index int) (string, error) {
if index > len(p.queue) - 1 {
if index > len(p.queue)-1 {
return "", errors.New("Index out of range")
}
@ -88,24 +91,24 @@ func (p *Player) Remove(index int) (string, error) {
func (p *Player) Run() {
first, err := p.Pop()
// removes playing song from the queue
p.list.RemoveItem(0)
p.app.Draw()
if err != nil {
p.IsRunning = false
log(err.Error())
}
}
f, err := os.Open(first)
defer f.Close()
streamer, format, err := mp3.Decode(f)
// song duration
p.length = format.SampleRate.D(streamer.Len())
@ -131,14 +134,24 @@ func (p *Player) Run() {
done := make(chan bool)
p.done = done
sstreamer := beep.Seq(streamer, beep.Callback(func() {
done <- true
// prevents from sending done channel is the song is skipped
if !p.isSkipped {
done <- true
} else {
p.isSkipped = false
}
}))
ctrl := &beep.Ctrl{Streamer: sstreamer, Paused: false}
resampler := beep.ResampleRatio(4, 1, ctrl)
p.resampler = resampler
volume := &effects.Volume{
Streamer: ctrl,
Streamer: resampler,
Base: 2,
Volume: 0,
Silent: false,
@ -161,12 +174,13 @@ func (p *Player) Run() {
p.playingBar.NewProgress(song.name, int(p.length.Seconds()), 100)
p.playingBar.Run()
go func () {
go func() {
i := 0
for {
// stop progress bar from progressing when paused
if !p.IsRunning {
continue
}
@ -174,20 +188,21 @@ func (p *Player) Run() {
i++
p.playingBar.progress <- 1
if i > p.playingBar.full {
if i > p.playingBar.full || p.isSkipped {
break
}
time.Sleep(time.Second)
}
}()
next:
for {
select {
case <-done:
close(done)
p.playingBar._progress = 0
p.position = 0
p.current = ""
p.IsRunning = false
@ -195,9 +210,9 @@ func (p *Player) Run() {
if len(p.queue) != 0 {
go p.Run()
}
}
goto next
break next
case <-time.After(time.Second):
speaker.Lock()
p.position = position()
@ -205,9 +220,6 @@ func (p *Player) Run() {
}
}
next:
}
func (p *Player) Pause() {
@ -263,3 +275,10 @@ func (p *Player) TogglePause() {
}
}
// skips current song
func (p *Player) Skip() {
if len(p.queue) > 0 {
p.isSkipped = true
p.done <- true
}
}

View File

@ -16,12 +16,8 @@ func PlayingBar(app *tview.Application, player *Player) *Progress {
textView := tview.NewTextView()
progress := InitProgressBar(textView)
progress := InitProgressBar(textView, player)
progress.frame.SetInputCapture(func (e *tcell.EventKey) *tcell.EventKey {
return e
})
textView.SetChangedFunc(func() {
app.Draw()
@ -41,17 +37,18 @@ type Progress struct {
progress chan int
frame *tview.Frame
_progress int
player *Player
}
// full is the maximum amount of value can be sent to channel
// limit is the progress bar size
func InitProgressBar(txt *tview.TextView) *Progress {
p := &Progress{textView: txt}
func InitProgressBar(txt *tview.TextView, player *Player) *Progress {
p := &Progress{textView: txt, player: player}
p.progress = make(chan int)
p.textView.SetTextAlign(tview.AlignCenter)
p.frame = tview.NewFrame(p.textView).SetBorders(1, 1, 1, 1, 1, 1)
p.frame.SetBorder(true).SetTitle("Now Playing")
p.frame.SetBorder(true).SetTitle(" Now Playing ")
p.SetDefault()
@ -60,16 +57,19 @@ func InitProgressBar(txt *tview.TextView) *Progress {
func (p *Progress) Run() {
go func() { // Simple channel status gauge (progress bar)
go func() {
for {
if p._progress > p.full {
p._progress = 0
break
}
p._progress += <-p.progress
p.textView.Clear()
if p._progress > p.full {
p._progress = 0
break
}
start, err := time.ParseDuration(strconv.Itoa(p._progress) + "s")
@ -96,10 +96,8 @@ func (p *Progress) Run() {
}
func (p *Progress) SetSongTitle(title string) {
p.frame.Clear()
p.frame.AddText(title, true, tview.AlignCenter, tcell.ColorGreen)
}
func (p *Progress) NewProgress(songTitle string, full, limit int) {

View File

@ -50,9 +50,9 @@ func Queue(player *Player) *tview.List {
list.SetHighlightFullLine(true)
list.SetBorder(true).SetTitle("Queue")
list.SetBorder(true).SetTitle(" Queue ")
list.SetSelectedBackgroundColor(tcell.ColorDarkCyan)
list.SetSelectedTextColor(tcell.ColorAntiqueWhite)
list.SetSelectedTextColor(tcell.ColorWhite)
return list

View File

@ -62,13 +62,14 @@ func start(app *tview.Application) {
player.TogglePause()
case '+':
player.Volume(0.5)
case '-':
player.Volume(-0.5)
case 'n':
player.Skip()
}
return event