英文:
Implement previous with libvlc playback
问题
我正在使用libvlc
(go绑定)在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)
// 检查错误并返回
playlist = append(playlist, media)
}
for idx := range playlist {
p.SetMedia(playlist[idx])
err = p.Play()
// 检查错误并返回
status, err := p.MediaState()
// 检查错误并返回
PlaybackLoop:
for status != vlc.MediaEnded {
status, err = p.MediaState()
// 继续并检查错误
l.SetSelected(idx) // TUI歌曲列表
song := songStatus(a, l.Selected())
s.SetPermanentText(song) // TUI状态栏
select {
case <-next:
break PlaybackLoop
case <-prev:
continue // TODO: 实现上一首
case <-done:
return err
default:
time.Sleep(50 * time.Millisecond)
}
}
}
return err
}
我无法实现Previous
,因为我不能在for循环中回退。
理想情况下,我认为我应该使用libvlc
的media_list_player
。然而,如果我无法获取media_list
中歌曲的持续时间、长度和索引,我宁愿使用这种方法。
如果我必须使用media_player
,有没有比使用嵌套循环和通道更好的处理播放的方法?有没有办法实现上一首?
英文:
I'm using libvlc
(go binding) to play music in a TUI. Instead of using the media_list_player
, which has Next
and Previous
methods, I followed the advice of this answer https://stackoverflow.com/a/44647523/4443226 to use the regular media_player
and a loop:
<!-- language: python -->
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
This has the benefit that I can get the index of the current song and I can get the position and duration of the current playing song.
I implemented it in Go, and one of the problems, is that I am unable to implement (effectively) Next
and Previous
song.
Part of the problem is that this playback loop must be in a separate goroutine
than the UI thread. I use chan
to send signals for stopping the goroutine
and skipping the song.
<!-- language: go -->
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
}
I am unable to implement Previous
, because I can't just go back in the for loop.
Ideally I think I would like to use the libvlc
media_list_player
. However, if I can't get the song duration and length as well as the index of the song in the media_list
, I would rather do this method.
If I must use the media_player
instead, is there a better way to handle playback than using nested loops and channels? Something that can use previous?
答案1
得分: 1
根据与提问者的评论和讨论,确定使用链表可能是在尝试以较少的努力控制前进和后退的最佳方法。由于使用了Go语言,并且使用的模块需要goroutine,因此链表在goroutine中的使用也必须是安全的。
英文:
Based on the comments and discussion with the OP It was determined that a linked list was probably the best route in trying to control how to go forward and backwards with a bit less effort. Since Go is being used and the modules that are being used require goroutines the linked list also would have to be safe to use within goroutines.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论