示例#1
0
    def configure_pipeline(self, pipeline, properties):
        # Later, when the typefind element has successfully found the type
        # of the data, we'll rebuild the pipeline.
        self.src = pipeline.get_by_name('src')
        self.url = properties['url']
        self.passthrough = properties.get('passthrough', False)
        self.src.set_property('location', self.url)
        self.src.set_property('iradio-mode', True)

        typefind = pipeline.get_by_name('tf')
        self.signal_id = typefind.connect('have-type',\
                self._typefind_have_caps_cb)

        if not self.configured:
            self.attachPadMonitorToElement('src', self._src_connected,
                                           self._src_disconnected)
        self.reconnecting = False
        self.reconnector = RetryingDeferred(self.connect)
        self.reconnector.initialDelay = 1.0
        self.attemptD = None

        def _drop_eos(pad, event):
            self.debug('Swallowing event %r', event)
            if event.type == gst.EVENT_EOS:
                return False
            return True

        self.configured = True
        self.src.get_pad('src').add_event_probe(_drop_eos)
示例#2
0
    def testSimple(self):
        def genDef():
            return defer.succeed(True)

        rd = RetryingDeferred(genDef)
        d = rd.start()

        return d
示例#3
0
    def testSimple(self):

        def genDef():
            return defer.succeed(True)

        rd = RetryingDeferred(genDef)
        d = rd.start()

        return d
示例#4
0
    def testRetryOnce(self):
        self.__first = True

        def genDef():
            if self.__first:
                self.__first = False
                return defer.fail(errors.FlumotionError())
            else:
                return defer.succeed(None)

        rd = RetryingDeferred(genDef)
        rd.initialDelay = 0.1 # Set it short so the test isn't long-running.
        d = rd.start()

        return d
示例#5
0
    def testRetryOnce(self):
        self.__first = True

        def genDef():
            if self.__first:
                self.__first = False
                return defer.fail(errors.FlumotionError())
            else:
                return defer.succeed(None)

        rd = RetryingDeferred(genDef)
        rd.initialDelay = 0.1  # Set it short so the test isn't long-running.
        d = rd.start()

        return d
示例#6
0
    def configure_pipeline(self, pipeline, properties):
        # Later, when the typefind element has successfully found the type
        # of the data, we'll rebuild the pipeline.
        self.src = pipeline.get_by_name('src')
        self.url = properties['url']
        self.passthrough = properties.get('passthrough', False)
        self.src.set_property('location', self.url)
        self.src.set_property('iradio-mode', True)

        typefind = pipeline.get_by_name('tf')
        self.signal_id = typefind.connect('have-type',\
                self._typefind_have_caps_cb)

        if not self.configured:
            self.attachPadMonitorToElement('src',
                                           self._src_connected,
                                           self._src_disconnected)
        self.reconnecting = False
        self.reconnector = RetryingDeferred(self.connect)
        self.reconnector.initialDelay = 1.0
        self.attemptD = None

        def _drop_eos(pad, event):
            self.debug('Swallowing event %r', event)
            if event.type == gst.EVENT_EOS:
                return False
            return True
        self.configured = True
        self.src.get_pad('src').add_event_probe(_drop_eos)
示例#7
0
文件: icecast.py 项目: flyapen/UgFlu
    def configure_pipeline(self, pipeline, properties):
        # Later, when the typefind element has successfully found the type
        # of the data, we'll rebuild the pipeline.

        def have_caps(tf, prob, caps):
            capsname = caps[0].get_name()
            # We should add appropriate parsers for any given format here. For
            # some it's critical for this to work at all, for others
            # it's needed for timestamps (thus for things like
            # time-based burst-on-connect) Currently, we only handle ogg.
            parser = None
            if capsname == 'application/ogg':
                parser = gst.element_factory_make('oggparse')
            elif capsname == 'audio/mpeg':
                parser = gst.element_factory_make('mp3parse')

            if parser:
                parser.set_state(gst.STATE_PLAYING)
                pipeline.add(parser)
                # Relink - unlink typefind from the bits that follow it (the
                # gdp payloader), link in the parser, relink to the payloader.
                pad = tf.get_pad('src')
                peer = pad.get_peer()
                pad.unlink(peer)
                tf.link(parser)
                parser.link(peer.get_parent())
                # Disconnect signal to avoid adding a parser every time
                # it gets reconnected.
                tf.disconnect(self.signal_id)

        self.src = pipeline.get_by_name('src')
        self.url = properties['url']
        self.src.set_property('location', self.url)

        typefind = pipeline.get_by_name('tf')
        self.signal_id = typefind.connect('have-type', have_caps)

        self._pad_monitors.attach(self.src.get_pad('src'), 'gnomevfs-src')
        self._pad_monitors['gnomevfs-src'].addWatch(
                self._src_connected, self._src_disconnected)
        self.reconnecting = False
        self.reconnector = RetryingDeferred(self.connect)
        self.reconnector.initialDelay = 1.0
        self.attemptD = None

        def _drop_eos(pad, event):
            self.debug('Swallowing event %r', event)
            if event.type == gst.EVENT_EOS:
                return False
            return True
        self.src.get_pad('src').add_event_probe(_drop_eos)
