示例#1
0
文件: Rtmp.py 项目: slyseal/slyseal
    def readPacket(self, header, input):
        channel = self.channels.get(header[0])
        if channel is None:
            header_size = header[2]
            if header_size < self.read_chunk_size:
                return self.processBody(header, input.read(header_size))
            buffer = BytesOutput(True)
            buffer.write(input.read(self.read_chunk_size))
            self.channels[header[0]] = [
                header, buffer, header_size - self.read_chunk_size
            ]
        else:
            channel_header = channel[0]
            if header[1] != channel_header[1]:
                raise Exception, "Timestamp Changed"
            if header[4] != channel_header[4]:
                raise Exception, "Stream Id Changed"
            if header[3] != channel_header[3]:
                raise Exception, "Type Changed"
            if header[2] != channel_header[2]:
                raise Exception, "Size Changed"
            if channel[2] > self.read_chunk_size:
                channel[1].write(input.read(self.read_chunk_size))
                channel[2] -= self.read_chunk_size
            else:
                channel[1].write(input.read(channel[2]))
                del self.channels[header[0]]
                return self.processBody(channel[0], channel[1].getBytes())

        return None
示例#2
0
 def sendNetStreamDataStart(self, stream, stream_id=None):
     output = BytesOutput(True)
     Amf.write(output, Amf.encode("onStatus"))
     Amf.write(output, Amf.encode({"code": "NetStream.Data.Start"}))
     self.writeMessage(
         self.rtmp.make(5, (Rtmp.RTMP_TYPE_NOTIFY, output.getBytes()), 0,
                        stream_id))
示例#3
0
 def sendRtmpSampleAccess(self, stream, stream_id=None):
     output = BytesOutput(True)
     Amf.write(output, Amf.encode("|RtmpSampleAccess"))
     Amf.write(output, Amf.encode(False))
     Amf.write(output, Amf.encode(False))
     self.writeMessage(
         self.rtmp.make(5, (Rtmp.RTMP_TYPE_NOTIFY, output.getBytes()), 0,
                        stream_id))
示例#4
0
文件: Stream.py 项目: slyseal/slyseal
    def getFrame(self):
        try:
            time, type, offset, size, keyframe, composition_time = self.info.frames[
                self.index]
        except:
            return None

        output = BytesOutput(True)

        first = False
        if (type == FRAME_TYPE_VIDEO):
            if (self.video_count == 0):
                first = True
            rtmp_type = Rtmp.RTMP_TYPE_VIDEO
            self.video_count += 1
        elif (type == FRAME_TYPE_AUDIO):
            if (self.audio_count < 2):
                first = True
            rtmp_type = Rtmp.RTMP_TYPE_AUDIO
            self.audio_count += 1

        stream_id = None

        if first:
            output.write(self.getDescription(type, (time == 0)))
            stream_id = self.id

        data = BytesOutput(True)
        data.write(self.getFrameHeader(type, keyframe, False,
                                       composition_time))

        self.file.seek(offset, 0)
        data.write(self.file.read(size))

        timestamp = time - self.base_time

        output.write(
            self.rtmp.make(self.channel, (rtmp_type, data.getBytes()),
                           timestamp, stream_id))

        self.index += 1
        self.base_time = time

        return (time, output.getBytes())
示例#5
0
文件: Stream.py 项目: slyseal/slyseal
    def getFrameHeader(self, type, keyframe, description=False, ref_time=0):
        output = BytesOutput(True)

        if type == FRAME_TYPE_VIDEO:
            output.writeByte((0x27, 0x17)[keyframe])
            output.writeByte((0x01, 0x00)[description])
            output.writeInt24(ref_time)
        elif type == FRAME_TYPE_AUDIO:
            output.writeByte(0xAF)
            output.writeByte((0x01, 0x00)[description])

        return output.getBytes()
示例#6
0
 def sendMetaData(self, stream, stream_id=None):
     #self.writeMessage(self.rtmp.make(stream.channel_id, (Rtmp.RTMP_TYPE_COMMAND, ("onMetaData", 0, [
     #	Amf.encode(None),
     #	Amf.encode(stream.stream.getMetadata())
     #])), 0, stream_id))
     output = BytesOutput(True)
     Amf.write(output, Amf.encode("onMetaData"))
     Amf.write(output, Amf.encode(stream.stream.getMetadata()))
     self.writeMessage(
         self.rtmp.make(stream.channel_id,
                        (Rtmp.RTMP_TYPE_NOTIFY, output.getBytes()), 0,
                        stream_id))
示例#7
0
def makeHandshakeResponse(handshake):
    flash_plugin_version = unpack(">I", handshake[4:8])[0]
    #scheme = SCHEMES.get(flash_plugin_version, 0)
    scheme = validateClient(handshake)
    print "scheme", scheme

    handshake = prepareHandshake(handshake, scheme)

    output = BytesOutput(True)
    output.writeByte(0x03)
    output.write(makeHandshakePart1(handshake, scheme))
    output.write(makeHandshakePart2(handshake, scheme))
    return output.getBytes()
