bool Init(CTSTR lpFile) { strFile = lpFile; initialTimestamp = -1; if(!fileOut.Open(lpFile, XFILE_CREATEALWAYS, 1024*1024)) return false; fileOut.OutputByte('F'); fileOut.OutputByte('L'); fileOut.OutputByte('V'); fileOut.OutputByte(1); fileOut.OutputByte(5); //bit 0 = (hasAudio), bit 2 = (hasAudio) fileOut.OutputDword(DWORD_BE(9)); fileOut.OutputDword(0); metaDataPos = fileOut.GetPos(); char metaDataBuffer[2048]; char *enc = metaDataBuffer; char *pend = metaDataBuffer+sizeof(metaDataBuffer); enc = AMF_EncodeString(enc, pend, &av_onMetaData); char *endMetaData = App->EncMetaData(enc, pend, true); UINT metaDataSize = endMetaData-metaDataBuffer; AppendFLVPacket((LPBYTE)metaDataBuffer, metaDataSize, 18, 0); return true; }
int SendPlayStop(RTMP *r) { RTMPPacket packet; char pbuf[512], *pend = pbuf+sizeof(pbuf); packet.m_nChannel = 0x03; // control channel (invoke) packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM; packet.m_packetType = RTMP_PACKET_TYPE_INVOKE; packet.m_nTimeStamp = 0; packet.m_nInfoField2 = 0; packet.m_hasAbsTimestamp = 0; packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE; char *enc = packet.m_body; enc = AMF_EncodeString(enc, pend, &av_onStatus); enc = AMF_EncodeNumber(enc, pend, 0); *enc++ = AMF_NULL; *enc++ = AMF_OBJECT; enc = AMF_EncodeNamedString(enc, pend, &av_level, &av_status); enc = AMF_EncodeNamedString(enc, pend, &av_code, &av_NetStream_Play_Stop); enc = AMF_EncodeNamedString(enc, pend, &av_description, &av_Stopped_playing); enc = AMF_EncodeNamedString(enc, pend, &av_details, &r->Link.playpath); enc = AMF_EncodeNamedString(enc, pend, &av_clientid, &av_clientid); *enc++ = 0; *enc++ = 0; *enc++ = AMF_OBJECT_END; packet.m_nBodySize = enc - packet.m_body; return RTMP_SendPacket(r, &packet, FALSE); }
static int SendConnectResult(RTMP *r, double txn) { RTMPPacket packet; char pbuf[384], *pend = pbuf+sizeof(pbuf); AMFObject obj; AMFObjectProperty p, op; AVal av; packet.m_nChannel = 0x03; // control channel (invoke) packet.m_headerType = 1; /* RTMP_PACKET_SIZE_MEDIUM; */ packet.m_packetType = 0x14; // INVOKE packet.m_nTimeStamp = 0; packet.m_nInfoField2 = 0; packet.m_hasAbsTimestamp = 0; packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE; char *enc = packet.m_body; enc = AMF_EncodeString(enc, pend, &av__result); enc = AMF_EncodeNumber(enc, pend, txn); *enc++ = AMF_OBJECT; STR2AVAL(av, "FMS/3,5,1,525"); enc = AMF_EncodeNamedString(enc, pend, &av_fmsVer, &av); enc = AMF_EncodeNamedNumber(enc, pend, &av_capabilities, 31.0); enc = AMF_EncodeNamedNumber(enc, pend, &av_mode, 1.0); *enc++ = 0; *enc++ = 0; *enc++ = AMF_OBJECT_END; *enc++ = AMF_OBJECT; STR2AVAL(av, "status"); enc = AMF_EncodeNamedString(enc, pend, &av_level, &av); STR2AVAL(av, "NetConnection.Connect.Success"); enc = AMF_EncodeNamedString(enc, pend, &av_code, &av); STR2AVAL(av, "Connection succeeded."); enc = AMF_EncodeNamedString(enc, pend, &av_description, &av); enc = AMF_EncodeNamedNumber(enc, pend, &av_objectEncoding, r->m_fEncoding); #if 0 STR2AVAL(av, "58656322c972d6cdf2d776167575045f8484ea888e31c086f7b5ffbd0baec55ce442c2fb"); enc = AMF_EncodeNamedString(enc, pend, &av_secureToken, &av); #endif STR2AVAL(p.p_name, "version"); STR2AVAL(p.p_vu.p_aval, "3,5,1,525"); p.p_type = AMF_STRING; obj.o_num = 1; obj.o_props = &p; op.p_type = AMF_OBJECT; STR2AVAL(op.p_name, "data"); op.p_vu.p_object = obj; enc = AMFProp_Encode(&op, enc, pend); *enc++ = 0; *enc++ = 0; *enc++ = AMF_OBJECT_END; packet.m_nBodySize = enc - packet.m_body; return RTMP_SendPacket(r, &packet, FALSE); }
static char* amf_encode_string(char* out, char* outend, const char* s) { AVal v; v.av_len = strlen(s); v.av_val = (char*)s; return AMF_EncodeString(out, outend, &v); }
int RequestData(RTMP *r, YLENGStream *yle) { RTMPPacket packet; char pbuf[128], *pend = pbuf+sizeof(pbuf); AVal clipID; packet.m_nChannel = 0x03; // control channel packet.m_headerType = RTMP_PACKET_SIZE_LARGE; packet.m_packetType = 0x11; // FLEX MESSAGE packet.m_nTimeStamp = RTMP_GetTime(); packet.m_nInfoField2 = 0; packet.m_hasAbsTimestamp = 0; packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE; char *enc = packet.m_body; *enc++ = 0x00; // Unknown enc = AMF_EncodeString(enc, pend, &av_requestData); enc = AMF_EncodeNumber(enc, pend, 0); *enc++ = AMF_NULL; enc = AMF_EncodeString(enc, pend, &av_e0); if ((r->Link.lFlags & RTMP_LF_LIVE) != 0) { char *tmp = malloc(yle->clipID.av_len+12); strcpy(tmp, "streams/fi/"); strncat(tmp, yle->clipID.av_val, yle->clipID.av_len); STR2AVAL(clipID, tmp); enc = AMF_EncodeString(enc, pend, &clipID); free(tmp); } else { char *tmp = malloc(yle->clipID.av_len+2); strcpy(tmp, "/"); strncat(tmp, yle->clipID.av_val, yle->clipID.av_len); STR2AVAL(clipID, tmp); enc = AMF_EncodeString(enc, pend, &clipID); free(tmp); } if (!enc) { RTMP_Log(RTMP_LOGERROR, "Buffer too short in RequestData"); return FALSE; } packet.m_nBodySize = enc-packet.m_body; return RTMP_SendPacket(r, &packet, FALSE); }
char * amf::AMF_EncodeNamedString(char *output, char *outend, const AVal * strName, const AVal * strValue) { if (output+2+strName->av_len > outend) return NULL; output = AMF_EncodeInt16(output, outend, strName->av_len); memcpy(output, strName->av_val, strName->av_len); output += strName->av_len; return AMF_EncodeString(output, outend, strValue); }
int ExecuteAuthenticationDetails(RTMP *r, AMFObject *proplist, YLENGStream *yle) { long authResult = -1; int i; for (i=0; i<AMF_CountProp(proplist); i++) { AVal name; AMFObjectProperty *prop = AMF_GetProp(proplist, NULL, i); AMFProp_GetName(prop, &name); if (AVMATCH(&name, &av_locatedInBroadcastTerritory)) { yle->locatedInBroadcastTerritory = AMFProp_GetBoolean(prop); } else if (AVMATCH(&name, &av_randomAuth)) { authResult = ((long)AMFProp_GetNumber(prop) + 447537687) % 6834253; } else if (AVMATCH(&name, &av_tvFeeActivated)) { yle->tvFeeActivated = AMFProp_GetBoolean(prop); } } if (authResult != -1) { RTMPPacket packet; char pbuf[128], *pend = pbuf+sizeof(pbuf); packet.m_nChannel = 0x03; // control channel packet.m_headerType = RTMP_PACKET_SIZE_LARGE; packet.m_packetType = 0x11; // FLEX MESSAGE packet.m_nTimeStamp = RTMP_GetTime(); packet.m_nInfoField2 = 0; packet.m_hasAbsTimestamp = 0; packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE; char *enc = packet.m_body; *enc++ = 0x00; // Unknown enc = AMF_EncodeString(enc, pend, &av_authenticateRandomNumber); enc = AMF_EncodeNumber(enc, pend, 0); *enc++ = AMF_NULL; enc = AMF_EncodeNumber(enc, pend, (double)authResult); packet.m_nBodySize = enc-packet.m_body; RTMP_Log(RTMP_LOGDEBUG, "sending authenticateRandomNumber"); return RTMP_SendPacket(r, &packet, FALSE); } return FALSE; }
int SendResultNumber(RTMP *r, double txn, double ID) { RTMPPacket packet; char pbuf[256], *pend = pbuf+sizeof(pbuf); packet.m_nChannel = 0x03; // control channel (invoke) packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM; packet.m_packetType = RTMP_PACKET_TYPE_INVOKE; packet.m_nTimeStamp = 0; packet.m_nInfoField2 = 0; packet.m_hasAbsTimestamp = 0; packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE; char *enc = packet.m_body; enc = AMF_EncodeString(enc, pend, &av__result); enc = AMF_EncodeNumber(enc, pend, txn); *enc++ = AMF_NULL; enc = AMF_EncodeNumber(enc, pend, ID); packet.m_nBodySize = enc - packet.m_body; return RTMP_SendPacket(r, &packet, FALSE); }
void RTMPPublisher::BeginPublishingInternal() { RTMPPacket packet; char pbuf[2048], *pend = pbuf+sizeof(pbuf); packet.m_nChannel = 0x03; // control channel (invoke) packet.m_headerType = RTMP_PACKET_SIZE_LARGE; packet.m_packetType = RTMP_PACKET_TYPE_INFO; packet.m_nTimeStamp = 0; packet.m_nInfoField2 = rtmp->m_stream_id; packet.m_hasAbsTimestamp = TRUE; packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE; char *enc = packet.m_body; enc = AMF_EncodeString(enc, pend, &av_setDataFrame); enc = AMF_EncodeString(enc, pend, &av_onMetaData); enc = App->EncMetaData(enc, pend); packet.m_nBodySize = enc - packet.m_body; if(!RTMP_SendPacket(rtmp, &packet, FALSE)) { App->PostStopMessage(); return; } //---------------------------------------------- List<BYTE> packetPadding; DataPacket mediaHeaders; //---------------------------------------------- packet.m_nChannel = 0x05; // source channel packet.m_packetType = RTMP_PACKET_TYPE_AUDIO; App->GetAudioHeaders(mediaHeaders); packetPadding.SetSize(RTMP_MAX_HEADER_SIZE); packetPadding.AppendArray(mediaHeaders.lpPacket, mediaHeaders.size); packet.m_body = (char*)packetPadding.Array()+RTMP_MAX_HEADER_SIZE; packet.m_nBodySize = mediaHeaders.size; if(!RTMP_SendPacket(rtmp, &packet, FALSE)) { App->PostStopMessage(); return; } //---------------------------------------------- packet.m_nChannel = 0x04; // source channel packet.m_headerType = RTMP_PACKET_SIZE_LARGE; packet.m_packetType = RTMP_PACKET_TYPE_VIDEO; App->GetVideoHeaders(mediaHeaders); packetPadding.SetSize(RTMP_MAX_HEADER_SIZE); packetPadding.AppendArray(mediaHeaders.lpPacket, mediaHeaders.size); packet.m_body = (char*)packetPadding.Array()+RTMP_MAX_HEADER_SIZE; packet.m_nBodySize = mediaHeaders.size; if(!RTMP_SendPacket(rtmp, &packet, FALSE)) { App->PostStopMessage(); return; } }
uint8_t inline *amf_write_str(uint8_t *s, uint8_t *e, const char *c) { AVal a = AVALSTR(c); return (uint8_t*)AMF_EncodeString((char*)s, (char*)e, &a); }