示例#8
0
class Icecast(feedcomponent.ParseLaunchComponent):

    configured = False

    def get_pipeline_string(self, properties):
        return "souphttpsrc name=src ! typefind name=tf"

    def _typefind_have_caps_cb(self, tf, prob, caps):
        # Basing on the cappabilities plug additional gst compoponents:
        # 1. If we have pure audio (http src doesn't support ICY) plug parser
        # 2. If we have application/x-icy plug the icydemuxer and than parser
        capsname = caps[0].get_name()
        tf_src_pad = tf.get_pad('src')
        gdp_sink_pad = tf_src_pad.get_peer()
        # unlink the typefind from the gdp pad so that we can put another
        # component in it's place
        tf_src_pad.unlink(gdp_sink_pad)

        if capsname == 'application/x-icy':
            demuxer = gst.element_factory_make("icydemux")
            demuxer.set_state(gst.STATE_PLAYING)
            self._demuxer_name = demuxer.get_name()
            self.pipeline.add(demuxer)
            tf.link(demuxer)
            # demuxer src pad is dynamic, we need to register a callback
            demuxer.connect('pad-added', self._link_parser, gdp_sink_pad)
        else:
            self._demuxer_name = None
            self._link_parser(tf, tf_src_pad, gdp_sink_pad)

    def _link_parser(self, element, pad, gdp_sink_pad):
        # Append the audio parser to the end of the pipeline
        caps = pad.get_caps()
        capsname = caps.get_structure(0).get_name()
        self._parser_name = None
        parser = None
        if self.passthrough:
            self.info("Acting in passthrough mode, not parsing the audio")
            pad.link(gdp_sink_pad)
            return
        if capsname == 'application/ogg':
            parser = gst.element_factory_make('oggparse')
        elif capsname == 'audio/mpeg':
            mpegversion = caps[0]['mpegversion']
            if mpegversion == 1:
                self.info("Detecting MP3 stream. Adding 'mp3parse'")
                parser = gst.element_factory_make('mp3parse')
            elif mpegversion in [2, 4]:
                self.info("Detecting AAC stream. Adding 'aacparse'")
                parser = gst.element_factory_make('aacparse')
        if parser:
            self._parser_name = parser.get_name()
            parser.set_state(gst.STATE_PLAYING)
            self.pipeline.add(parser)
            element.link(parser)
            parser.get_pad('src').link(gdp_sink_pad)
        else:
            # in case we good sth else than mp3 or ogg just connect the
            # gdb back
            self.warning("Couldn't find the correct parser for caps: %s",\
                capsname)
            pad.link(gdp_sink_pad)

    def configure_pipeline(self, pipeline, properties):
        # Later, when the typefind element has successfully found the type
        # of the data, we'll rebuild the pipeline.
        self.src = pipeline.get_by_name('src')
        self.url = properties['url']
        self.passthrough = properties.get('passthrough', False)
        self.src.set_property('location', self.url)
        self.src.set_property('iradio-mode', True)

        typefind = pipeline.get_by_name('tf')
        self.signal_id = typefind.connect('have-type',\
                self._typefind_have_caps_cb)

        if not self.configured:
            self.attachPadMonitorToElement('src', self._src_connected,
                                           self._src_disconnected)
        self.reconnecting = False
        self.reconnector = RetryingDeferred(self.connect)
        self.reconnector.initialDelay = 1.0
        self.attemptD = None

        def _drop_eos(pad, event):
            self.debug('Swallowing event %r', event)
            if event.type == gst.EVENT_EOS:
                return False
            return True

        self.configured = True
        self.src.get_pad('src').add_event_probe(_drop_eos)

    def bus_message_received_cb(self, bus, message):
        if message.type == gst.MESSAGE_ERROR and message.src == self.src:
            gerror, debug = message.parse_error()
            self.warning('element %s error %s %s',
                         message.src.get_path_string(), gerror, debug)
            if self.reconnecting:
                self._retry()
            return True
        feedcomponent.ParseLaunchComponent.bus_message_received_cb(
            self, bus, message)

    def connect(self):
        self.info('Connecting to icecast server on %s', self.url)
        self.src.set_state(gst.STATE_READY)
        # can't just self.src.set_state(gst.STATE_PLAYING),
        # because the pipeline might NOT be in PLAYING,
        # if we never connected to Icecast and never went to PLAYING
        self.try_start_pipeline(force=True)
        self.attemptD = defer.Deferred()
        return self.attemptD

    def _src_connected(self, name):
        self.info('Connected to icecast server on %s', self.url)
        if self.reconnecting:
            assert self.attemptD
            self.attemptD.callback(None)
            self.reconnecting = False

    def _reset(self, pad):
        # remove all the elements downstream souphttpsrc.
        if not self._parser_name:
            self.reconnecting = True
            self.reconnector.start()
            return

        tf = self.get_element('tf')
        pad.unlink(tf.get_pad('sink'))

        parser = self.get_element(self._parser_name)
        tf.get_pad('src').unlink(parser.get_pad('sink'))
        peer = parser.get_pad('src').get_peer()
        parser.get_pad('src').unlink(peer)

        parser.set_state(gst.STATE_NULL)
        self.pipeline.remove(parser)
        self._parser_name = None
        tf.set_state(gst.STATE_NULL)
        self.pipeline.remove(tf)
        if self._demuxer_name is not None:
            demuxer = self.get_element(self._demuxer_name)
            demuxer.set_state(gst.STATE_NULL)
            self.pipeline.remove(demuxer)
            self._demuxer_name = None

        # recreate the typefind element in order to be in the same state as
        # when the component was first initiated
        tf = gst.element_factory_make('typefind', 'tf')
        self.pipeline.add(tf)
        tf.set_state(gst.STATE_PLAYING)
        pad.link(tf.get_pad('sink'))
        tf.get_pad('src').link(peer)

        # reconfigure the pipeline
        self.configure_pipeline(self.pipeline, self.config['properties'])
        self.pipeline.set_state(gst.STATE_PLAYING)
        self.reconnecting = True
        self.reconnector.start()

    def _src_disconnected(self, name):
        self.info('Disconnected from icecast server on %s', self.url)
        if not self.reconnecting:
            src = self.get_element('src')
            pad = src.get_pad('src')
            self._reset(pad)

    def _retry(self):
        assert self.attemptD
        self.debug('Retrying connection to icecast server on %s', self.url)
        self.attemptD.errback(errors.ConnectionError)
