使用 python-vlc 获取基于 URL 的媒体对象的持续时间 - 无法解析
Get the duration of a URL-based Media object with python-vlc - Cannot parse
我正在尝试使用 python 2.7 python-vlc 来解析然后从 URL 中获取音乐曲目的持续时间。解析不起作用,播放然后偶尔暂停媒体 returns -1。
我知道有两种解析媒体的方法,必须在使用 media.get_duration()
之前完成。我可以解析它,也可以播放它。
无论如何,我无法解析媒体。使用 parse_with_options()
为我提供了除 parse_with_option(1,0)
以外的所有内容的解析状态 MediaParsedStatus.skipped
,它为我提供了解析状态 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 Music 的歌曲的实际流式传输 URL,它与 MediaPlayer 完美配合。
我也试过播放媒体 0.01 到 0.5 秒的短时间,然后尝试获取时间,这在大多数时间都有效,但随机 returns -1 的持续时间约为 10 次。再次使用 media.get_duration()
returns 结果相同。
我宁愿只解析这首歌而不是担心播放它,但我想不出任何解析它的方法。
我已经向 python-vlc github 提交了错误报告,因为我认为 MediaParsedStatus.FIXME_(0L)
是某种错误。
更新:我知道了!这可能是我所有编程生涯中最大的痛苦(并不多)。这是用于获取 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()
media.parse_with_options
是异步的。因此,您的代码不会等待 URL 的响应,它会立即继续。与所有异步方法一样,您需要收到已收到数据的通知,然后才能继续。在这种情况下,它看起来像是 MediaParsedChanged
事件。
或者,您应该能够使用同步的 parse()
方法,该方法将阻塞直到收到元数据。不推荐这样做(并且已弃用),因为它可能会无限期地阻塞并锁定。但它是一个选项,具体取决于您使用代码的目的。
编辑:
如果您需要使用带有 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 方法。因此使用简单的标志而不是直接在回调中调用媒体方法。
libvlc
默认不会解析网络资源。您需要使用 libvlc_media_parse_network
.
选项调用解析
我正在尝试使用 python 2.7 python-vlc 来解析然后从 URL 中获取音乐曲目的持续时间。解析不起作用,播放然后偶尔暂停媒体 returns -1。
我知道有两种解析媒体的方法,必须在使用 media.get_duration()
之前完成。我可以解析它,也可以播放它。
无论如何,我无法解析媒体。使用 parse_with_options()
为我提供了除 parse_with_option(1,0)
以外的所有内容的解析状态 MediaParsedStatus.skipped
,它为我提供了解析状态 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 Music 的歌曲的实际流式传输 URL,它与 MediaPlayer 完美配合。
我也试过播放媒体 0.01 到 0.5 秒的短时间,然后尝试获取时间,这在大多数时间都有效,但随机 returns -1 的持续时间约为 10 次。再次使用 media.get_duration()
returns 结果相同。
我宁愿只解析这首歌而不是担心播放它,但我想不出任何解析它的方法。
我已经向 python-vlc github 提交了错误报告,因为我认为 MediaParsedStatus.FIXME_(0L)
是某种错误。
更新:我知道了!这可能是我所有编程生涯中最大的痛苦(并不多)。这是用于获取 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()
media.parse_with_options
是异步的。因此,您的代码不会等待 URL 的响应,它会立即继续。与所有异步方法一样,您需要收到已收到数据的通知,然后才能继续。在这种情况下,它看起来像是 MediaParsedChanged
事件。
或者,您应该能够使用同步的 parse()
方法,该方法将阻塞直到收到元数据。不推荐这样做(并且已弃用),因为它可能会无限期地阻塞并锁定。但它是一个选项,具体取决于您使用代码的目的。
编辑:
如果您需要使用带有 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 方法。因此使用简单的标志而不是直接在回调中调用媒体方法。
libvlc
默认不会解析网络资源。您需要使用 libvlc_media_parse_network
.