scanner: move _query_duration() into _process()
This commit is contained in:
parent
3183f43b18
commit
57518861ea
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user