1. RTMP streaming method 1: Push H.264, ACC
1. Create a thread to initialize RTMP.
void RtmpPush::init() { LOGE("init()"); mCallJava->onConnectint(THREAD_MAIN); pthread_create( & amp;push_thread, NULL, callBackPush, this); } void *callBackPush(void *data) { RtmpPush *rtmpPush = static_cast<RtmpPush *>(data); rtmpPush->startPushing = false; LOGE("callBackPush()"); //RTMP applies for heap memory rtmpPush->rtmp = RTMP_Alloc(); //RTMP initialization RTMP_Init(rtmpPush->rtmp); rtmpPush->rtmp->Link.timeout = 10; rtmpPush->rtmp->Link.lFlags |= RTMP_LF_LIVE; //Set the push address RTMP_SetupURL(rtmpPush->rtmp, rtmpPush->url); //Turn on the output mode, when pushing the stream here. (You don’t need to turn it on when pulling the stream) RTMP_EnableWrite(rtmpPush->rtmp); //connect to the server if(!RTMP_Connect(rtmpPush->rtmp, NULL)) { //LOGE("can not connect the url"); rtmpPush->mCallJava->onConnectFail("RTMPConnectsFaile"); goto end; } if(!RTMP_ConnectStream(rtmpPush->rtmp, 0)) { //LOGE("can not connect the stream of service"); rtmpPush->mCallJava->onConnectFail("RTMPConnectStreamFaile"); goto end; } rtmpPush->mCallJava->onConnectsuccess(); LOGE("The link is successful, start pushing"); rtmpPush->startPushing = true; rtmpPush->startTime = RTMP_GetTime(); while(true) { if(!rtmpPush->startPushing) { break; } RTMPPacket *packet = NULL; packet = rtmpPush->queue->getRtmpPacket(); if(packet != NULL) { //Send packet int result = RTMP_SendPacket(rtmpPush->rtmp, packet, 1); //LOGE("RTMP_SendPacket result is %d", result); if(!result){ rtmpPush->mCallJava->onConnectFail("rtmpSocketDisconnect"); goto end; } RTMPPacket_Free(packet); free(packet); packet = NULL; } } end: RTMP_Close(rtmpPush->rtmp); RTMP_Free(rtmpPush->rtmp); rtmpPush->rtmp = NULL; pthread_exit( & amp;rtmpPush->push_thread); }
2. RTMP sends SPS and PPS
void RtmpPush::pushSPSPPS(char *sps, int sps_len, char *pps, int pps_len) { int bodysize = sps_len + pps_len + 16; RTMPPacket *packet = static_cast<RTMPPacket *>(malloc(sizeof(RTMPPacket))); RTMPPacket_Alloc(packet, bodysize); RTMPPacket_Reset(packet); char *body = packet->m_body; int i = 0; body[i + + ] = 0x17; body[i + + ] = 0x00; body[i + + ] = 0x00; body[i + + ] = 0x00; body[i + + ] = 0x00; body[i + + ] = 0x01; body[i + + ] = sps[1]; body[i + + ] = sps[2]; body[i + + ] = sps[3]; body[i + + ] = 0xFF; body[i + + ] = 0xE1; body[i + + ] = (sps_len >> 8) & amp; 0xff; body[i + + ] = sps_len & 0xff; memcpy( & amp;body[i], sps, sps_len); i + = sps_len; body[i + + ] = 0x01; body[i + + ] = (pps_len >> 8) & amp; 0xff; body[i + + ] = pps_len & 0xff; memcpy( & amp;body[i], pps, pps_len); packet->m_packetType = RTMP_PACKET_TYPE_VIDEO; packet->m_nBodySize = bodysize; packet->m_nTimeStamp = 0; packet->m_hasAbsTimestamp = 0; packet->m_nChannel = 0x04; packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM; packet->m_nInfoField2 = rtmp->m_stream_id; queue->putRtmpPacket(packet); }
3. Send video data
void RtmpPush::pushVideoData(char *data, int data_len, bool keyframe) { int bodysize = data_len + 9; RTMPPacket *packet = static_cast<RTMPPacket *>(malloc(sizeof(RTMPPacket))); RTMPPacket_Alloc(packet, bodysize); RTMPPacket_Reset(packet); char *body = packet->m_body; int i = 0; if(keyframe) { body[i + + ] = 0x17; } else{ body[i + + ] = 0x27; } body[i + + ] = 0x01; body[i + + ] = 0x00; body[i + + ] = 0x00; body[i + + ] = 0x00; body[i + + ] = (data_len >> 24) & amp; 0xff; body[i + + ] = (data_len >> 16) & amp; 0xff; body[i + + ] = (data_len >> 8) & amp; 0xff; body[i + + ] = data_len & 0xff; memcpy( & amp;body[i], data, data_len); packet->m_packetType = RTMP_PACKET_TYPE_VIDEO; packet->m_nBodySize = bodysize; packet->m_nTimeStamp = RTMP_GetTime() - startTime; packet->m_hasAbsTimestamp = 0; packet->m_nChannel = 0x04; packet->m_headerType = RTMP_PACKET_SIZE_LARGE; packet->m_nInfoField2 = rtmp->m_stream_id; queue->putRtmpPacket(packet); }
4. Send audio data
void RtmpPush::pushAudioData(char *data, int data_len) { int bodysize = data_len + 2; RTMPPacket *packet = static_cast<RTMPPacket *>(malloc(sizeof(RTMPPacket))); RTMPPacket_Alloc(packet, bodysize); RTMPPacket_Reset(packet); char *body = packet->m_body; body[0] = 0xAF; body[1] = 0x01; memcpy( & amp;body[2], data, data_len); packet->m_packetType = RTMP_PACKET_TYPE_AUDIO; packet->m_nBodySize = bodysize; packet->m_nTimeStamp = RTMP_GetTime() - startTime; packet->m_hasAbsTimestamp = 0; packet->m_nChannel = 0x04; packet->m_headerType = RTMP_PACKET_SIZE_LARGE; packet->m_nInfoField2 = rtmp->m_stream_id; queue->putRtmpPacket(packet); }
2. RTMP streaming method 2: Push FLV encapsulation format
int RtmpPush::pushFlvData(char *data, int data_len) { if (data_len < 15) { return -1; } //packet attributes uint32_t type = 0; uint32_t datalength = 0; uint32_t timestamp = 0; uint32_t streamid = 0; memcpy(&type, data, 1); data + + ; memcpy( & amp;datalength, data, 3); datalength = HTON24(datalength); data + = 3; memcpy(×tamp, data, 4); timestamp = HTONTIME(timestamp); data + = 4; memcpy(&streamid, data, 3); streamid = HTON24(streamid); data + = 3; //LOGE("Parse packet data: %u,%u,%u,%u,%d",type, datalength, timestamp, streamid, data_len); if (type != 0x08 & amp; & amp; type != 0x09) { return -2; } if (datalength != (data_len - 11 - 4)) { return -3; } RTMPPacket *packet = static_cast<RTMPPacket *>(malloc(sizeof(RTMPPacket))); RTMPPacket_Alloc(packet, 1024 * 64); RTMPPacket_Reset(packet); memcpy(packet->m_body, data, data_len - 11 - 4); packet->m_headerType = RTMP_PACKET_SIZE_LARGE; packet->m_nTimeStamp = timestamp; packet->m_packetType = type; packet->m_nBodySize = datalength; if(type == RTMP_PACKET_TYPE_AUDIO){ packet->m_nChannel = 0x05;//audio }else if(type == RTMP_PACKET_TYPE_VIDEO){ packet->m_nChannel = 0x04;//video }else if(type == RTMP_PACKET_TYPE_INFO){ packet->m_nChannel = 0x03;//metaData } packet->m_nInfoField2 = rtmp->m_stream_id; queue->putRtmpPacket(packet); return 0; }