示例#9
0
class Icecast(feedcomponent.ParseLaunchComponent):

    configured = False

    def get_pipeline_string(self, properties):
        return "souphttpsrc name=src ! typefind name=tf"

    def _typefind_have_caps_cb(self, tf, prob, caps):
        # Basing on the cappabilities plug additional gst compoponents:
        # 1. If we have pure audio (http src doesn't support ICY) plug parser
        # 2. If we have application/x-icy plug the icydemuxer and than parser
        capsname = caps[0].get_name()
        tf_src_pad = tf.get_pad('src')
        gdp_sink_pad = tf_src_pad.get_peer()
        # unlink the typefind from the gdp pad so that we can put another
        # component in it's place
        tf_src_pad.unlink(gdp_sink_pad)

        if capsname == 'application/x-icy':
            demuxer = gst.element_factory_make("icydemux")
            demuxer.set_state(gst.STATE_PLAYING)
            self._demuxer_name = demuxer.get_name()
            self.pipeline.add(demuxer)
            tf.link(demuxer)
            # demuxer src pad is dynamic, we need to register a callback
            demuxer.connect('pad-added', self._link_parser, gdp_sink_pad)
        else:
            self._demuxer_name = None
            self._link_parser(tf, tf_src_pad, gdp_sink_pad)

    def _link_parser(self, element, pad, gdp_sink_pad):
        # Append the audio parser to the end of the pipeline
        caps = pad.get_caps()
        capsname = caps.get_structure(0).get_name()
        self._parser_name = None
        parser = None
        if self.passthrough:
            self.info("Acting in passthrough mode, not parsing the audio")
            pad.link(gdp_sink_pad)
            return
        if capsname == 'application/ogg':
            parser = gst.element_factory_make('oggparse')
        elif capsname == 'audio/mpeg':
            mpegversion = caps[0]['mpegversion']
            if mpegversion == 1:
                self.info("Detecting MP3 stream. Adding 'mp3parse'")
                parser = gst.element_factory_make('mp3parse')
            elif mpegversion in [2, 4]:
                self.info("Detecting AAC stream. Adding 'aacparse'")
                parser = gst.element_factory_make('aacparse')
        if parser:
            self._parser_name = parser.get_name()
            parser.set_state(gst.STATE_PLAYING)
            self.pipeline.add(parser)
            element.link(parser)
            parser.get_pad('src').link(gdp_sink_pad)
        else:
            # in case we good sth else than mp3 or ogg just connect the
            # gdb back
            self.warning("Couldn't find the correct parser for caps: %s",\
                capsname)
            pad.link(gdp_sink_pad)

    def configure_pipeline(self, pipeline, properties):
        # Later, when the typefind element has successfully found the type
        # of the data, we'll rebuild the pipeline.
        self.src = pipeline.get_by_name('src')
        self.url = properties['url']
        self.passthrough = properties.get('passthrough', False)
        self.src.set_property('location', self.url)
        self.src.set_property('iradio-mode', True)

        typefind = pipeline.get_by_name('tf')
        self.signal_id = typefind.connect('have-type',\
                self._typefind_have_caps_cb)

        if not self.configured:
            self.attachPadMonitorToElement('src',
                                           self._src_connected,
                                           self._src_disconnected)
        self.reconnecting = False
        self.reconnector = RetryingDeferred(self.connect)
        self.reconnector.initialDelay = 1.0
        self.attemptD = None

        def _drop_eos(pad, event):
            self.debug('Swallowing event %r', event)
            if event.type == gst.EVENT_EOS:
                return False
            return True
        self.configured = True
        self.src.get_pad('src').add_event_probe(_drop_eos)

    def bus_message_received_cb(self, bus, message):
        if message.type == gst.MESSAGE_ERROR and message.src == self.src:
            gerror, debug = message.parse_error()
            self.warning('element %s error %s %s',
                    message.src.get_path_string(), gerror, debug)
            if self.reconnecting:
                self._retry()
            return True
        feedcomponent.ParseLaunchComponent.bus_message_received_cb(
                self, bus, message)

    def connect(self):
        self.info('Connecting to icecast server on %s', self.url)
        self.src.set_state(gst.STATE_READY)
        # can't just self.src.set_state(gst.STATE_PLAYING),
        # because the pipeline might NOT be in PLAYING,
        # if we never connected to Icecast and never went to PLAYING
        self.try_start_pipeline(force=True)
        self.attemptD = defer.Deferred()
        return self.attemptD

    def _src_connected(self, name):
        self.info('Connected to icecast server on %s', self.url)
        if self.reconnecting:
            assert self.attemptD
            self.attemptD.callback(None)
            self.reconnecting = False

    def _reset(self, pad):
        # remove all the elements downstream souphttpsrc.
        if not self._parser_name:
            self.reconnecting = True
            self.reconnector.start()
            return

        tf = self.get_element('tf')
        pad.unlink(tf.get_pad('sink'))

        parser = self.get_element(self._parser_name)
        tf.get_pad('src').unlink(parser.get_pad('sink'))
        peer = parser.get_pad('src').get_peer()
        parser.get_pad('src').unlink(peer)

        parser.set_state(gst.STATE_NULL)
        self.pipeline.remove(parser)
        self._parser_name = None
        tf.set_state(gst.STATE_NULL)
        self.pipeline.remove(tf)
        if self._demuxer_name is not None:
            demuxer = self.get_element(self._demuxer_name)
            demuxer.set_state(gst.STATE_NULL)
            self.pipeline.remove(demuxer)
            self._demuxer_name = None

        # recreate the typefind element in order to be in the same state as
        # when the component was first initiated
        tf = gst.element_factory_make('typefind', 'tf')
        self.pipeline.add(tf)
        tf.set_state(gst.STATE_PLAYING)
        pad.link(tf.get_pad('sink'))
        tf.get_pad('src').link(peer)

        # reconfigure the pipeline
        self.configure_pipeline(self.pipeline, self.config['properties'])
        self.pipeline.set_state(gst.STATE_PLAYING)
        self.reconnecting = True
        self.reconnector.start()

    def _src_disconnected(self, name):
        self.info('Disconnected from icecast server on %s', self.url)
        if not self.reconnecting:
            src = self.get_element('src')
            pad = src.get_pad('src')
            self._reset(pad)

    def _retry(self):
        assert self.attemptD
        self.debug('Retrying connection to icecast server on %s', self.url)
        self.attemptD.errback(errors.ConnectionError)
