Exemple #1
0
    def connectionLost(self, reason):
        log.info('app disconnected: %s', reason.getErrorMessage())
        if self._stream:
            self.closeStream(self._stream, force=True)
            self._stream = None

        self.publish_source = None
Exemple #2
0
    def play(self, net_stream, stream_name, start=-2, duration=-1,
             reset=True):
        # rtmpdump (commandline client) sends -1000 for live streams
        # flash based clients (flowplayer) send -2 instead
        assert start in (-2, -1000), 'only live streams'

        # ignoring duration and reset for now...

        log.info('opening stream %r', stream_name)

        def got_streamgroup(streamgroup):
            self.sg = streamgroup
            log.debug('starting playing %r', streamgroup)

            self.ctrl = c = RTMPPlayer(streamgroup)
            c.connect(net_stream)

            log.debug('calling c.start()...')
            d = c.start()
            def _dbg(r, msg):
                log.debug(msg)
                return r
            d.addCallback(_dbg, 'c.start()... done.')

            return d

        d = self.server.open(stream_name, namespace=self.ns)
        d.addCallback(got_streamgroup)
        return d
    def play(self, net_stream, stream_name, start=-2, duration=-1,
             reset=True):
        assert start == -2, 'only live streams'

        # ignoring duration and reset for now...

        log.info('opening stream %r', stream_name)

        def got_streamgroup(streamgroup):
            self.sg = streamgroup
            log.debug('starting playing %r', streamgroup)

            self.ctrl = c = RTMPPlayer(streamgroup)
            c.connect(net_stream)

            log.debug('calling c.start()...')
            d = c.start()
            def _dbg(r, msg):
                log.debug(msg)
                return r
            d.addCallback(_dbg, 'c.start()... done.')

            return d

        d = self.server.open(stream_name, namespace=self.ns)
        d.addCallback(got_streamgroup)
        return d
Exemple #4
0
    def on_mute_message(self, ts, type_, do_send):
        log.info('on_mute_message: %s, %s, %s', ts, type_, do_send)

        if type_ == chunks.MSG_AUDIO:
            self._send_audio = do_send
        else:
            self._send_video = do_send
Exemple #5
0
    def publish(self, net_stream, stream_name, publish_type='live'):
        publish_type = 'live'
        if publish_type != 'live':
            # this app is only for live streams
            raise CallResultError('only live streams for now')

        def got_streamgroup(streamgroup):
            self.sg = streamgroup

            self.ctrl = r = RTMPRecorder(streamgroup)
            r.connect(net_stream)

            d = r.start()
            return d

        # normalize stream_name better? :/
        # this just throws away url-type args:
        args = ''
        name_args = stream_name.split('?', 1)
        stream_name = name_args[0]
        if len(name_args) > 1:
            args = name_args[1]

        log.info('requested publishing of: %r with args %r', stream_name, args)
        d = self.server.open(stream_name, mode='l', namespace=self.ns)

        # AppDispatchServerProtocol should handle reporting failures
        # in server.open() for us... (strange idea? :/ )
        d.addCallback(got_streamgroup)
        return d
Exemple #6
0
    def prepare_video(self):
        log.info('prepare_video, caps: "%s"', self.video_caps)
        if self.video_codec.codecId == 7:
            codec_data = self.video_caps[0]['codec_data']
            self.video_avc_profile = ord(codec_data[1])
            self.video_avc_level = ord(codec_data[3])

            self._make_rtmp_video = self._make_rtmp_video_complex
        else:
            self._make_rtmp_video = self._make_rtmp_video_simple
Exemple #7
0
    def connectionLost(self, reason):
        log.info('app connection lost: %r (%r)', reason, self.sg)

        if self.ctrl:
            self.ctrl.stop()
            self.ctrl.disconnect()
            self.ctrl = None

        if self.sg:
            sg, self.sg = self.sg, None
            self.server.close(sg)
Exemple #8
0
    def command_onBWDone(self, ts, ms_id, trans_id, _none,
                         bw, _ignore1=None, _ignore2=None, latency=None):
        log.info('Bandwidth check done (estimated bandwidth: %r, latency: %r)',
                 bw, latency)

        if self._app:
            handler_m = None
            if self._app:
                handler_m = getattr(self._app, 'onBWDone', None)

        if handler_m is None:
            return

        return handler_m(ts, ms_id, trans_id, _none, bw, latency)
