예제 #1
0
파일: header.py 프로젝트: longde123/fmspy
    def write(self, previous=None):
        """
        Write (encoder) header to byte string.

        @param previous: previous header (used to compress header)
        @type previous: L{RTMPHeader}
        @return: encoded header
        @rtype: C{str}
        """
        if previous is None:
            diff = 3
        else:
            diff = self.diff(previous)

        first = self.object_id & 0x3f | ((diff ^ 3) << 6)

        if diff == 0:
            return chr(first)

        buf = BufferedByteStream()
        buf.write_uchar(first)

        buf.write_24bit_uint(self.timestamp)

        if diff > 1:
            buf.write_24bit_uint(self.length)
            buf.write_uchar(self.type)

            if diff > 2:
                buf.write_ulong(self.stream_id)

        buf.seek(0, 0)
        return buf.read()
예제 #2
0
    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()
예제 #3
0
    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()
예제 #4
0
 def test_read_short(self):
     for fixture in self.data:
         for l in xrange(len(fixture[0])-1):
             try:
                 RTMPHeader.read(BufferedByteStream(fixture[0][0:l]))
                 self.fail()
             except NeedBytes, (bytes,):
                 self.failUnlessEqual(len(fixture[0])-l if l != 0 else 1, bytes)
예제 #5
0
    def startStreaming(self):
        """
        This must be called before any RTMP data is received.
        """
        self.streamManager = self.buildStreamManager()
        self.controlStream = self.streamManager.getControlStream()

        self._decodingBuffer = BufferedByteStream()
        self._encodingBuffer = BufferedByteStream()

        self.decoder = codec.Decoder(self.getDispatcher(),
                                     self.streamManager,
                                     stream=self._decodingBuffer)
        self.encoder = codec.Encoder(self.getWriter(),
                                     stream=self._encodingBuffer)

        self.decoder_task = None
        self.encoder_task = None
예제 #6
0
파일: assembly.py 프로젝트: longde123/fmspy
    def disassemble(self):
        """
        Disassemble L{buffer} into packets.

        Returns first decoded packet or None, if no packet could
        be decoded at the moment.

        @return: decoded packet
        @rtype: L{Packet}
        """
        self.buffer.seek(0)

        while self.buffer.remaining() > 0:
            try:
                # try to parse header from stream
                header = RTMPHeader.read(self.buffer)
            except NeedBytes, (bytes, ):
                # not enough bytes, return what we've already parsed
                return None

            # fill header with extra data from previous headers received
            # with same object_id
            header.fill(self.lastHeaders.get(header.object_id, RTMPHeader()))

            # get buffer for data of this packet
            buf = self.pool.get(header.object_id, BufferedByteStream())

            # this chunk size is minimum of regular chunk size in this
            # disassembler and what we have left here
            thisChunk = min(header.length - len(buf), self.chunkSize)
            if self.buffer.remaining() < thisChunk:
                # we have not enough bytes to read this chunk of data
                return None

            # we got complete chunk
            buf.write(self.buffer.read(thisChunk))

            # store packet header for this object_id
            self.lastHeaders[header.object_id] = header

            # skip data left in input buffer
            self.buffer.consume()

            # this chunk completes full packet?
            if len(buf) < header.length:
                # no, store buffer for further chunks
                self.pool[header.object_id] = buf
            else:
                # parse packet from header and data
                buf.seek(0, 0)

                # delete stored data for this packet
                if header.object_id in self.pool:
                    del self.pool[header.object_id]

                return self._decode_packet(header, buf)
예제 #7
0
    def setUp(self):
        self.patch(codec, 'ChannelDemuxer', MockChannelDemuxer)

        self.dispatcher = DispatchTester(self)
        self.stream_factory = MockStreamFactory(self)
        self.decoder = codec.Decoder(self.dispatcher,
                                     self.stream_factory,
                                     stream=BufferedByteStream())

        self.expected_streams = None
        self.streams = {}
예제 #8
0
파일: assembly.py 프로젝트: longde123/fmspy
    def __init__(self, chunkSize):
        """
        Constructor.

        @param chunkSize: initial size of chunk
        @type chunkSize: C{int}
        """
        self.lastHeaders = {}
        self.pool = {}
        self.chunkSize = chunkSize
        self.buffer = BufferedByteStream()
