public DataAMF3Message(RTMPMessage x) : base(x) { using (var reader = new AMF0Reader(new MemoryStream(x.Body))) { reader.BaseStream.ReadByte(); this.propertyName = (string)reader.ReadValue(); var arguments = new List <AMFValue>(); while (reader.BaseStream.Position < reader.BaseStream.Length) { arguments.Add(reader.ReadValue()); } this.arguments = arguments; } }
public void PushDataPacket(string name, AMF0Reader message) { if (PublisherId == 0) { Logger.FATAL("Data packet pushed on a publication {0} who is idle", PublisherId); return; } //var pos = message.BaseStream.Position; foreach (var listener in Listeners) { listener.Value.PushDataPacket(name, message); //message.BaseStream.Position = pos; } _publisher.OnDataPacket(this, name, message); }
public override void SendStream(Stream stream, int length) { var marker = stream.ReadByte() | 0xF0; var echoTime = marker == (Target == null ? 0xFE : 0xFD); stream.ReadUShort(); if (echoTime) { stream.ReadUShort(); } var type = stream.ReadByte(); if (type == 0x10) { var sizePos = stream.Position; var size = stream.ReadUShort(); var flags = stream.ReadByte(); var idFlow = stream.Read7BitLongValue(); var stage = stream.Read7BitLongValue(); if (idFlow == 2 && stage == 1) { var deltaNAck = stream.Read7BitLongValue(); var len = (ushort)stream.ReadByte(); stream.Position += len; stream.ReadByte(); stream.ReadByte(); //type stream.ReadUInt(); //timestamp var amfReader = new AMF0Reader(stream); var str = amfReader.ReadShortString(true); var num = amfReader.ReadAMFDouble(true); var pos = stream.Position; var connectionInfo = amfReader.ReadVariant(); connectionInfo["tcUrl"] = MiddleSession.QueryUrl; connectionInfo["app"] = MiddleSession.QueryUrl.Split('/').Last(); stream.Position = pos; var amfWriter = new AMF0Writer(stream); amfWriter.WriteObject(connectionInfo, true); length = (int)stream.Position; len = (ushort)(stream.Position - sizePos - 2); stream.Position = sizePos; stream.Write(len); } } stream.Position = 6; base.SendStream(stream, length); }
public CommandAMF0Message(RTMPMessage x) : base(x) { using (var reader = new AMF0Reader(new MemoryStream(x.Body))) { this.commandName = (string)reader.ReadValue(); this.transactionId = (int)reader.ReadValue(); this.commandObject = reader.ReadValue(); if (AMFValue.IsNull(CommandObject)) { this.commandObject = null; } var args = new List <AMFValue>(); while (reader.BaseStream.Position < reader.BaseStream.Length) { args.Add(reader.ReadValue()); } this.arguments = args; } }
public override void SendStream(Stream stream,int length) { var marker = stream.ReadByte() | 0xF0; var echoTime = marker == (Target == null ? 0xFE : 0xFD); stream.ReadUShort(); if (echoTime) stream.ReadUShort(); var type = stream.ReadByte(); if (type == 0x10) { var sizePos = stream.Position; var size = stream.ReadUShort(); var flags = stream.ReadByte(); var idFlow = stream.Read7BitLongValue(); var stage = stream.Read7BitLongValue(); if (idFlow == 2 && stage == 1) { var deltaNAck = stream.Read7BitLongValue(); var len = (ushort) stream.ReadByte(); stream.Position += len; stream.ReadByte(); stream.ReadByte();//type stream.ReadUInt();//timestamp var amfReader = new AMF0Reader(stream); var str = amfReader.ReadShortString(true); var num = amfReader.ReadAMFDouble(true); var pos = stream.Position; var connectionInfo = amfReader.ReadVariant(); connectionInfo["tcUrl"] = MiddleSession.QueryUrl; connectionInfo["app"] = MiddleSession.QueryUrl.Split('/').Last(); stream.Position = pos; var amfWriter = new AMF0Writer(stream); amfWriter.WriteObject(connectionInfo, true); length = (int) stream.Position; len = (ushort) (stream.Position - sizePos-2); stream.Position = sizePos; stream.Write(len); } } stream.Position = 6; base.SendStream(stream,length); }
private void HandlerMessage(Stream message, bool needDispose = true) { var type = message.ReadByte(); AMF0Reader amf = new AMF0Reader(message); switch (type) { case Defines.RM_HEADER_MESSAGETYPE_INVOKE: case Defines.RM_HEADER_MESSAGETYPE_FLEX: case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND: amf._ReadUInt32(); //skip timestamp goto default; case Defines.RM_HEADER_MESSAGETYPE_VIDEODATA: VideoHandler(message); break; case Defines.RM_HEADER_MESSAGETYPE_AUDIODATA: AudioHandler(message); break; case Defines.RM_HEADER_MESSAGETYPE_CHUNKSIZE: RawHandler(1, message); break; case Defines.RM_HEADER_MESSAGETYPE_USRCTRL: amf._ReadUInt32(); //skip timestamp var usrCtrlType = amf.ReadUInt16(); switch (usrCtrlType) { case 0x29: var keepAliveServer = amf.ReadUInt32(); var keepAlivePeer = amf.ReadUInt32(); Logger.Debug("keepAliveServer:{0},keepAlivePeer:{1}", keepAliveServer, keepAlivePeer); Band.KeepAliveServer = keepAliveServer; break; case 0x22: var syncID = amf.ReadUInt32(); var count = amf.ReadUInt32(); if (Band.FlowSynchronization.ContainsKey(syncID)) { if (Band.FlowSynchronization[syncID].Count + 1 == count) { foreach (var flow in Band.FlowSynchronization[syncID]) { flow.SyncDone(); } Band.FlowSynchronization[syncID].Clear(); } else { Band.FlowSynchronization[syncID].Add(this); IsWaitingSync = true; } } else { Band.FlowSynchronization[syncID] = new HashSet <Flow> { this }; IsWaitingSync = true; } //Logger.Debug("syncID:{0},count:{1}", syncID, count); break; } break; default: try { var messageBody = RtmpProtocolSerializer.Deserialize(type, amf); switch (type) { case Defines.RM_HEADER_MESSAGETYPE_INVOKE: case Defines.RM_HEADER_MESSAGETYPE_FLEX: string functionName = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_FUNCTION]; Writer.CallbackHandle = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_ID]; MessageHandler(functionName, messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS]); break; case Defines.RM_HEADER_MESSAGETYPE_NOTIFY: case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND: break; default: Logger.WARN("type:{0}\r\n{1}", type, messageBody.ToString()); break; } } catch (Exception) { //do nothing } break; } Writer.CallbackHandle = 0; if (needDispose) { message.Dispose(); } }
public override bool Initialize(int clientSideBufferLength) { if (!base.Initialize(clientSideBufferLength)) { FATAL("Unable to initialize stream"); return(false); } //2. Get stream capabilities StreamCapabilities pCapabilities = Capabilities; if (pCapabilities == null) { FATAL("Invalid stream capabilities"); return(false); } //3. Create the video builder switch (pCapabilities.VideoCodecId) { case VideoCodec.H264: _pVideoBuilder = new AVCBuilder(); break; case VideoCodec.PassThrough: _pVideoBuilder = new BaseBuilder(); break; case VideoCodec.Unknown: WARN("Invalid video stream capabilities:{0}", pCapabilities.VideoCodecId); break; default: FATAL("Invalid video stream capabilities:{0}", pCapabilities.VideoCodecId); return(false); } //4. Create the audio builder switch (pCapabilities.AudioCodecId) { case AudioCodec.Aac: _pAudioBuilder = new AACBuilder(); break; case AudioCodec.Mp3: _pAudioBuilder = new MP3Builder(); break; case AudioCodec.PassThrough: _pAudioBuilder = new BaseBuilder(); break; case AudioCodec.Unknown: WARN("Invalid audio stream capabilities: {0}", pCapabilities.AudioCodecId); break; default: FATAL("Invalid audio stream capabilities: {0}", pCapabilities.AudioCodecId); return(false); } _amf0Reader = new AMF0Reader(_pFile.DataStream); _pFile.Br = _amf0Reader; return(true); }
public void PushDataPacket(string name, AMF0Reader message) { if (PublisherId == 0) { Logger.FATAL("Data packet pushed on a publication {0} who is idle", PublisherId); return; } //var pos = message.BaseStream.Position; foreach (var listener in Listeners) { listener.Value.PushDataPacket(name,message); //message.BaseStream.Position = pos; } _publisher.OnDataPacket(this,name,message); }
public override bool Initialize(int clientSideBufferLength) { if (! base.Initialize(clientSideBufferLength)) { FATAL("Unable to initialize stream"); return false; } //2. Get stream capabilities StreamCapabilities pCapabilities = Capabilities; if (pCapabilities == null) { FATAL("Invalid stream capabilities"); return false; } //3. Create the video builder switch (pCapabilities.VideoCodecId) { case VideoCodec.H264: _pVideoBuilder = new AVCBuilder(); break; case VideoCodec.PassThrough: _pVideoBuilder = new BaseBuilder(); break; case VideoCodec.Unknown: WARN("Invalid video stream capabilities:{0}", pCapabilities.VideoCodecId); break; default: FATAL("Invalid video stream capabilities:{0}", pCapabilities.VideoCodecId); return false; } //4. Create the audio builder switch (pCapabilities.AudioCodecId) { case AudioCodec.Aac: _pAudioBuilder = new AACBuilder(); break; case AudioCodec.Mp3: _pAudioBuilder = new MP3Builder(); break; case AudioCodec.PassThrough: _pAudioBuilder = new BaseBuilder(); break; case AudioCodec.Unknown: WARN("Invalid audio stream capabilities: {0}", pCapabilities.AudioCodecId); break; default: FATAL("Invalid audio stream capabilities: {0}", pCapabilities.AudioCodecId); return false; } _amf0Reader = new AMF0Reader(_pFile.DataStream); _pFile.Br = _amf0Reader; return true; }
public virtual void SendStream(Stream stream, int len) { var marker = stream.ReadByte() | 0xF0; var echoTime = marker == (Target == null ? 0xFE : 0xFD); stream.ReadUShort(); if (echoTime) { stream.ReadUShort(); } var type = stream.ReadByte(); var size = stream.ReadUShort(); switch (type) { case 0x51: var idFlow = stream.Read7BitLongValue(); var bufferSize = stream.Read7BitLongValue(); var stageReaden = stream.Read7BitLongValue(); var tail = ""; while (stream.GetAvaliableByteCounts() > 0) { tail += " " + stream.Read7BitLongValue(); } Debug.WriteLine("from {1}:{0:X} ack {2} on flow {3} {4}", type, Target == null ? "server" : "client", stageReaden, idFlow, tail); break; case 0x10: var flags = stream.ReadByte(); idFlow = stream.Read7BitLongValue(); var stage = stream.Read7BitLongValue(); var deltaNAck = stream.Read7BitLongValue(); Debug.WriteLine("from {1}:{0:X} stage {2} deltaNAck {4} on flow {3}", type, Target == null ? "server" : "client", stage, idFlow, deltaNAck); if ((flags & FlowWriter.MESSAGE_HEADER) != 0) { var signturelen = stream.ReadByte(); stream.Position += signturelen; if (stream.ReadByte() > 0) { if (stream.ReadByte() != 0x0A) { Logger.WARN("Unknown fullduplex header part for the flow {0}", idFlow); } else { var assocFlowId = stream.Read7BitLongValue(); } var length = stream.ReadByte(); while (length > 0 && stream.GetAvaliableByteCounts() > 0) { Logger.WARN("Unknown message part on flow {0}", idFlow); stream.Position += length; length = stream.ReadByte(); } if (length > 0) { Logger.FATAL("Bad header message part, finished before scheduled"); } } var stype = stream.ReadByte();//type //var timestamp = stream.ReadUInt();//timestamp switch (stype) { case 0x08: case 0x09: break; case Defines.RM_HEADER_MESSAGETYPE_FLEX: stream.ReadByte(); goto case Defines.RM_HEADER_MESSAGETYPE_INVOKE; case Defines.RM_HEADER_MESSAGETYPE_INVOKE: var timestamp = stream.ReadUInt(); //timestamp var amfReader = new AMF0Reader(stream); var str = amfReader.ReadShortString(true); Logger.Debug("from {1}:{0:X} to {2:X} on flow {3}", type, Target == null ? "server" : "client", str, idFlow); break; default: Logger.Debug("from {1}:{0:X} to {2:X} on flow {3}", type, Target == null ? "server" : "client", stype, idFlow); break; } } break; default: Logger.Debug("from {1}:{0:X}", type, Target == null ? "server" : "client"); break; } stream.Position = 0; _outputBuffer.Position = 0; stream.CopyPartTo(_outputBuffer, len); RtmfpUtils.EncodeAndPack(AesEncrypt.Next(PrevAesType), Writer, FarId); EnqueueForOutbound(_outputBuffer); }
private void HandlerMessage(Stream message,bool needDispose = true) { var type = message.ReadByte(); AMF0Reader amf = new AMF0Reader(message); switch (type) { case Defines.RM_HEADER_MESSAGETYPE_INVOKE: case Defines.RM_HEADER_MESSAGETYPE_FLEX: case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND: amf._ReadUInt32();//skip timestamp goto default; case Defines.RM_HEADER_MESSAGETYPE_VIDEODATA: VideoHandler(message); break; case Defines.RM_HEADER_MESSAGETYPE_AUDIODATA: AudioHandler(message); break; case Defines.RM_HEADER_MESSAGETYPE_CHUNKSIZE: RawHandler(1, message); break; case Defines.RM_HEADER_MESSAGETYPE_USRCTRL: amf._ReadUInt32();//skip timestamp var usrCtrlType = amf.ReadUInt16(); switch (usrCtrlType) { case 0x29: var keepAliveServer = amf.ReadUInt32(); var keepAlivePeer = amf.ReadUInt32(); Logger.Debug("keepAliveServer:{0},keepAlivePeer:{1}", keepAliveServer, keepAlivePeer); Band.KeepAliveServer = keepAliveServer; break; case 0x22: var syncID = amf.ReadUInt32(); var count = amf.ReadUInt32(); if (Band.FlowSynchronization.ContainsKey(syncID)) { if (Band.FlowSynchronization[syncID].Count + 1 == count) { foreach (var flow in Band.FlowSynchronization[syncID]) flow.SyncDone(); Band.FlowSynchronization[syncID].Clear(); } else { Band.FlowSynchronization[syncID].Add(this); IsWaitingSync = true; } } else { Band.FlowSynchronization[syncID] = new HashSet<Flow> {this}; IsWaitingSync = true; } //Logger.Debug("syncID:{0},count:{1}", syncID, count); break; } break; default: try { var messageBody = RtmpProtocolSerializer.Deserialize(type, amf); switch (type) { case Defines.RM_HEADER_MESSAGETYPE_INVOKE: case Defines.RM_HEADER_MESSAGETYPE_FLEX: string functionName = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_FUNCTION]; Writer.CallbackHandle = messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_ID]; MessageHandler(functionName, messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS]); break; case Defines.RM_HEADER_MESSAGETYPE_NOTIFY: case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND: break; default: Logger.WARN("type:{0}\r\n{1}", type, messageBody.ToString()); break; } } catch (Exception) { //do nothing } break; } Writer.CallbackHandle = 0; if(needDispose) message.Dispose(); }
public bool OnMessage(string name, AMF0Reader message) { return(true); }
public Variant Deserialize(int msgType, AMF0Reader _amf0) { var messageBody = Variant.Get(); var stream = _amf0.BaseStream; //messageBody[Defines.RM_HEADER] = header.GetVariant(); switch (msgType) { case Defines.RM_HEADER_MESSAGETYPE_NOTIFY: messageBody[Defines.RM_NOTIFY, Defines.RM_NOTIFY_PARAMS] = Variant.Get(); while (_amf0.Available) messageBody[Defines.RM_NOTIFY, Defines.RM_NOTIFY_PARAMS].Add(_amf0.ReadVariant()); break; case Defines.RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND: messageBody[Defines.RM_FLEXSTREAMSEND, Defines.RM_FLEXSTREAMSEND_UNKNOWNBYTE] = stream.ReadByte(); messageBody[Defines.RM_FLEXSTREAMSEND, Defines.RM_FLEXSTREAMSEND_PARAMS] = Variant.Get(); while (_amf0.Available) messageBody[Defines.RM_FLEXSTREAMSEND, Defines.RM_FLEXSTREAMSEND_PARAMS].Add(_amf0.ReadVariant()); break; case Defines.RM_HEADER_MESSAGETYPE_FLEX: messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_IS_FLEX] = true; stream.ReadByte(); goto case Defines.RM_HEADER_MESSAGETYPE_INVOKE; case Defines.RM_HEADER_MESSAGETYPE_INVOKE: messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_FUNCTION] = _amf0.ReadShortString(true); messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_ID] = _amf0.ReadAMFDouble(true); messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS] = Variant.Get(); while (_amf0.Available) messageBody[Defines.RM_INVOKE, Defines.RM_INVOKE_PARAMS].Add(_amf0.ReadVariant()); break; case Defines.RM_HEADER_MESSAGETYPE_FLEXSHAREDOBJECT: if (stream.ReadByte() != 0) throw new NotSupportedException(); goto case Defines.RM_HEADER_MESSAGETYPE_SHAREDOBJECT; case Defines.RM_HEADER_MESSAGETYPE_SHAREDOBJECT: messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_NAME] = _amf0.ReadShortString(); messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_VERSION] = _amf0.ReadUInt32(); messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_PERSISTENCE] = _amf0.ReadUInt32()==2; stream.Position += 4; messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_PRIMITIVES] = Variant.Get(); while (_amf0.Available) { var primitive = Variant.Get(); primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_TYPE] = _amf0.ReadByte(); primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_STRTYPE] = GetSOPrimitiveString(primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_TYPE]); uint rawLength = 0; primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_RAWLENGTH] = rawLength = _amf0.ReadUInt32(); long read; switch ((byte)primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_TYPE]) { case Defines.SOT_CS_CONNECT: case Defines.SOT_CS_DISCONNECT: break; case Defines.SOT_CS_SET_ATTRIBUTE: read = 0; while (read < rawLength) { var afterRead = stream.Position; var key = _amf0.ReadShortString(); primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD, key] = _amf0.ReadVariant(); read += stream.Position - afterRead; } break; case Defines.SOT_CSC_DELETE_DATA: primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD] = _amf0.ReadShortString(); //read = 0; //while (read < rawLength) //{ // var afterRead = stream.Position; // var key = _amf0.ReadShortString(); // read += stream.Position - afterRead; // primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD].Add(key); //} break; case Defines.SOT_BW_SEND_MESSAGE: primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD] = Variant.Get(); while (_amf0.Available) primitive[Defines.RM_SHAREDOBJECTPRIMITIVE_PAYLOAD].Add(_amf0.ReadVariant()); break; default: Logger.FATAL("Invalid SO primitive type. Partial result:{0}",messageBody.ToString()); break; } messageBody[Defines.RM_SHAREDOBJECT, Defines.RM_SHAREDOBJECT_PRIMITIVES].Add(primitive); } break; case Defines.RM_HEADER_MESSAGETYPE_USRCTRL: messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE] = _amf0.ReadUInt16(); messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE_STRING] = GetUserCtrlTypeString(messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE]); switch ((ushort)messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_TYPE]) { case Defines.RM_USRCTRL_TYPE_STREAM_BEGIN: case Defines.RM_USRCTRL_TYPE_STREAM_EOF: case Defines.RM_USRCTRL_TYPE_STREAM_DRY: case Defines.RM_USRCTRL_TYPE_STREAM_IS_RECORDED: messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_STREAMID] = _amf0.ReadUInt32(); break; case Defines.RM_USRCTRL_TYPE_STREAM_SET_BUFFER_LENGTH: messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_STREAMID] = _amf0.ReadUInt32(); messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_BUFFLEN] = _amf0.ReadUInt32(); break; case Defines.RM_USRCTRL_TYPE_PING_REQUEST: messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_PING] = _amf0.ReadUInt32(); break; case Defines.RM_USRCTRL_TYPE_PING_RESPONSE: messageBody[Defines.RM_USRCTRL, Defines.RM_USRCTRL_PONG] = _amf0.ReadUInt32(); break; case Defines.RM_USRCTRL_TYPE_UNKNOWN1: case Defines.RM_USRCTRL_TYPE_UNKNOWN2: messageBody[Defines.RM_USRCTRL_UNKNOWN_U32] = _amf0.ReadUInt32(); break; default: throw new InvalidDataException("Invalid user control message:"+messageBody); } break; case Defines.RM_HEADER_MESSAGETYPE_CHUNKSIZE: messageBody[Defines.RM_CHUNKSIZE] = _amf0.ReadUInt32(); break; case Defines.RM_HEADER_MESSAGETYPE_ACK: messageBody[Defines.RM_ACK] = _amf0.ReadUInt32(); break; case Defines.RM_HEADER_MESSAGETYPE_WINACKSIZE: messageBody[Defines.RM_WINACKSIZE] = _amf0.ReadUInt32(); break; case Defines.RM_HEADER_MESSAGETYPE_PEERBW: messageBody[Defines.RM_PEERBW, Defines.RM_PEERBW_VALUE] = _amf0.ReadUInt32(); messageBody[Defines.RM_PEERBW, Defines.RM_PEERBW_TYPE] = stream.ReadByte(); break; case Defines.RM_HEADER_MESSAGETYPE_ABORTMESSAGE: messageBody[Defines.RM_ABORTMESSAGE] = _amf0.ReadUInt32(); break; case 0: break; default: Logger.FATAL("Invalid message type"); break; } return messageBody; }