我正在使用libvlc
(绑定)在TUI中播放音乐。我没有使用media_list_player
和Next
方法的Previous
,而是按照此答案https://stackoverflow.com/a/44647523/4443226的建议使用常规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
这样做的好处是我可以获得当前歌曲的索引,我可以获得当前播放歌曲的位置和持续时间。
我在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
。但是,如果我无法在media_list
中获得歌曲持续时间和长度以及歌曲的索引,我宁愿做这种方法。
如果我必须使用media_player
,是否有比使用嵌套循环和通道更好的方法来处理播放?可以使用上一个?
答案 0 :(得分:1)
基于对OP的评论和讨论确定链接列表可能是试图控制如何前进和后退而不需要更少努力的最佳途径。由于正在使用Go并且正在使用的模块需要goroutine,因此链接列表也必须在goroutines中安全使用。