我正在尝试使用python 2.7 python-vlc进行解析,然后从URL获取音乐曲目的持续时间。解析不起作用然后播放然后暂停媒体会偶尔返回-1持续时间。
我知道解析媒体有两种方法,必须在使用media.get_duration()
之前完成。我可以解析它,或者我可以玩它。
无论如何,我无法解析媒体。使用parse_with_options()
给我解析状态MediaParsedStatus.skipped
的一切除了parse_with_option(1,0)
which给我解析状态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的歌曲的实际流媒体网址,与MediaPlayer完美配合。
我也试过播放媒体短暂的0.01到0.5秒的时间,然后试图获得时间,其工作时间最多,但随机返回-1的持续时间约为10次。再次使用media.get_duration()
返回相同的结果。
我宁愿只是解析这首歌而不是担心播放它,但我无法找出任何方法来解析它。我已经向python-vlc github提交了一个错误报告,因为我认为MediaParsedStatus.FIXME_(0L)
是某种bug。
更新:我知道了!这可能是我所有编程生涯中最大的痛苦(这不是很多)。以下是用于获取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
选项调用解析。