RTMP streams in two ways: H.264, ACC and FLV encapsulation format

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(&timestamp, 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;
}