AVPacket构建RtmpPacket

1.在学会构建之前你需要了解avpacket存储的是什么类型的数据

2.rtmppackt需要的是什么类型的数据 

avpacket存储的是h264数据startcode+nalu 

需要将avpacket进行分离 分离代码如下 

- (void)separation_avpacket_with_avpacket:(AVPacket *)av_packet{
    memset(encode_pkt, 0, av_packet->size);
    memcpy(encode_pkt, av_packet->data, av_packet->size);
    [self.seppkt_array removeAllObjects];
    SepPkt *beforpkt;
    SepPkt *lastpakt;
    for (int i = 0; i < av_packet->size - 4; i = i + 1) {
        uint8_t num = *encode_pkt;
        uint8_t num_1 = *(encode_pkt+1);
        uint8_t num_2 = *(encode_pkt+2);
        uint8_t num_3 = *(encode_pkt+3);
        encode_pkt =  encode_pkt + 1;
        if ((num == '\x00' && num_1 == '\x00' && num_2 == '\x00' && num_3 == '\x01') || (num =='\x00' && num_1 == '\x00' && num_2 == '\x01')) {
    
            if (num == '\x00'  && num_1 == '\x00' && num_2 == '\x00' && num_3 == '\x01') {
                SepPkt *seppkt = [[SepPkt alloc]init];
                seppkt.index = i;
                seppkt.seplen = 4;
                if (beforpkt) {
                    beforpkt.length = seppkt.index - beforpkt.index;
                }
                beforpkt = seppkt;
                [self.seppkt_array addObject:seppkt];
                encode_pkt =  encode_pkt + 4;
            }else if(num =='\x00' && num_1 == '\x00' && num_2 == '\x01'){
                SepPkt *seppkt = [[SepPkt alloc]init];
                seppkt.index = i;
                seppkt.seplen = 3;
                if (beforpkt) {
                    beforpkt.length = seppkt.index - beforpkt.index;
                }
                beforpkt = seppkt;
                [self.seppkt_array addObject:seppkt];
                encode_pkt =  encode_pkt + 3;
            }
        }
    }

}

当数据分离成功后 即可构建rtmppacket

rtmppacket的构建需要对照flv格式表 rtmppacket同flv格式相类似 

这个方法是构建sps以及pps

-(void)sendSpsPps:(uint8_t *)sps and_pps:(uint8_t *)pps and_spslen:(int)sps_len and_ppslen:(int)pps_len{
    XCQueueObj *obj = [[XCQueueObj alloc]init];
    obj->rtmp_packet = (RTMPPacket *)malloc(sizeof(RTMPPacket));
    int bodysize = 13 + sps_len + 3 + pps_len;
    RTMPPacket_Alloc(obj->rtmp_packet, bodysize);
    int i = 0;
    obj->rtmp_packet->m_body[i++] = 0x17;
    obj->rtmp_packet->m_body[i++] = 0x00;
    obj->rtmp_packet->m_body[i++] = 0x00;
    obj->rtmp_packet->m_body[i++] = 0x00;
    obj->rtmp_packet->m_body[i++] = 0x00;
    obj->rtmp_packet->m_body[i++] = 0x01;
    obj->rtmp_packet->m_body[i++] = sps[1];
    obj->rtmp_packet->m_body[i++] = sps[2];
    obj->rtmp_packet->m_body[i++] = sps[3];
    obj->rtmp_packet->m_body[i++] = 0xFF;
    obj->rtmp_packet->m_body[i++] = 0xE1;
    obj->rtmp_packet->m_body[i++] = (sps_len >> 8) & 0xff;
    obj->rtmp_packet->m_body[i++] = sps_len & 0xff;
    memcpy(&obj->rtmp_packet->m_body[i], sps, sps_len);
    i += sps_len;
    obj->rtmp_packet->m_body[i++] = 0x01;
    obj->rtmp_packet->m_body[i++] = (pps_len >> 8) & 0xff;
    obj->rtmp_packet->m_body[i++] = (pps_len) & 0xff;
    memcpy(&obj->rtmp_packet->m_body[i], pps, pps_len);
    obj->rtmp_packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;
    obj->rtmp_packet->m_nBodySize = bodysize;
    obj->rtmp_packet->m_nChannel = 10;
    obj->rtmp_packet->m_nTimeStamp = 0;
    obj->rtmp_packet->m_hasAbsTimestamp = 0;
    obj->rtmp_packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM;
    self.callback(obj);
}

下面是构建关键帧以及非关键帧

-(void)sendFrame:(uint8_t)type and_payload:(int)payload and_p_payload:(uint8_t *)p_payload{
    XCQueueObj *obj = [[XCQueueObj alloc]init];
    if (p_payload[2] == 0x00){
        payload -= 4;
        p_payload += 4;
    } else if(p_payload[2] == 0x01){
        payload -= 3;
        p_payload += 3;
    }
    obj->rtmp_packet = (RTMPPacket*)malloc(sizeof(RTMPPacket));
    int bodysize = 9 + payload;
    RTMPPacket_Alloc( obj->rtmp_packet, bodysize);
    RTMPPacket_Reset( obj->rtmp_packet);
    obj->rtmp_packet->m_body[0] = 0x27;
    if (type == '\x65') {//关键帧
        obj->rtmp_packet->m_body[0] = 0x17;
    }
    obj->rtmp_packet->m_body[1] = 0x01;
    obj->rtmp_packet->m_body[2] = 0x00;
    obj->rtmp_packet->m_body[3] = 0x00;
    obj->rtmp_packet->m_body[4] = 0x00;
    obj->rtmp_packet->m_body[5] = (payload >> 24) & 0xff;
    obj->rtmp_packet->m_body[6] = (payload >> 16) & 0xff;
    obj->rtmp_packet->m_body[7] = (payload >> 8) & 0xff;
    obj->rtmp_packet->m_body[8] = (payload) & 0xff;
    memcpy(& obj->rtmp_packet->m_body[9],p_payload,  payload);
    obj->rtmp_packet->m_hasAbsTimestamp = 0;
    obj->rtmp_packet->m_nBodySize = bodysize;
    obj->rtmp_packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;
    obj->rtmp_packet->m_nChannel = 0x10;
    obj->rtmp_packet->m_headerType = RTMP_PACKET_SIZE_LARGE;
    self.callback(obj);
}

构建后的数据使用callback返回到上一层然后进行推流或写入本地文件的操作

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值