예제 #9
0
파일: packets.py 프로젝트: longde123/fmspy
    def write(self):
        """
        Encode packet into bytes.

        @return: representation of packet
        @rtype: C{str}
        """
        buf = BufferedByteStream()
        buf.write_ulong(self.bytes)
        self.header.length = len(buf)
        buf.seek(0, 0)
        return buf.read()
예제 #10
0
    def dispatchMessage(self, stream, datatype, timestamp, data):
        """
        Called when the RTMP decoder has read a complete RTMP message.

        @param stream: The L{Stream} to receive this message.
        @param datatype: The RTMP datatype for the message.
        @param timestamp: The absolute timestamp this message was received.
        @param data: The raw data for the message.
        """
        m = message.classByType(datatype)()

        m.decode(BufferedByteStream(data))
        m.dispatch(stream, timestamp)
예제 #11
0
파일: base.py 프로젝트: longde123/fmspy
    def connectionMade(self):
        """
        Successfully connected to peer.
        """
        self.input = RTMPDisassembler(constants.DEFAULT_CHUNK_SIZE)
        self.output = RTMPAssembler(constants.DEFAULT_CHUNK_SIZE,
                                    self.transport)

        self.state = self.State.HANDSHAKE_SEND
        self.handshakeTimeout = reactor.callLater(
            config.getint('RTMP', 'handshakeTimeout'), self._handshakeTimedout)
        self.handshakeBuf = BufferedByteStream()
        self._beginHandshake()
예제 #12
0
    def dispatchMessage(self, stream, datatype, timestamp, data):
        p = Packet(self.type,
                   streamId=stream.streamId,
                   datatype=datatype,
                   timestamp=timestamp)

        self.observer.messageStart(p)

        e = message.classByType(datatype)()

        e.decode(BufferedByteStream(data))

        e.dispatch(stream, timestamp)

        self.observer.messageComplete(p)
예제 #13
0
class BytesReadTestCase(unittest.TestCase):
    """
    Test case for L{fmspy.rtmp.packets.BytesRead}.
    """

    data = [
        (
            {
                'header':
                RTMPHeader(object_id=2,
                           timestamp=0,
                           length=4,
                           type=0x03,
                           stream_id=0L),
                'buf':
                BufferedByteStream('\x00\x00\x00\x89'),
            },
            BytesRead(bytes=137,
                      header=RTMPHeader(object_id=2,
                                        timestamp=0,
                                        length=4,
                                        type=0x03,
                                        stream_id=0L)),
        ),
    ]

    def test_eq(self):
        self.failUnlessEqual(
            BytesRead(bytes=5, header=RTMPHeader(object_id=3)),
            BytesRead(bytes=5, header=RTMPHeader(object_id=3)))
        self.failIfEqual(BytesRead(bytes=5, header=RTMPHeader(object_id=4)),
                         BytesRead(bytes=5, header=RTMPHeader(object_id=3)))
        self.failIfEqual(BytesRead(bytes=6, header=RTMPHeader(object_id=3)),
                         BytesRead(bytes=5, header=RTMPHeader(object_id=3)))

    def test_read(self):
        for fixture in self.data:
            fixture[0]['buf'].seek(0)
            self.failUnlessEqual(fixture[1], BytesRead.read(**fixture[0]))

    def test_write(self):
        for fixture in self.data:
            fixture[0]['buf'].seek(0)
            self.failUnlessEqual(fixture[0]['buf'].read(), fixture[1].write())
예제 #14
0
    def pyamfEncode(self, obj, amf3=False, use_proxies=False):
        if amf3 is True:
            context = pyamf.get_context(pyamf.AMF3)
        else:
            context = pyamf.get_context(pyamf.AMF0)

        stream = BufferedByteStream()

        if amf3 is True:
            pyamf_encoder = pyamf.get_encoder(pyamf.AMF3,
                                              stream=stream,
                                              context=context)
        else:
            pyamf_encoder = pyamf.get_encoder(pyamf.AMF0,
                                              stream=stream,
                                              context=context)

        pyamf_encoder.writeElement(obj)
        return pyamf_encoder.stream.getvalue()
예제 #15
0
    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)
예제 #16
0
파일: util.py 프로젝트: sasqwatch/deblaze
 def setUp(self):
     self.context = pyamf.get_context(self.amf_version)
     self.stream = BufferedByteStream()
예제 #17
0
 def setUp(self):
     self.output = BufferedByteStream()
     self.encoder = codec.Encoder(self.output)
