Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
 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()
Ejemplo n.º 4
0
 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()
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
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)