Пример #1
0
    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 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
			
		
Пример #3
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()
Пример #4
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()
Пример #5
0
	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)
Пример #6
0
    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)
Пример #7
0
    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())
Пример #8
0
	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
	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())
Пример #10
0
    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
Пример #11
0
    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()
Пример #12
0
	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()