Exemple #9
0
    def _build_pipeline(self):
        self.make_pipeline()
        log.info('pipeline: %r', self.pipeline)

        self._caps_pending = {}
        if self.audio_codec:
            pad = self.asink.get_static_pad('sink')
            cid = pad.connect('notify::caps', self._got_caps_cb)
            self._caps_pending[pad] = (cid, 0)

        if self.video_codec:
            pad = self.vsink.get_static_pad('sink')
            cid = pad.connect('notify::caps', self._got_caps_cb)
            self._caps_pending[pad] = (cid, 1)
Exemple #10
0
    def connect(self, request, req_opts):
        log.info('connect(%r, %r)', request, req_opts)

        # note: order of setting attributes is important
        server_info = (Object(fmsVer=SERVER_VERSION_STRING)
                       .s(capabilities=31)
                       .s(mode=1))

        status_info = (Object(level='status')
                       .s(code='NetConnection.Connect.Success')
                       .s(description='Connection succeeded.')
                       .s(objectEncoding=0)
                       .s(data={'version': '%d,%d,%d,%d' % SERVER_VERSION}))

        return server_info, status_info
Exemple #11
0
    def prepare_audio(self):
        log.info('prepare_audio, caps: "%s"', self.audio_caps)
        if self.audio_codec.codecId in (10, 11): # aac and speex are always
                                         # marked 44kHz, stereo
            rate = 44100
            channels = 2
        else:
            rate = self.audio_rate
            channels = self.channels

        h1 = self.audio_codec.codecId << 4
        h1 |= {44100: 3, 22050: 2, 11025: 1}.get(rate, 3) << 2
        h1 |= 1 << 1             # always 16-bit size
        h1 |= int(channels == 2)

        self._ah1 = h1

        if self.complex_audio_header:
            self._header_audio = _s_double_uchar.pack(h1, 1) # h1 | "keyframe"
        else:
            self._header_audio = _s_uchar.pack(h1)
Exemple #12
0
    def discover_client_scheme(self, context):
        ts, v0, v1, v2, v3 = _s_ts_ver.unpack_from(context, 0)
        client_ver = (v0, v1, v2, v3)

        if client_ver == NO_VERSION:
            log.info("no client version - won't use crypto handshake")
            return None

        log.debug('client version: %s', client_ver)

        # non-zero version - let's find out the scheme
        scheme = find_client_offset_scheme(client_ver)
        log.debug('scheme from ver: %s', scheme)
        if scheme is not None:
            if self._check_client_scheme(scheme, context):
                log.debug('verified client scheme: %s', scheme)
                self._digest_offset_extractor = schemes[scheme][0]
                return scheme

        log.debug('trying all known schemes...')
        # the exact version<->scheme match didn't help - try all the
        # other known schemes
        for i in xrange(len(schemes)):
            if i == scheme:
                # we've checked that one already
                continue

            if self._check_client_scheme(i, context):
                log.debug('verified client scheme: %s', i)
                self._digest_offset_extractor = schemes[i][0]
                return i

        log.info("couldn't figure the client scheme out")
        if not self.strict:
            # Why so strict? Let's just use the lowest scheme we know
            log.debug('selecting scheme anyway: %s', OFFSET_SCHEME_1)
            return OFFSET_SCHEME_1

        return None
Exemple #13
0
    def dataReceived(self, data):
        self._buf.write(data)

        while 1:  # need to be able to retry immediately when handlers change
            try:
                while len(self._buf) >= self._toread:
                    self._toread = self._handler.send(self._buf)
                break  # no data, no retry
            except StopIteration:
                if self._handler_changed:
                    self._handler_changed = False
                else:
                    self._toread = None
                    self._handler = None
                    break
            except:
                # undocumented, but real; this way we can signal
                # protocol errors directly, and by not passing/raising
                # directly we avoid a stack trace log, with the same
                # effect - connectionLost
                f = failure.Failure()
                log.info(f.value, exc_info=log.isEnabledFor(logging.DEBUG))
                return f
Exemple #14
0
    def dataReceived(self, data):
        self._buf.write(data)

        while 1: # need to be able to retry immediately when handlers change
            try:
                while len(self._buf) >= self._toread:
                    self._toread = self._handler.send(self._buf)
                break           # no data, no retry
            except StopIteration:
                if self._handler_changed:
                    self._handler_changed = False
                else:
                    self._toread = None
                    self._handler = None
                    break
            except:
                # undocumented, but real; this way we can signal
                # protocol errors directly, and by not passing/raising
                # directly we avoid a stack trace log, with the same
                # effect - connectionLost
                f = failure.Failure()
                log.info(f.value, exc_info=log.isEnabledFor(logging.DEBUG))
                return f
