def sendMessage(self, msg, stream, whenDone=None): """ Queues L{msg} for encoding into RTMP and being spit out to L{output}. This is a low level api and is not for public consumption. Use L{interfaces.IStream.sendMessage} instead. @param msg: The message being sent to the peer. @type msg: L{message.IMessage} @param stream: The stream instance that is sending the message. @type stream: L{interfaces.IStream} @param whenDone: A callback fired when the message has been written to the RTMP stream. See L{BaseStream.sendMessage} """ buf = BufferedByteStream() e = self.encoder # this will probably need to be rethought as this could block for an # unacceptable amount of time. For most messages however it seems to be # fast enough and the penalty for setting up a new thread is too high. msg.encode(buf) e.send(buf.getvalue(), msg.__data_type__, stream.streamId, stream.timestamp, whenDone) if e.active and not self._encoding_task: self.startEncoding()
def sendMessage(self, msg, stream, whenDone=None): """ Sends an RTMP message to the peer. Not part of a public api, use C{stream.sendMessage} instead. @param msg: The message being sent to the peer. @type msg: L{message.IMessage} @param stream: The stream instance that is sending the message. @type stream: L{NetStream} @param whenDone: A callback fired when the message has been written to the RTMP stream. See L{BaseStream.sendMessage} """ buf = BufferedByteStream() e = self.encoder # this will probably need to be rethought as this could block for an # unacceptable amount of time. For most messages however it seems to be # fast enough and the penalty for setting up a new thread is too high. msg.encode(buf) e.send(buf.getvalue(), msg.__data_type__, stream.streamId, stream.timestamp, whenDone) if e.active and not self.encoder_task: self.startEncoding()
def sendMessage(self, msg, stream, whenDone=None): """ Sends an RTMP message to the peer. Not part of a public api, use C{stream.sendMessage} instead. @param msg: The message being sent to the peer. @type msg: L{message.IMessage} @param stream: The stream instance that is sending the message. @type stream: L{NetStream} @param whenDone: A callback fired when the message has been written to the RTMP stream. See L{BaseStream.sendMessage} """ buf = BufferedByteStream() e = self.encoder # this will probably need to be rethought as this could block for an # unacceptable amount of time. For most messages however it seems to be # fast enough and the penalty for setting up a new thread is too high. msg.encode(buf) e.send(buf.getvalue(), msg.__data_type__, stream.streamId, stream.timestamp, whenDone) if e.active and not self.encoder_task: self.startEncoding()
class _BackRelay(protocol.ProcessProtocol): def __init__(self, deferred): self.deferred = deferred self.s = BufferedByteStream() def errReceived(self, text): self.deferred.errback(failure.Failure(IOError())) self.deferred = None self.transport.loseConnection() def outReceived(self, text): self.s.write(text) def processEnded(self, reason): if self.deferred is not None: result = self.s.getvalue() self.deferred.callback(result)
class _BackRelay(protocol.ProcessProtocol): def __init__(self, deferred): self.deferred = deferred self.s = BufferedByteStream() def errReceived(self, text): self.deferred.errback(failure.Failure(IOError())) self.deferred = None self.transport.loseConnection() def outReceived(self, text): self.s.write(text) def processEnded(self, reason): if self.deferred is not None: result = self.s.getvalue() self.deferred.callback(result)
class StreamingChannel(object): """ """ def __init__(self, channel, streamId, output): self.type = None self.channel = channel self.streamId = streamId self.output = output self.stream = BufferedByteStream() self._lastHeader = None self._oldStream = channel.stream channel.stream = self.stream h = header.Header(channel.channelId) # encode a continuation header for speed header.encode(self.stream, h, h) self._continuationHeader = self.stream.getvalue() self.stream.consume() def __del__(self): try: self.channel.stream = self._oldStream except: pass def setType(self, type): self.type = type def sendData(self, data, timestamp): c = self.channel if timestamp < c.timestamp: relTimestamp = timestamp else: relTimestamp = timestamp - c.timestamp h = header.Header(c.channelId, relTimestamp, self.type, len(data), self.streamId) if self._lastHeader is None: h.full = True c.setHeader(h) c.append(data) header.encode(self.stream, h, self._lastHeader) self._lastHeader = h c.marshallOneFrame() while not c.complete(): self.stream.write(self._continuationHeader) c.marshallOneFrame() c.reset() self.output.write(self.stream.getvalue()) self.stream.consume()
class BaseNegotiator(object): """ Base functionality for negotiating an RTMP handshake. @ivar observer: An observer for handshake negotiations. @type observer: L{IHandshakeObserver} @ivar buffer: Any data that has not yet been consumed. @type buffer: L{BufferedByteStream} @ivar started: Determines whether negotiations have already begun. @type started: C{bool} @ivar my_syn: The initial handshake packet that will be sent by this negotiator. @type my_syn: L{Packet} @ivar my_ack: The handshake packet that will be sent after the peer has sent its syn. @ivar peer_syn: The initial L{Packet} received from the peer. @ivar peer_ack: The L{Packet} received in acknowledgement of my syn. @ivar peer_version: The handshake version that the peer understands. """ implements(IHandshakeNegotiator) def __init__(self, observer, transport): self.observer = observer self.transport = transport self.started = False def start(self, uptime=None, version=None): """ Called to start the handshaking negotiations. """ if self.started: raise HandshakeError('Handshake negotiator cannot be restarted') self.started = True self.buffer = BufferedByteStream() self.peer_version = None self.my_syn = Packet(uptime, version) self.my_ack = None self.peer_syn = None self.peer_ack = None self.buildSynPayload(self.my_syn) self._writePacket(self.my_syn) def getPeerPacket(self): """ Attempts to decode a L{Packet} from the buffer. If there is not enough data in the buffer then C{None} is returned. """ if self.buffer.remaining() < HANDSHAKE_LENGTH: # we're expecting more data return packet = Packet() packet.decode(self.buffer) return packet def _writePacket(self, packet, stream=None): stream = stream or BufferedByteStream() packet.encode(stream) self.transport.write(stream.getvalue()) def dataReceived(self, data): """ Called when handshake data has been received. If an error occurs whilst negotiating the handshake then C{self.observer.handshakeFailure} will be called, citing the reason. 3 stages of data are received. The handshake version, the syn packet and then the ack packet. """ if not self.started: raise HandshakeError('Data was received, but negotiator was ' 'not started') self.buffer.append(data) self._process() def _process(self): if not self.peer_syn: self.peer_syn = self.getPeerPacket() if not self.peer_syn: return self.buffer.consume() self.synReceived() if not self.peer_ack: self.peer_ack = self.getPeerPacket() if not self.peer_ack: return self.buffer.consume() self.ackReceived() # if we get here then a successful handshake has been negotiated. # inform the observer accordingly self.observer.handshakeSuccess(self.buffer.getvalue()) def writeAck(self): """ Writes L{self.my_ack} to the observer. """ self._writePacket(self.my_ack) def buildSynPayload(self, packet): """ Called to build the syn packet, based on the state of the negotiations. """ raise NotImplementedError def buildAckPayload(self, packet): """ Called to build the ack packet, based on the state of the negotiations. """ raise NotImplementedError def synReceived(self): """ Called when the peers syn packet has been received. Use this function to do any validation/verification. """ def ackReceived(self): """
class StreamingChannel(object): """ """ def __init__(self, encoder, streamId, output): self.encoder = encoder self.channel = self.encoder.acquireChannel() if self.channel is None: # todo: make this better raise RuntimeError('No streaming channel available') self.type = None self.streamId = streamId self.output = output self.stream = BufferedByteStream() self._lastHeader = None self._oldStream = self.channel.stream self.channel.stream = self.stream h = header.Header(self.channel.channelId) # encode a continuation header for speed header.encode(self.stream, h, h) self._continuationHeader = self.stream.getvalue() self.stream.consume() def __del__(self): try: self.channel.stream = self._oldStream except: pass def setType(self, type): self.type = type def sendData(self, data, timestamp): c = self.channel if timestamp < c.timestamp: relTimestamp = timestamp else: relTimestamp = timestamp - c.timestamp h = header.Header(c.channelId, relTimestamp, self.type, len(data), self.streamId) if self._lastHeader is None: h.full = True c.setHeader(h) c.append(data) header.encode(self.stream, h, self._lastHeader) self._lastHeader = h c.marshallOneFrame() while not c.complete(): self.stream.write(self._continuationHeader) c.marshallOneFrame() c.reset() s = self.stream.getvalue() self.output.write(s) self.encoder.bytes += len(s) self.stream.consume()
class BaseNegotiator(object): """ Base functionality for negotiating an RTMP handshake. @ivar observer: An observer for handshake negotiations. @type observer: L{IHandshakeObserver} @ivar buffer: Any data that has not yet been consumed. @type buffer: L{BufferedByteStream} @ivar started: Determines whether negotiations have already begun. @type started: C{bool} @ivar my_syn: The initial handshake packet that will be sent by this negotiator. @type my_syn: L{Packet} @ivar my_ack: The handshake packet that will be sent after the peer has sent its syn. @ivar peer_syn: The initial L{Packet} received from the peer. @ivar peer_ack: The L{Packet} received in acknowledgement of my syn. @ivar peer_version: The handshake version that the peer understands. """ implements(IHandshakeNegotiator) def __init__(self, observer, transport): self.observer = observer self.transport = transport self.started = False def start(self, uptime=None, version=None): """ Called to start the handshaking negotiations. """ if self.started: raise HandshakeError('Handshake negotiator cannot be restarted') self.started = True self.buffer = BufferedByteStream() self.peer_version = None self.my_syn = Packet(uptime, version) self.my_ack = None self.peer_syn = None self.peer_ack = None self.buildSynPayload(self.my_syn) self._writePacket(self.my_syn) def getPeerPacket(self): """ Attempts to decode a L{Packet} from the buffer. If there is not enough data in the buffer then C{None} is returned. """ if self.buffer.remaining() < HANDSHAKE_LENGTH: # we're expecting more data return packet = Packet() packet.decode(self.buffer) return packet def _writePacket(self, packet, stream=None): stream = stream or BufferedByteStream() packet.encode(stream) self.transport.write(stream.getvalue()) def dataReceived(self, data): """ Called when handshake data has been received. If an error occurs whilst negotiating the handshake then C{self.observer.handshakeFailure} will be called, citing the reason. 3 stages of data are received. The handshake version, the syn packet and then the ack packet. """ if not self.started: raise HandshakeError('Data was received, but negotiator was ' 'not started') self.buffer.append(data) self._process() def _process(self): if not self.peer_syn: self.peer_syn = self.getPeerPacket() if not self.peer_syn: return self.buffer.consume() self.synReceived() if not self.peer_ack: self.peer_ack = self.getPeerPacket() if not self.peer_ack: return self.buffer.consume() self.ackReceived() # if we get here then a successful handshake has been negotiated. # inform the observer accordingly self.observer.handshakeSuccess(self.buffer.getvalue()) def writeAck(self): """ Writes L{self.my_ack} to the observer. """ self._writePacket(self.my_ack) def buildSynPayload(self, packet): """ Called to build the syn packet, based on the state of the negotiations. """ raise NotImplementedError def buildAckPayload(self, packet): """ Called to build the ack packet, based on the state of the negotiations. """ raise NotImplementedError def synReceived(self): """ Called when the peers syn packet has been received. Use this function to do any validation/verification. """ def ackReceived(self): """