示例#10
0
文件: icecast.py 项目: flyapen/UgFlu
class Icecast(feedcomponent.ParseLaunchComponent):

    def get_pipeline_string(self, properties):
        return "gnomevfssrc name=src ! typefind name=tf"

    def configure_pipeline(self, pipeline, properties):
        # Later, when the typefind element has successfully found the type
        # of the data, we'll rebuild the pipeline.

        def have_caps(tf, prob, caps):
            capsname = caps[0].get_name()
            # We should add appropriate parsers for any given format here. For
            # some it's critical for this to work at all, for others
            # it's needed for timestamps (thus for things like
            # time-based burst-on-connect) Currently, we only handle ogg.
            parser = None
            if capsname == 'application/ogg':
                parser = gst.element_factory_make('oggparse')
            elif capsname == 'audio/mpeg':
                parser = gst.element_factory_make('mp3parse')

            if parser:
                parser.set_state(gst.STATE_PLAYING)
                pipeline.add(parser)
                # Relink - unlink typefind from the bits that follow it (the
                # gdp payloader), link in the parser, relink to the payloader.
                pad = tf.get_pad('src')
                peer = pad.get_peer()
                pad.unlink(peer)
                tf.link(parser)
                parser.link(peer.get_parent())
                # Disconnect signal to avoid adding a parser every time
                # it gets reconnected.
                tf.disconnect(self.signal_id)

        self.src = pipeline.get_by_name('src')
        self.url = properties['url']
        self.src.set_property('location', self.url)

        typefind = pipeline.get_by_name('tf')
        self.signal_id = typefind.connect('have-type', have_caps)

        self._pad_monitors.attach(self.src.get_pad('src'), 'gnomevfs-src')
        self._pad_monitors['gnomevfs-src'].addWatch(
                self._src_connected, self._src_disconnected)
        self.reconnecting = False
        self.reconnector = RetryingDeferred(self.connect)
        self.reconnector.initialDelay = 1.0
        self.attemptD = None

        def _drop_eos(pad, event):
            self.debug('Swallowing event %r', event)
            if event.type == gst.EVENT_EOS:
                return False
            return True
        self.src.get_pad('src').add_event_probe(_drop_eos)

    def bus_message_received_cb(self, bus, message):
        if message.type == gst.MESSAGE_ERROR and message.src == self.src:
            gerror, debug = message.parse_error()
            self.warning('element %s error %s %s',
                    message.src.get_path_string(), gerror, debug)
            if self.reconnecting:
                self._retry()
            return True
        feedcomponent.ParseLaunchComponent.bus_message_received_cb(
                self, bus, message)

    def connect(self):
        self.info('Connecting to icecast server: %s', self.url)
        self.src.set_state(gst.STATE_READY)
        # can't just self.src.set_state(gst.STATE_PLAYING),
        # because the pipeline might NOT be in PLAYING,
        # if we never connected to Icecast and never went to PLAYING
        self.try_start_pipeline(force=True)
        self.attemptD = defer.Deferred()
        return self.attemptD

    def _src_connected(self, name):
        self.info('Connected to icecast server : %s', self.url)
        if self.reconnecting:
            assert self.attemptD
            self.attemptD.callback(None)
            self.reconnecting = False

    def _src_disconnected(self, name):
        self.info('Icecast server: %s got disconnected', self.url)
        if not self.reconnecting:
            self.reconnecting = True
            self.reconnector.start()

    def _retry(self):
        assert self.attemptD
        self.debug('Retrying connection to icecast server: %s', self.url)
        self.attemptD.errback(errors.ConnectionError)