使用python-vlc获取基于URL的Media对象的持续时间-无法解析

时间:2019-04-05 07:23:49

标签: python libvlc

我正在尝试使用python 2.7 python-vlc进行解析,然后从URL获取音乐曲目的持续时间。解析无法正常进行,然后播放,然后暂停播放媒体,有时会返回-1。

我知道有两种解析媒体的方法,必须在使用media.get_duration()之前完成。我可以解析它,也可以播放它。

无论如何,我都无法解析媒体。使用parse_with_options()可以为我提供所有内容的解析状态MediaParsedStatus.skipped,除了parse_with_option(1,0)可以为我解析状态MediaParsedStatus.FIXME_(0L)

        p = vlc.MediaPlayer(songurl)
        media = p.get_media()
        media.parse_with_options(1, 0)
        print media.get_parsed_status()
        print media.get_duration()

字符串“ songurl”是Youtube或Google Play音乐中歌曲的实际流URL,与MediaPlayer完美配合。

我也尝试过播放媒体0.01到0.5秒,然后尝试获取时间,这在MOST OF THE TIME上有效,但会随机返回-1的持续时间,大约为10倍。再次使用media.get_duration()会返回相同的结果。

我宁愿只分析歌曲,也不用担心播放它,但是我想不出任何方法来分析它。 由于我认为MediaParsedStatus.FIXME_(0L)是某种错误,因此我已经向python-vlc github提交了一个错误报告。

更新:我知道了!这可能是我整个编程生涯中最大的痛苦(并不多)。这是用于获取URL跟踪时间的代码:

        instance = vlc.Instance()
        media = instance.media_new(songurl)
        player = instance.media_player_new()
        player.set_media(media)
        #Start the parser
        media.parse_with_options(1,0)
        while True:
            if str(media.get_parsed_status()) == 'MediaParsedStatus.done':
                break #Might be a good idea to add a failsafe in here.
        print media.get_duration()

2 个答案:

答案 0 :(得分:1)

media.parse_with_options是异步的。因此,您的代码无需等待URL的响应,而只是继续进行下去。与所有异步方法一样,您需要接收到已接收到数据的通知,然后才能继续。在这种情况下,它看起来像是MediaParsedChanged事件。

https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__media.html#ga55f5a33e22aa32e17a9bb75decd1497b

或者,您应该能够使用parse()方法,该方法是同步的,并且将阻塞直到收到元数据为止。不建议这样做(不建议使用),因为它可能会无限期阻塞并锁定。但这是一个选项,具体取决于您使用代码的目的。

https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__media.html#ga4b71084fb35b3dd8cc6457a4d27baf0c

编辑:

如果您需要将事件管理器与python绑定一起使用的示例,这是一个很好的示例: VLC Python EventManager callback type?

特别是,请看一下Rolf的回答,因为他的使用方式可能对您来说是一个很好的起点。

import vlc
parseReady = 0

def ParseReceived(event):
    global parseReady
    #set a flag that your data is ready
    parseReady = 1
...
events = player.event_manager()
events.event_attach(vlc.EventType.MediaParsedChanged, ParseReceived)
...
parseReady = 0
media.parse_with_options(1, 0)
while parseReady == 0:
    #TODO: spin something to waste time

#Once the flag is set, your data is ready
print media.get_parsed_status()
print media.get_duration()

毫无疑问,有更好的方法可以做到这一点,但这是一个基本示例。注意,根据文档,您不能从事件回调中调用vlc方法。因此,使用简单的标志而不是直接在回调中调用媒体方法。

答案 1 :(得分:0)

libvlc默认情况下不会解析网络资源。您需要使用libvlc_media_parse_network来调用带有选项的解析。