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.

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

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog