scanner: move _query_duration() into _process()

This commit is contained in:
SeeSpotRun 2016-03-15 18:37:23 +10:00 committed by Thomas Adamcik
parent 3183f43b18
commit 57518861ea

View File

@ -61,8 +61,7 @@ class Scanner(object):
try:
_start_pipeline(pipeline)
tags, mime, have_audio = _process(pipeline, timeout)
duration = _query_duration(pipeline)
tags, mime, have_audio, duration = _process(pipeline, timeout)
seekable = _query_seekable(pipeline)
finally:
signals.clear()
@ -136,30 +135,6 @@ def _start_pipeline(pipeline):
pipeline.set_state(Gst.State.PLAYING)
def _query_duration(pipeline, timeout=100):
# 1. Try and get a duration, return if success.
# 2. Some formats need to play some buffers before duration is found.
# 3. Wait for a duration change event.
# 4. Try and get a duration again.
success, duration = pipeline.query_duration(Gst.Format.TIME)
if success and duration >= 0:
return duration // Gst.MSECOND
result = pipeline.set_state(Gst.State.PLAYING)
if result == Gst.StateChangeReturn.FAILURE:
return None
gst_timeout = timeout * Gst.MSECOND
bus = pipeline.get_bus()
bus.timed_pop_filtered(gst_timeout, Gst.MessageType.DURATION_CHANGED)
success, duration = pipeline.query_duration(Gst.Format.TIME)
if success and duration >= 0:
return duration // Gst.MSECOND
return None
def _query_seekable(pipeline):
query = Gst.Query.new_seeking(Gst.Format.TIME)
pipeline.query(query)
@ -172,6 +147,7 @@ def _process(pipeline, timeout_ms):
mime = None
have_audio = False
missing_message = None
duration = None
types = (
Gst.MessageType.ELEMENT |
@ -179,6 +155,7 @@ def _process(pipeline, timeout_ms):
Gst.MessageType.ERROR |
Gst.MessageType.EOS |
Gst.MessageType.ASYNC_DONE |
Gst.MessageType.DURATION_CHANGED |
Gst.MessageType.TAG
)
@ -197,7 +174,7 @@ def _process(pipeline, timeout_ms):
mime = message.get_structure().get_value('caps').get_name()
if mime and (
mime.startswith('text/') or mime == 'application/xml'):
return tags, mime, have_audio
return tags, mime, have_audio, duration
elif message.get_structure().get_name() == 'have-audio':
have_audio = True
elif message.type == Gst.MessageType.ERROR:
@ -205,16 +182,28 @@ def _process(pipeline, timeout_ms):
if missing_message and not mime:
caps = missing_message.get_structure().get_value('detail')
mime = caps.get_structure(0).get_name()
return tags, mime, have_audio
return tags, mime, have_audio, duration
raise exceptions.ScannerError(error)
elif message.type == Gst.MessageType.EOS:
return tags, mime, have_audio
return tags, mime, have_audio, duration
elif message.type == Gst.MessageType.ASYNC_DONE:
if tags:
return tags, mime, have_audio
success, duration = pipeline.query_duration(Gst.Format.TIME)
if success:
duration = duration // Gst.MSECOND
else:
# workaround for https://bugzilla.gnome.org/show_bug.cgi?id=763553:
pipeline.set_state(Gst.State.PLAYING)
duration = None
if (tags and duration
# workaround for
# https://bugzilla.gnome.org/show_bug.cgi?id=763553:
# try to start pipeline playing; if it doesn't then
# give up:
) or ( pipeline.set_state(Gst.State.PLAYING)
== Gst.StateChangeReturn.FAILURE):
return tags, mime, have_audio, duration
elif message.type == Gst.MessageType.DURATION_CHANGED:
# duration will be read after ASYNC_DONE received; for now
# just give it a non-None value to flag that we have a duration:
duration = 0
elif message.type == Gst.MessageType.TAG:
taglist = message.parse_tag()
# Note that this will only keep the last tag.
@ -223,8 +212,10 @@ def _process(pipeline, timeout_ms):
now = int(time.time() * 1000)
timeout -= now - previous
previous = now
# workaround for https://bugzilla.gnome.org/show_bug.cgi?id=763553:
if tags:
# if we got what we want then stop playing (and wait for ASYNC_DONE)
if tags and duration:
pipeline.set_state(Gst.State.PAUSED)
raise exceptions.ScannerError('Timeout after %dms' % timeout_ms)