在接收到客戶端發送的34bytes 再去掉12bytes的頭剩下22bytes Deserialize來解碼 [cpp] <span style="font-size:18px;">switch (H_MT(header)) { ... case RM_HEADER_MESSAGETYPE_FLEX: { message[RM_INVOKE][RM_INVOKE_IS_FLEX] = (bool)(H_MT(header) == RM_HEADER_MESSAGETYPE_FLEX); return DeserializeInvoke(buffer, message[RM_INVOKE]); } }</span> [cpp] <span style="font-size:18px;">bool RTMPProtocolSerializer::DeserializeInvoke(IOBuffer &buffer, Variant &message) { if (message[RM_INVOKE_IS_FLEX]) { if (!buffer.Ignore(1)) { FATAL("Unable to ignore 1 byte"); return false; } } if (!_amf0.ReadShortString(buffer, message[RM_INVOKE_FUNCTION])) { FATAL("Unable to read %s", STR(RM_INVOKE_FUNCTION)); return false; } if (!_amf0.ReadDouble(buffer, message[RM_INVOKE_ID])) { FATAL("Unable to read %s", STR(RM_INVOKE_ID)); return false; } for (uint32_t i = 0; GETAVAILABLEBYTESCOUNT(buffer) > 0; i++) { if (!_amf0.Read(buffer, message[RM_INVOKE_PARAMS][i])) { FATAL("Unable to de-serialize invoke parameter %u", i); return false; } } return true; }</span> 完全的數據在這裡被消耗了 在 [cpp] <span style="font-size:18px;">bool BaseRTMPAppProtocolHandler::InboundMessageAvailable(BaseRTMPProtocol *pFrom, Variant &request) { switch ((uint8_t) VH_MT(request)) { case RM_HEADER_MESSAGETYPE_FLEX: { return ProcessInvoke(pFrom, request); } } } </span> 中進行處理 [cpp] <span style="font-size:18px;">bool BaseRTMPAppProtocolHandler::ProcessInvoke(BaseRTMPProtocol *pFrom, Variant &request) { ... else if (functionName == RM_INVOKE_FUNCTION_PLAY) { return ProcessInvokePlay(pFrom, request); }</span> 這裡多N多事情 [cpp] <span style="font-size:18px;">bool BaseRTMPAppProtocolHandler::ProcessInvokePlay(BaseRTMPProtocol *pFrom, Variant & request) { ...在這裡生成meta文件,生成seek文件 }</span> 然後最核心的是這裡 [cpp] www.2cto.com <span style="font-size:18px;">void BaseOutNetRTMPStream::SignalAttachedToInStream() { //1. Store the attached stream type to know how we should proceed on detach ... //2. Mirror the feeder chunk size ... //3. Fix the time base ... //4. Store the metadata ... //5. Send abort messages on audio/video channels ... //6. Stream is recorded ... //7. Stream begin ... if (_sendOnStatusPlayMessages) { //8. Send NetStream.Play.Reset ... //9. NetStream.Play.Start ... //10. notify |RtmpSampleAccess ... } //11. notify onStatus code="NetStream.Data.Start" ... //12. notify onMetaData ... }</span> [cpp] <span style="font-size:18px;">bool BaseInStream::Play(double absoluteTimestamp, double length) { if (!SignalPlay(absoluteTimestamp, length)) { FATAL("Unable to signal play"); return false; } LinkedListNode<BaseOutStream *> *pTemp = _pOutStreams; while (pTemp != NULL) { if (!pTemp->info->SignalPlay(absoluteTimestamp, length)) { WARN("Unable to signal play on an outbound stream"); } pTemp = pTemp->pPrev; } return true; }</span>