def preroll_done(self): if self.rewrite: gps = [b[-1][0] for b in self.bufs.values() if b] if gps: self.base_gp = max(gps) log.debug('preroll_done: buf lens: %r, rewr: %r (%r), mark: %r', [(t, len(b)) for (t, b) in self.bufs.items()], self.rewrite, self.base_gp, self.mark) for type, mark in ((chunks.MSG_VIDEO, self.mark), (chunks.MSG_AUDIO, False)): frames = self.bufs.get(type) if mark: # TODO: use correct codec id for the info markers, # not always "7" self.nstream.send(0, t, vb('\x57\x00')) if frames: if self.rewrite: self._send_many_zero_gp(type, frames) else: self._send_many(type, frames) frames.clear() self.nstream.send(0, t, vb('\x57\x01')) elif frames: if self.rewrite: self._send_many_zero_gp(type, frames) else: self._send_many(type, frames) frames.clear() self.prerolling = False log.debug('preroll_done: done.')
def _init_connect(self): # why change chunk size? :/ sm = self.muxer.sendMessage sm(0, chunks.PROTO_SET_CHUNK_SIZE, 0, vb('00000400'.decode('hex'))) self.muxer.set_chunk_size(0x0400) app_path = self.factory.get_connect_app_path() app_url = self.factory.get_connect_url() self._app = self.factory.make_app(self) def _connected(info): log.debug('_connected: %r', info) self._app.makeConnection(info) def _translate_failure(failure): failure.trap(CommandResultError) # for the moment we know we tried to connect, hence ConnectError # TODO: add a more fine-grained translation(?) return Failure(ClientConnectError(*failure.value.args)) params = self.make_connect_params(app=app_path, # flashVer='LNX 10,0,22,87', flashVer=CLIENT_VERSION, tcUrl=app_url, objectEncoding=0) extra_params = self._app.get_connect_extra() log.debug('invoking connect(%r, extra=%r)' % (params, extra_params)) d = self.callRemote(0, 'connect', params, *extra_params) d.addErrback(_translate_failure) d.addCallbacks(_connected, self._connect_call_failed) d.addErrback(self._failed_disconnect)
def _init_connect(self): # why change chunk size? :/ sm = self.muxer.sendMessage sm(0, chunks.PROTO_SET_CHUNK_SIZE, 0, vb('00000400'.decode('hex'))) self.muxer.set_chunk_size(0x0400) app_path = self.factory.get_connect_app_path() app_url = self.factory.get_connect_url() self._app = self.factory.make_app(self) def _connected(info): log.debug('_connected: %r', info) self._app.makeConnection(info) def _translate_failure(failure): failure.trap(CommandResultError) # for the moment we know we tried to connect, hence ConnectError # TODO: add a more fine-grained translation(?) return Failure(ClientConnectError(*failure.value.args)) params = self.make_connect_params(app=app_path, # flashVer='LNX 10,0,22,87', flashVer=CLIENT_VERSION, tcUrl=app_url, objectEncoding=0) log.debug('invoking connect(%r)', params) d = self.callRemote(0, 'connect', params, {}) d.addErrback(_translate_failure) d.addCallbacks(_connected, self._connect_call_failed) d.addErrback(self._failed_disconnect)
def _connect_call_failed(self, failure): # this errback might have been fired because of connection # failure, which we handle elsewhere... log.debug('_connect_call_failed: %r', failure.value) if self._app: self._app.failConnection(failure) self._app = None return failure
def got_meta(meta): if meta: self._stream_meta = meta self._nstream.asend(0, chunks.MSG_DATA, 'onStatus', Object(code='NetStream.Data.Start')) log.debug('sending meta: %r', meta) self._nstream.asend(0, chunks.MSG_DATA, 'onMetaData', Object(meta))
def _video_data_cb(self, element): buf = element.emit('pull-buffer') ts = int(buf.timestamp / 1000000.0) ts = ts % 0x100000000 log.debug('[V] %5d [%d] %s', int(ts), int(buf.duration / 1000000), ellip(str(buf).encode('hex'), maxlen=102)) frame = self.make_rtmp_video(buf) reactor.callFromThread(self._stream.write_video, ts, frame)
def _audio_data_cb(self, element): buf = element.emit('pull-buffer') ts = int(buf.timestamp / 1000000.0) ts = ts % 0x100000000 # api clients are supposed to handle # timestamp wraps (4-bytes only) log.debug('[A] %5d [%d] %s', int(ts), int(buf.duration / 1000000), ellip(str(buf).encode('hex'), maxlen=102)) frame = self.make_rtmp_audio(buf) reactor.callFromThread(self._stream.write_audio, ts, frame)
def clientConnectionLost(self, connector, reason): log.debug('clientConnectionLost(%r, %r) [%r]', connector, reason, self._auth_reconnect) if self._auth_reconnect: self._auth_reconnect = False connector.connect() else: if self._do_auth: # update the auth args in case we'll want to re-connect... self.set_app_auth_args(self.auth.get_auth_args(self.cred, None)) SimpleAppClientFactory.clientConnectionLost(self, connector, reason)
def on_meta(self, ts, args): meta = None if (len(args) > 2 and args[0] == '@setDataFrame' and args[1] == 'onMetaData'): meta = args[2] elif len(args) > 1 and args[0] == 'onMetaData': meta = args[1] if meta is not None: log.debug('storing meta: %r', meta) self._stream_meta = dict(meta) d = self._sg.set_meta(self._stream_meta)
def _fcpublish_retry(self, failure, name): log.debug('FCPublish failed, %r', failure.value) if failure.check(UnexpectedStatusError): if failure.value.args[0].code == 'NetStream.Publish.BadName': log.debug('releasing stream and re-trying FCPublish...') self.protocol.signalRemote(0, 'releaseStream', None, name) d = self.protocol.call_FCPublish(name) # note: not re-trying on subsequent failures; # assuming _fcpublish_failed is attached after us: d.addCallback(self._fcpublish_ok, name) return d return failure
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
def _connect_call_failed(self, failure): log.debug('_connect_call_failed: %r', failure.value) if not self.factory._do_auth: # ... :/ return SimpleAppClientProtocol._connect_call_failed(self, failure) log.debug('_connect_call_failed(2): %r', failure.value) desc = check_get_rejected_desc(failure) try: args = self.factory.auth.get_auth_args(self.factory.cred, desc) except: return SimpleAppClientProtocol._connect_call_failed(self, Failure()) if args is not None: self.factory.set_app_auth_args(args) self.factory._auth_reconnect = True # umm... bleehh! :/ return failure
def _add_headers_cb(self, _result): d = defer.succeed(None) def debug_cb(result, msg): log.debug(msg) return result def header_callback_maker(type_): def header_callback(ts, flags, data): return self.on_header_data_added(type_, ts, flags, data) return header_callback def do_read_headers(_result, s, type_): return s.read_headers(header_callback_maker(type_)) log.debug('[adding headers]') for s, type_ in self._tracks: d.addCallback(do_read_headers, s, type_) d.addCallback(debug_cb, '[headers done..]') return d
def _connected(info): log.debug('_connected: %r', info) self._app.makeConnection(info)
def remote_onBWCheck(self, ts, ms_id, _none, probe): log.debug('Bandwidth check probe (size: %r)', len(probe)) return 0
def padNotifyCaps(self, pad, pspec): log.debug("pad %s negotiated caps %s", pad, pad.get_negotiated_caps())
def subscribed(subscription, s): self._subscription.append((s, subscription)) log.debug('(done subscribing: %r)', s)
def onDelete(self, key_name): log.debug("onDelete called for %s" % key_name) d, self._deleted = self._deleted, defer.Deferred() d.callback((self._deleted, key_name))
def _fcpublish_ok(self, result, name): self._fcpublished = name log.debug('FCPublish succeeded: %r', result)
def on_header_data_added(self, type_, ts, flags, data): log.debug('=> %s, %s, %s, %s, %s', ts, type_, flags, self._nstream.id, len(data)) self._nstream.send(0, type_, vb_clone(data))
def debug_cb(result, msg): log.debug(msg) return result
def _remote_abort_handler_eb(self, failure): failure.trap(CallAbortedException) # log failure but do nothing more log.debug('remote call aborted: %s', failure.value)
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
def do_subscribe(_result, s, type_, params): log.debug('(%d: subscribing: %r, %r)', type_, s, params) return s.subscribe(subscr_callback_maker(self._writer, type_), preroll_grpos_range=params[0], preroll_frames=params[1], flag_mask=params[2])
def play_cb(result): log.debug('play handler done') return result
def onChange(self, key_name, value): log.debug("onChange called: %s=%s" % (key_name, value)) d, self._changed = self._changed, defer.Deferred() d.callback((self._changed, key_name, value))
def _dbg(r, msg): log.debug(msg) return r