def on_missing_plugin(self, msg): desc = GstPbutils.missing_plugin_message_get_description(msg) debug = GstPbutils.missing_plugin_message_get_installer_detail(msg) gst_logger.debug( 'Got missing-plugin bus message: description=%r', desc) logger.warning('Could not find a %s to handle media.', desc) if GstPbutils.install_plugins_supported(): logger.info('You might be able to fix this by running: ' 'gst-installer "%s"', debug)
def on_missing_plugin(self, msg): desc = GstPbutils.missing_plugin_message_get_description(msg) debug = GstPbutils.missing_plugin_message_get_installer_detail(msg) gst_logger.debug('Got missing-plugin bus message: description=%r', desc) logger.warning('Could not find a %s to handle media.', desc) if GstPbutils.install_plugins_supported(): logger.info( 'You might be able to fix this by running: ' 'gst-installer "%s"', debug)
def on_message(self, bus, msg): if msg.type == Gst.MessageType.STATE_CHANGED: if msg.src != self._element: return old_state, new_state, pending_state = msg.parse_state_changed() self.on_playbin_state_changed(old_state, new_state, pending_state) elif msg.type == Gst.MessageType.BUFFERING: self.on_buffering(msg.parse_buffering(), msg.get_structure()) elif msg.type == Gst.MessageType.EOS: self.on_end_of_stream() elif msg.type == Gst.MessageType.ERROR: error, debug = msg.parse_error() self.on_error(error, debug) elif msg.type == Gst.MessageType.WARNING: error, debug = msg.parse_warning() self.on_warning(error, debug) elif msg.type == Gst.MessageType.ASYNC_DONE: self.on_async_done() elif msg.type == Gst.MessageType.TAG: taglist = msg.parse_tag() self.on_tag(taglist) elif msg.type == Gst.MessageType.ELEMENT: if GstPbutils.is_missing_plugin_message(msg): self.on_missing_plugin(msg) elif msg.type == Gst.MessageType.STREAM_START: self.on_stream_start()
def _process(pipeline, timeout_ms): bus = pipeline.get_bus() tags = {} mime = None have_audio = False missing_message = None types = ( Gst.MessageType.ELEMENT | Gst.MessageType.APPLICATION | Gst.MessageType.ERROR | Gst.MessageType.EOS | Gst.MessageType.ASYNC_DONE | Gst.MessageType.TAG ) timeout = timeout_ms previous = int(time.time() * 1000) while timeout > 0: message = bus.timed_pop_filtered(timeout * Gst.MSECOND, types) if message is None: break elif message.type == Gst.MessageType.ELEMENT: if GstPbutils.is_missing_plugin_message(message): missing_message = message elif message.type == Gst.MessageType.APPLICATION: if message.get_structure().get_name() == "have-type": mime = message.get_structure().get_value("caps").get_name() if mime and (mime.startswith("text/") or mime == "application/xml"): return tags, mime, have_audio elif message.get_structure().get_name() == "have-audio": have_audio = True elif message.type == Gst.MessageType.ERROR: error = encoding.locale_decode(message.parse_error()[0]) 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 raise exceptions.ScannerError(error) elif message.type == Gst.MessageType.EOS: return tags, mime, have_audio elif message.type == Gst.MessageType.ASYNC_DONE: if message.src == pipeline: return tags, mime, have_audio elif message.type == Gst.MessageType.TAG: taglist = message.parse_tag() # Note that this will only keep the last tag. tags.update(tags_lib.convert_taglist(taglist)) now = int(time.time() * 1000) timeout -= now - previous previous = now raise exceptions.ScannerError("Timeout after %dms" % timeout_ms)
def _process(pipeline, timeout_ms): bus = pipeline.get_bus() tags = {} mime = None have_audio = False missing_message = None types = (Gst.MessageType.ELEMENT | Gst.MessageType.APPLICATION | Gst.MessageType.ERROR | Gst.MessageType.EOS | Gst.MessageType.ASYNC_DONE | Gst.MessageType.TAG) timeout = timeout_ms previous = int(time.time() * 1000) while timeout > 0: message = bus.timed_pop_filtered(timeout * Gst.MSECOND, types) if message is None: break elif message.type == Gst.MessageType.ELEMENT: if GstPbutils.is_missing_plugin_message(message): missing_message = message elif message.type == Gst.MessageType.APPLICATION: if message.get_structure().get_name() == 'have-type': mime = message.get_structure().get_value('caps').get_name() if mime and (mime.startswith('text/') or mime == 'application/xml'): return tags, mime, have_audio elif message.get_structure().get_name() == 'have-audio': have_audio = True elif message.type == Gst.MessageType.ERROR: error = encoding.locale_decode(message.parse_error()[0]) 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 raise exceptions.ScannerError(error) elif message.type == Gst.MessageType.EOS: return tags, mime, have_audio elif message.type == Gst.MessageType.ASYNC_DONE: if message.src == pipeline: return tags, mime, have_audio elif message.type == Gst.MessageType.TAG: taglist = message.parse_tag() # Note that this will only keep the last tag. tags.update(tags_lib.convert_taglist(taglist)) now = int(time.time() * 1000) timeout -= now - previous previous = now raise exceptions.ScannerError('Timeout after %dms' % timeout_ms)
def _process(pipeline, timeout_ms): bus = pipeline.get_bus() tags = {} mime = None have_audio = False missing_message = None duration = None types = (Gst.MessageType.ELEMENT | Gst.MessageType.APPLICATION | Gst.MessageType.ERROR | Gst.MessageType.EOS | Gst.MessageType.ASYNC_DONE | Gst.MessageType.DURATION_CHANGED | Gst.MessageType.TAG) timeout = timeout_ms start = int(time.time() * 1000) while timeout > 0: msg = bus.timed_pop_filtered(timeout * Gst.MSECOND, types) if msg is None: break if logger.isEnabledFor(log.TRACE_LOG_LEVEL) and msg.get_structure(): debug_text = msg.get_structure().to_string() if len(debug_text) > 77: debug_text = debug_text[:77] + '...' _trace('element %s: %s', msg.src.get_name(), debug_text) if msg.type == Gst.MessageType.ELEMENT: if GstPbutils.is_missing_plugin_message(msg): missing_message = msg elif msg.type == Gst.MessageType.APPLICATION: if msg.get_structure().get_name() == 'have-type': mime = msg.get_structure().get_value('caps').get_name() if mime and (mime.startswith('text/') or mime == 'application/xml'): return tags, mime, have_audio, duration elif msg.get_structure().get_name() == 'have-audio': have_audio = True elif msg.type == Gst.MessageType.ERROR: error = encoding.locale_decode(msg.parse_error()[0]) 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, duration raise exceptions.ScannerError(error) elif msg.type == Gst.MessageType.EOS: return tags, mime, have_audio, duration elif msg.type == Gst.MessageType.ASYNC_DONE: success, duration = _query_duration(pipeline) if tags and success: return tags, mime, have_audio, duration # Don't try workaround for non-seekable sources such as mmssrc: if not _query_seekable(pipeline): return tags, mime, have_audio, duration # Workaround for upstream bug which causes tags/duration to arrive # after pre-roll. We get around this by starting to play the track # and then waiting for a duration change. # https://bugzilla.gnome.org/show_bug.cgi?id=763553 logger.debug('Using workaround for duration missing before play.') result = pipeline.set_state(Gst.State.PLAYING) if result == Gst.StateChangeReturn.FAILURE: return tags, mime, have_audio, duration elif msg.type == Gst.MessageType.DURATION_CHANGED and tags: # VBR formats sometimes seem to not have a duration by the time we # go back to paused. So just try to get it right away. success, duration = _query_duration(pipeline) pipeline.set_state(Gst.State.PAUSED) if success: return tags, mime, have_audio, duration elif msg.type == Gst.MessageType.TAG: taglist = msg.parse_tag() # Note that this will only keep the last tag. tags.update(tags_lib.convert_taglist(taglist)) timeout = timeout_ms - (int(time.time() * 1000) - start) raise exceptions.ScannerError('Timeout after %dms' % timeout_ms)
def _process(pipeline, timeout_ms): bus = pipeline.get_bus() tags = {} mime = None have_audio = False missing_message = None duration = None types = ( Gst.MessageType.ELEMENT | Gst.MessageType.APPLICATION | Gst.MessageType.ERROR | Gst.MessageType.EOS | Gst.MessageType.ASYNC_DONE | Gst.MessageType.DURATION_CHANGED | Gst.MessageType.TAG ) timeout = timeout_ms start = int(time.time() * 1000) while timeout > 0: message = bus.timed_pop_filtered(timeout * Gst.MSECOND, types) if message is None: break elif message.type == Gst.MessageType.ELEMENT: if GstPbutils.is_missing_plugin_message(message): missing_message = message elif message.type == Gst.MessageType.APPLICATION: if message.get_structure().get_name() == 'have-type': mime = message.get_structure().get_value('caps').get_name() if mime and ( mime.startswith('text/') or mime == 'application/xml'): return tags, mime, have_audio, duration elif message.get_structure().get_name() == 'have-audio': have_audio = True elif message.type == Gst.MessageType.ERROR: error = encoding.locale_decode(message.parse_error()[0]) 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, duration raise exceptions.ScannerError(error) elif message.type == Gst.MessageType.EOS: return tags, mime, have_audio, duration elif message.type == Gst.MessageType.ASYNC_DONE: success, duration = _query_duration(pipeline) if tags and success: return tags, mime, have_audio, duration # Workaround for upstream bug which causes tags/duration to arrive # after pre-roll. We get around this by starting to play the track # and then waiting for a duration change. # https://bugzilla.gnome.org/show_bug.cgi?id=763553 result = pipeline.set_state(Gst.State.PLAYING) if result == 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. tags.update(tags_lib.convert_taglist(taglist)) timeout = timeout_ms - (int(time.time() * 1000) - start) # workaround for https://bugzilla.gnome.org/show_bug.cgi?id=763553: # if we got what we want then stop playing (and wait for ASYNC_DONE) if tags and duration is not None: pipeline.set_state(Gst.State.PAUSED) raise exceptions.ScannerError('Timeout after %dms' % timeout_ms)
def _process(pipeline, timeout_ms): bus = pipeline.get_bus() tags = {} mime = None have_audio = False missing_message = None duration = None types = (Gst.MessageType.ELEMENT | Gst.MessageType.APPLICATION | Gst.MessageType.ERROR | Gst.MessageType.EOS | Gst.MessageType.ASYNC_DONE | Gst.MessageType.DURATION_CHANGED | Gst.MessageType.TAG) timeout = timeout_ms start = int(time.time() * 1000) while timeout > 0: message = bus.timed_pop_filtered(timeout * Gst.MSECOND, types) if message is None: break elif message.type == Gst.MessageType.ELEMENT: if GstPbutils.is_missing_plugin_message(message): missing_message = message elif message.type == Gst.MessageType.APPLICATION: if message.get_structure().get_name() == 'have-type': mime = message.get_structure().get_value('caps').get_name() if mime and (mime.startswith('text/') or mime == 'application/xml'): return tags, mime, have_audio, duration elif message.get_structure().get_name() == 'have-audio': have_audio = True elif message.type == Gst.MessageType.ERROR: error = encoding.locale_decode(message.parse_error()[0]) 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, duration raise exceptions.ScannerError(error) elif message.type == Gst.MessageType.EOS: return tags, mime, have_audio, duration elif message.type == Gst.MessageType.ASYNC_DONE: success, duration = _query_duration(pipeline) if tags and success: return tags, mime, have_audio, duration # Workaround for upstream bug which causes tags/duration to arrive # after pre-roll. We get around this by starting to play the track # and then waiting for a duration change. # https://bugzilla.gnome.org/show_bug.cgi?id=763553 result = pipeline.set_state(Gst.State.PLAYING) if result == 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. tags.update(tags_lib.convert_taglist(taglist)) timeout = timeout_ms - (int(time.time() * 1000) - start) # workaround for https://bugzilla.gnome.org/show_bug.cgi?id=763553: # if we got what we want then stop playing (and wait for ASYNC_DONE) if tags and duration is not None: pipeline.set_state(Gst.State.PAUSED) raise exceptions.ScannerError('Timeout after %dms' % timeout_ms)
def _process(pipeline, timeout_ms): bus = pipeline.get_bus() tags = {} mime = None have_audio = False missing_message = None duration = None types = ( Gst.MessageType.ELEMENT | Gst.MessageType.APPLICATION | Gst.MessageType.ERROR | Gst.MessageType.EOS | Gst.MessageType.ASYNC_DONE | Gst.MessageType.DURATION_CHANGED | Gst.MessageType.TAG ) timeout = timeout_ms start = int(time.time() * 1000) while timeout > 0: msg = bus.timed_pop_filtered(timeout * Gst.MSECOND, types) if msg is None: break if logger.isEnabledFor(log.TRACE_LOG_LEVEL) and msg.get_structure(): debug_text = msg.get_structure().to_string() if len(debug_text) > 77: debug_text = debug_text[:77] + '...' _trace('element %s: %s', msg.src.get_name(), debug_text) if msg.type == Gst.MessageType.ELEMENT: if GstPbutils.is_missing_plugin_message(msg): missing_message = msg elif msg.type == Gst.MessageType.APPLICATION: if msg.get_structure().get_name() == 'have-type': mime = msg.get_structure().get_value('caps').get_name() if mime and ( mime.startswith('text/') or mime == 'application/xml'): return tags, mime, have_audio, duration elif msg.get_structure().get_name() == 'have-audio': have_audio = True elif msg.type == Gst.MessageType.ERROR: error = encoding.locale_decode(msg.parse_error()[0]) 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, duration raise exceptions.ScannerError(error) elif msg.type == Gst.MessageType.EOS: return tags, mime, have_audio, duration elif msg.type == Gst.MessageType.ASYNC_DONE: success, duration = _query_duration(pipeline) if tags and success: return tags, mime, have_audio, duration # Don't try workaround for non-seekable sources such as mmssrc: if not _query_seekable(pipeline): return tags, mime, have_audio, duration # Workaround for upstream bug which causes tags/duration to arrive # after pre-roll. We get around this by starting to play the track # and then waiting for a duration change. # https://bugzilla.gnome.org/show_bug.cgi?id=763553 logger.debug('Using workaround for duration missing before play.') result = pipeline.set_state(Gst.State.PLAYING) if result == Gst.StateChangeReturn.FAILURE: return tags, mime, have_audio, duration elif msg.type == Gst.MessageType.DURATION_CHANGED and tags: # VBR formats sometimes seem to not have a duration by the time we # go back to paused. So just try to get it right away. success, duration = _query_duration(pipeline) pipeline.set_state(Gst.State.PAUSED) if success: return tags, mime, have_audio, duration elif msg.type == Gst.MessageType.TAG: taglist = msg.parse_tag() # Note that this will only keep the last tag. tags.update(tags_lib.convert_taglist(taglist)) timeout = timeout_ms - (int(time.time() * 1000) - start) raise exceptions.ScannerError('Timeout after %dms' % timeout_ms)