dongwei1263 2017-07-15 15:38
浏览 48
已采纳

在libvlc播放中实现先前版本

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:

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.

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条回答 默认 最新

  • douji9734 2017-07-16 15:13
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改