用libvlc播放实现previous
Implement previous with libvlc playback
我正在使用 libvlc
(绑定)在 TUI 中播放音乐。我没有使用具有 Next
和 Previous
方法的 media_list_player
,而是按照此答案 的建议使用常规 media_player
和循环:
import vlc
import time
my_list = ['vp1.mp3','happy.mp3']
instance = vlc.Instance()
player = instance.media_player_new()
playing = set([1,2,3,4])
for i in my_list:
player.set_mrl(i)
player.play()
play=True
while play == True:
time.sleep(1)
play_state = player.get_state()
if play_state in playing:
continue
else:
play = False
这样的好处是可以得到当前歌曲的索引,可以得到当前歌曲的position和duration播放歌曲。
我用 Go 实现了它,其中一个问题是我无法(有效地)实现 Next
和 Previous
歌曲。
部分问题在于此回放循环必须在 与 UI 线程不同的 goroutine
中。我使用 chan
发送停止 goroutine
和跳过歌曲的信号。
func playAlbum(p *vlc.Player, a Album, l *tui.List, s *tui.StatusBar, done, next, prev chan struct{}) (err error) {
playlist := make([]*vlc.Media, 0)
for _, path := range a.Paths {
media, err := vlc.NewMediaFromPath(path)
// check eturn err
playlist = append(playlist, media)
}
for idx := range playlist {
p.SetMedia(playlist[idx])
err = p.Play()
// check return err
status, err := p.MediaState()
// check return err
PlaybackLoop:
for status != vlc.MediaEnded {
status, err = p.MediaState()
// continue with err
l.SetSelected(idx) // TUI list of songs
song := songStatus(a, l.Selected())
s.SetPermanentText(song) // TUI status bar
select {
case <-next:
break PlaybackLoop
case <-prev:
continue // TODO: implement previous
case <-done:
return err
default:
time.Sleep(50 * time.Millisecond)
}
}
}
return err
}
我无法实现 Previous
,因为我不能在 for 循环中返回。
理想情况下我想我想使用libvlc
media_list_player
。但是,如果我无法获取歌曲 duration 和 length 以及 index media_list
中的歌曲,我宁愿用这种方法。
如果我必须改用 media_player
,有没有比使用嵌套循环和通道更好的播放方式?可以用previous?
的东西
根据与 OP 的评论和讨论,我们确定链表可能是尝试控制前进和后退的最佳途径,而且花费更少。由于正在使用 Go,并且正在使用的模块需要 goroutines,因此链表也必须在 goroutines 中安全使用。
我正在使用 libvlc
(绑定)在 TUI 中播放音乐。我没有使用具有 Next
和 Previous
方法的 media_list_player
,而是按照此答案 media_player
和循环:
import vlc
import time
my_list = ['vp1.mp3','happy.mp3']
instance = vlc.Instance()
player = instance.media_player_new()
playing = set([1,2,3,4])
for i in my_list:
player.set_mrl(i)
player.play()
play=True
while play == True:
time.sleep(1)
play_state = player.get_state()
if play_state in playing:
continue
else:
play = False
这样的好处是可以得到当前歌曲的索引,可以得到当前歌曲的position和duration播放歌曲。
我用 Go 实现了它,其中一个问题是我无法(有效地)实现 Next
和 Previous
歌曲。
部分问题在于此回放循环必须在 与 UI 线程不同的 goroutine
中。我使用 chan
发送停止 goroutine
和跳过歌曲的信号。
func playAlbum(p *vlc.Player, a Album, l *tui.List, s *tui.StatusBar, done, next, prev chan struct{}) (err error) {
playlist := make([]*vlc.Media, 0)
for _, path := range a.Paths {
media, err := vlc.NewMediaFromPath(path)
// check eturn err
playlist = append(playlist, media)
}
for idx := range playlist {
p.SetMedia(playlist[idx])
err = p.Play()
// check return err
status, err := p.MediaState()
// check return err
PlaybackLoop:
for status != vlc.MediaEnded {
status, err = p.MediaState()
// continue with err
l.SetSelected(idx) // TUI list of songs
song := songStatus(a, l.Selected())
s.SetPermanentText(song) // TUI status bar
select {
case <-next:
break PlaybackLoop
case <-prev:
continue // TODO: implement previous
case <-done:
return err
default:
time.Sleep(50 * time.Millisecond)
}
}
}
return err
}
我无法实现 Previous
,因为我不能在 for 循环中返回。
理想情况下我想我想使用libvlc
media_list_player
。但是,如果我无法获取歌曲 duration 和 length 以及 index media_list
中的歌曲,我宁愿用这种方法。
如果我必须改用 media_player
,有没有比使用嵌套循环和通道更好的播放方式?可以用previous?
根据与 OP 的评论和讨论,我们确定链表可能是尝试控制前进和后退的最佳途径,而且花费更少。由于正在使用 Go,并且正在使用的模块需要 goroutines,因此链表也必须在 goroutines 中安全使用。