Exemple #15
0
    def _remote_handler_eb(self, failure, ms_id, trans_id):
        if log.isEnabledFor(logging.DEBUG):
            log.info('remote call failure: %s', failure.value,
                     exc_info=(failure.type, failure.value,
                               failure.getTracebackObject()))
        else:
            log.info('remote call failure: %s', failure.value)

        fatal = False
        if failure.check(CallResultError):
            body = self.encode_amf('_error', trans_id,
                                   *failure.value.get_error_args())
            fatal = failure.value.is_fatal
        else:
            err = amf0.Object(code='NetStream.Failed', level='error',
                              description=repr(failure.value))
            body = self.encode_amf('_error', trans_id, None, err)

        ts = ms_time_wrapped(self.session_time())
        self.muxer.sendMessage(ts, chunks.MSG_COMMAND, ms_id, body)

        if fatal:
            self.transport.loseConnection()
Exemple #16
0
 def log_failure(failure):
     # log the failure and consume it
     log.info(failure.value, exc_info=log.isEnabledFor(logging.DEBUG))
     return None
Exemple #17
0
 def _fcpublish_failed(self, failure):
     self._state = None
     log.info('FCPublish failed: %r', failure.value,
              exc_info=log.isEnabledFor(logging.DEBUG))
     return failure
Exemple #18
0
 def _failed_unpublishing(self, failure):
     log.info('failed unpublishing - Huh?!')
     return failure
Exemple #19
0
 def command_onBWDone(self, ts, ms_id, trans_id, _none,
                      bw, _ignore1=None, _ignore2=None, latency=None):
     log.info('Bandwidth check done (estimated bandwidth: %r, latency: %r)',
              bw, latency)
Exemple #20
0
 def _publish_failed(self, failure):
     self._state = None
     log.info('publish failed: %r', failure)
     return failure
 def clientConnectionLost(self, _connector, reason):
     log.info('lost connection: %s', reason.getErrorMessage())
     if reactor.running:
         reactor.stop()
Exemple #22
0
 def command_close(self, ts, ms_id, trans_id, *args):
     log.info('Closing connection on server request.')
     self.transport.loseConnection()
Exemple #23
0
 def _failed_disconnect(self, failure):
     log.info("Failed 'connecting': %r", failure.value)
     self.transport.loseConnection()
Exemple #24
0
 def _publish_failed(self, failure):
     self._state = None
     log.info('publish failed: %r', failure)
     return failure
Exemple #25
0
 def _failed_unpublishing(self, failure):
     log.info('failed unpublishing - Huh?!')
     return failure
Exemple #26
0
 def clientConnectionLost(self, _connector, reason):
     log.info('lost connection: %s', reason.getErrorMessage())
     if reactor.running:
         reactor.stop()
Exemple #27
0
 def connectionMade(self, info):
     log.info('Yay, connected! (%r)', info)
     # assert server (info) supports necessary codecs?
     d = self.createStream()
     d.addCallbacks(self._start_streaming, self._disconnect)
Exemple #28
0
 def command_close(self, ts, ms_id, trans_id, *args):
     log.info('Closing connection on server request.')
     self.transport.loseConnection()
Exemple #29
0
 def log_failure(failure):
     # log the failure and consume it
     log.info(failure.value, exc_info=log.isEnabledFor(logging.DEBUG))
     return None
Exemple #30
0
 def _failed_disconnect(self, failure):
     log.info("Failed 'connecting': %r", failure.value)
     self.transport.loseConnection()
 def _bus_message_eos_cb(self, bus, message):
     log.info("eos, quitting")
     reactor.stop()
Exemple #32
0
 def _fcpublish_failed(self, failure):
     self._state = None
     log.info('FCPublish failed: %r', failure.value,
              exc_info=log.isEnabledFor(logging.DEBUG))
     return failure
Exemple #33
0
 def _fail(self, msg=None):
     if msg is not None:
         log.info('ADSP._fail: %s', msg)
     self.transport.loseConnection()
Exemple #34
0
    def remote_createStream(self, ts, ms_id, _none):
        s = self._nsmgr.make_stream(self)
        log.info('created message stream: %r', s.id)

        return None, s.id
 def connectionMade(self, info):
     log.info('Yay, connected! (%r)', info)
     # assert server (info) supports necessary codecs?
     d = self.createStream()
     d.addCallbacks(self._start_streaming, self._disconnect)
Exemple #36
0
 def _bus_message_eos_cb(self, bus, message):
     log.info("eos, quitting")
     reactor.stop()
Exemple #37
0
 def command_onBWDone(self, ts, ms_id, trans_id, _none,
                      bw, _ignore1=None, _ignore2=None, latency=None):
     log.info('Bandwidth check done (estimated bandwidth: %r, latency: %r)',
              bw, latency)