예제 #18
0
 def setUp(self):
     self.buffer = BufferedByteStream()
     self.listener = MockMessageListener()
예제 #19
0
    def _writePacket(self, packet, stream=None):
        stream = stream or BufferedByteStream()

        packet.encode(stream)

        self.transport.write(stream.getvalue())
예제 #20
0
 def test_read(self):
     for fixture in self.data:
         self.failUnlessEqual(fixture[1], RTMPHeader.read(BufferedByteStream(fixture[0])))
예제 #21
0
파일: util.py 프로젝트: vanzhiganov/rtmpy
 def __init__(self, deferred):
     self.deferred = deferred
     self.s = BufferedByteStream()
예제 #22
0
class PingTestCase(unittest.TestCase):
    """
    Test case for L{fmspy.rtmp.packets.Ping}.
    """

    data = [
        (
            {
                'header':
                RTMPHeader(object_id=2,
                           timestamp=0,
                           length=6,
                           type=0x04,
                           stream_id=0L),
                'buf':
                BufferedByteStream('\x00\x06\x00\x00\x00\x89'),
            },
            Ping(event=6,
                 data=[137],
                 header=RTMPHeader(object_id=2,
                                   timestamp=0,
                                   length=6,
                                   type=0x04,
                                   stream_id=0L)),
        ),
        (
            {
                'header':
                RTMPHeader(object_id=2,
                           timestamp=0,
                           length=10,
                           type=0x04,
                           stream_id=0L),
                'buf':
                BufferedByteStream('\x00\x06\x00\x00\x00\x89\x00\x00\x00\x0e'),
            },
            Ping(event=6,
                 data=[137, 14],
                 header=RTMPHeader(object_id=2,
                                   timestamp=0,
                                   length=10,
                                   type=0x04,
                                   stream_id=0L)),
        ),
        (
            {
                'header':
                RTMPHeader(object_id=2,
                           timestamp=0,
                           length=14,
                           type=0x04,
                           stream_id=0L),
                'buf':
                BufferedByteStream(
                    '\x00\x06\x00\x00\x00\x89\x00\x00\x00\x0e\x00\x00\x03y'),
            },
            Ping(event=6,
                 data=[137, 14, 889],
                 header=RTMPHeader(object_id=2,
                                   timestamp=0,
                                   length=14,
                                   type=0x04,
                                   stream_id=0L)),
        ),
    ]

    def test_eq(self):
        self.failUnlessEqual(
            Ping(event=5, data=[3], header=RTMPHeader(object_id=3)),
            Ping(event=5, data=[3], header=RTMPHeader(object_id=3)))
        self.failIfEqual(
            Ping(event=5, data=[3], header=RTMPHeader(object_id=3)),
            Ping(event=5, data=[3], header=RTMPHeader(object_id=4)))
        self.failIfEqual(
            Ping(event=5, data=[3], header=RTMPHeader(object_id=3)),
            Ping(event=5, data=[3, 4], header=RTMPHeader(object_id=3)))
        self.failIfEqual(
            Ping(event=5, data=[3], header=RTMPHeader(object_id=3)),
            Ping(event=6, data=[3], header=RTMPHeader(object_id=3)))

    def test_read(self):
        for fixture in self.data:
            fixture[0]['buf'].seek(0)
            self.failUnlessEqual(fixture[1], Ping.read(**fixture[0]))

    def test_write(self):
        for fixture in self.data:
            fixture[0]['buf'].seek(0)
            self.failUnlessEqual(fixture[0]['buf'].read(), fixture[1].write())