示例#8
0
文件: Stream.py 项目: slyseal/slyseal
    def getDescription(self, type, first_time=False):
        data = BytesOutput(True)

        data.write(self.getFrameHeader(type, True, True))

        if type == FRAME_TYPE_VIDEO:
            data.write(self.info.descriptions[0])
            return self.rtmp.make(self.channel,
                                  (Rtmp.RTMP_TYPE_VIDEO, data.getBytes()), 0,
                                  (None, self.id)[first_time])
        elif type == FRAME_TYPE_AUDIO:
            data.write(self.info.descriptions[1])
            return self.rtmp.make(self.channel,
                                  (Rtmp.RTMP_TYPE_AUDIO, data.getBytes()), 0,
                                  (None, self.id)[first_time])
        else:
            return None
示例#9
0
文件: Stream.py 项目: slyseal/slyseal
    def getVideoFrame(self, index, ref_time):
        try:
            time, type, offset, size, keyframe, composition_time = self.info.frames[
                index]
        except:
            return None
        if type != FRAME_TYPE_VIDEO:
            return None

        data = BytesOutput(True)
        data.write(
            self.getFrameHeader(type, keyframe, False,
                                (time - ref_time) + composition_time))

        self.file.seek(offset, 0)
        data.write(self.file.read(size))

        self.video_count += 1
        return self.rtmp.make(self.channel,
                              (Rtmp.RTMP_TYPE_VIDEO, data.getBytes()), 0, None)
示例#10
0
文件: Rtmp.py 项目: slyseal/slyseal
    def makeHeader(self, header):
        output = BytesOutput(True)

        header_size = 1
        if header[4] is not None:
            header_size = 12
        elif header[3] is not None:
            header_size = 8
        elif header[1] is not None:
            header_size = 4

        output.writeByte(header[0] | (headerSizeToByte(header_size) << 6))

        if header_size >= 4:
            output.writeUInt24(header[1])
        if header_size >= 8:
            output.writeUInt24(header[2])
            output.writeByte(header[3])
        if (header_size >= 12):
            output.setEndianess(False)
            output.writeUInt(header[4])
            output.setEndianess(True)

        return output.getBytes()
示例#11
0
文件: Rtmp.py 项目: slyseal/slyseal
    def make(self, channel_id, packet, timestamp=0, stream_id=0):
        type = packet[0]
        header = [channel_id, timestamp, None, type, stream_id]

        data = BytesOutput(True)

        # 0x01 - Chunk Size
        if type == RTMP_TYPE_CHUNK_SIZE:
            data.writeUInt(packet[1])

        # 0x03 - Bytes Read
        elif type == RTMP_TYPE_BYTES_READ:
            data.writeUInt(packet[1])

        # 0x04 - Control
        elif type == RTMP_TYPE_CONTROL:
            control_stream_id, control = packet[1]
            control_type = control[0]
            value1 = None
            value2 = None

            # 0x00 - Clear
            if control_type == RTMP_CONTROL_CLEAR:
                pass

            # 0x01 - Clear Play
            elif control_type == RTMP_CONTROL_CLEAR_PLAY:
                pass

            # 0x03 - Client Buffer
            elif control_type == RTMP_CONTROL_CLIENT_BUFFER:
                value1 = control[1]

            # 0x04 - Reset
            elif control_type == RTMP_CONTROL_RESET:
                pass

            # 0x06 - Ping
            elif control_type == RTMP_CONTROL_PING:
                value1 = control[1]

            # 0x07 - Pong
            elif control_type == RTMP_CONTROL_PONG:
                value1 = control[1]

            # Unknown
            elif control_type == RTMP_CONTROL_UNKNOWN:
                control_type = control[1]
                value1 = control[2]
                value2 = control[3]

            data.writeUInt16(control_type)
            data.writeUInt(control_stream_id)

            if value1 is not None:
                data.writeUInt(value1)
            if value2 is not None:
                data.writeUInt(value2)

        # 0x05 - Server BW
        elif type == RTMP_TYPE_SERVER_BW:
            data.writeUInt(0x002625A0)

        # 0x06 - Client BW
        elif type == RTMP_TYPE_CLIENT_BW:
            data.writeUInt(0x002625A0)
            data.writeByte(0x02)

        # 0x08 - Audio
        elif type == RTMP_TYPE_AUDIO:
            data.write(packet[1])

        # 0x09 - Video
        elif type == RTMP_TYPE_VIDEO:
            data.write(packet[1])

        # 0x12 - Notify
        elif type == RTMP_TYPE_NOTIFY:
            data.writeString(packet[1])

        # 0x13 - Shared
        elif type == RTMP_TYPE_SHARED:
            raise Exception, "Not implemented"  #TODO -> Shared Object functions

        # 0x14 - Command
        elif type == RTMP_TYPE_COMMAND:
            name, id, args = packet[1]
            Amf.write(data, (3, name))  #Command name
            Amf.write(data, (1, id))  #Command id
            for arg in args:  # Args (Amf Values)
                Amf.write(data, arg)

        # Unknown
        elif type == RTMP_TYPE_UNKNOWN:
            type, body = packet[1]
            header[4] = type
            data.write(body)

        # Other
        else:
            header[4] = None

        data = data.getBytes()
        length = len(data)
        header[2] = length

        output = BytesOutput(True)

        output.write(self.makeHeader(header))
        if length > 0:
            pos = self.write_chunk_size
            if length <= pos:
                output.write(data)
            else:
                output.write(buffer(data, 0, pos))
                length -= pos
                while length > 0:
                    output.writeByte(header[0] | (headerSizeToByte(1) << 6))
                    n = (length,
                         self.write_chunk_size)[length > self.write_chunk_size]
                    output.write(buffer(data, pos, n))
                    pos += n
                    length -= n

        return output.getBytes()