예제 #23
0
class InvokeTestCase(unittest.TestCase):
    """
    Test case for L{fmspy.rtmp.packets.Invoke}.
    """

    data = [
        ({
            'header':
            RTMPHeader(object_id=3,
                       timestamp=0,
                       length=235,
                       type=0x14,
                       stream_id=0L),
            'buf':
            BufferedByteStream(
                '\x02\x00\x07connect\x00?\xf0\x00\x00\x00\x00\x00\x00\x03\x00\x03app\x02\x00\x04echo\x00\x08flashVer\x02\x00\rLNX 10,0,20,7\x00\x06swfUrl\x06\x00\x05tcUrl\x02\x00\x15rtmp://localhost/echo\x00\x04fpad\x01\x00\x00\x0ccapabilities\x00@.\x00\x00\x00\x00\x00\x00\x00\x0baudioCodecs\x00@\xa8\xee\x00\x00\x00\x00\x00\x00\x0bvideoCodecs\x00@o\x80\x00\x00\x00\x00\x00\x00\rvideoFunction\x00?\xf0\x00\x00\x00\x00\x00\x00\x00\x07pageUrl\x06\x00\x0eobjectEncoding\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t'
            ),
        },
         Invoke(name=u'connect',
                argv=({
                    'videoCodecs': 252,
                    'audioCodecs': 3191,
                    'flashVer': u'LNX 10,0,20,7',
                    'app': u'echo',
                    'tcUrl': u'rtmp://localhost/echo',
                    'videoFunction': 1,
                    'capabilities': 15,
                    'pageUrl': pyamf.Undefined,
                    'fpad': False,
                    'swfUrl': pyamf.Undefined,
                    'objectEncoding': 0
                }, ),
                id=1,
                header=RTMPHeader(object_id=3,
                                  timestamp=0,
                                  length=235,
                                  type=0x14,
                                  stream_id=0L)), False),
        ({
            'header':
            RTMPHeader(object_id=3,
                       timestamp=0,
                       length=0,
                       type=0x14,
                       stream_id=0L),
            'buf':
            BufferedByteStream(
                '\x02\x00\x07destroy\x00@@\x80\x00\x00\x00\x00\x00\x03\x00\x0bvideoCodecs\x00@o\x80\x00\x00\x00\x00\x00\x00\x00\t'
            ),
        },
         Invoke(name=u'destroy',
                argv=({
                    'videoCodecs': 252
                }, ),
                id=33,
                header=RTMPHeader(object_id=3,
                                  timestamp=0,
                                  length=0,
                                  type=0x14,
                                  stream_id=0L)), True),
    ]

    def test_eq(self):
        self.failUnlessEqual(
            Invoke(name='a', argv=(), id=35.0, header=RTMPHeader(object_id=3)),
            Invoke(name='a', argv=(), id=35.0, header=RTMPHeader(object_id=3)))
        self.failIfEqual(
            Invoke(name='a', argv=(), id=35.0, header=RTMPHeader(object_id=3)),
            Invoke(name='b', argv=(), id=35.0, header=RTMPHeader(object_id=3)))
        self.failIfEqual(
            Invoke(name='a', argv=(), id=35.0, header=RTMPHeader(object_id=3)),
            Invoke(name='a',
                   argv=('a'),
                   id=35.0,
                   header=RTMPHeader(object_id=3)))
        self.failIfEqual(
            Invoke(name='a', argv=(), id=35.0, header=RTMPHeader(object_id=3)),
            Invoke(name='a', argv=(), id=36.0, header=RTMPHeader(object_id=3)))
        self.failIfEqual(
            Invoke(name='a', argv=(), id=35.0, header=RTMPHeader(object_id=3)),
            Invoke(name='a', argv=(), id=35.0, header=RTMPHeader(object_id=4)))

    def test_repr(self):
        self.failUnlessEqual(
            "<Invoke(name=u'destroy', argv=({'videoCodecs': 252},), id=33, header=<RTMPHeader(object_id=3, timestamp=0, length=0, type=0x14, stream_id=0L)>)>",
            repr(
                Invoke(name=u'destroy',
                       argv=({
                           'videoCodecs': 252
                       }, ),
                       id=33,
                       header=RTMPHeader(object_id=3,
                                         timestamp=0,
                                         length=0,
                                         type=0x14,
                                         stream_id=0L))))

    def test_read(self):
        for fixture in self.data:
            fixture[0]['buf'].seek(0)
            self.failUnlessEqual(fixture[1], Invoke.read(**fixture[0]))

    def test_write(self):
        for fixture in self.data:
            if not fixture[2]:
                continue
            fixture[0]['buf'].seek(0)
            self.failUnlessEqual(fixture[0]['buf'].read(), fixture[1].write())
예제 #24
0
 def startVersioning(self):
     """
     Start protocol version negotiations.
     """
     self.buffer = BufferedByteStream()
예제 #25
0
    def __init__(self, channelId, stream, frameSize):
        BaseChannel.__init__(self, channelId, stream, frameSize)

        self.buffer = BufferedByteStream()
        self.acquired = False
        self.callback = None
예제 #26
0
    def __init__(self, stream=None):
        self.stream = stream or BufferedByteStream()

        self.channels = {}
        self.frameSize = FRAME_SIZE
        self.bytes = 0