rtmpdump的使用及遇到的问题

对rtmpdump进行了封装、优化。ios


1. 使用说明请参考雷神文章 http://blog.csdn.net/leixiaohua1020/article/details/14229047c++


2. 遇到的问题git

在ios移植中首先遇到的问题就是PIPE异常奔溃,添加 signal(SIGPIPE, SIG_IGN); 后仍是不行,安卓是能够了。github

后又在ios时修改成安全

int on = 1;网络

setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
socket

这时就能够了。ide


第二个问题 RTMP_GetNextMediaPacket 获取到的视频包会致使视频解码器奔溃,最后查出是包体有误,长度有时会是小于5个字节的数据。始终没查出这是怎么出来的这种包,最后作了安全检查优化

int RtmpConnection::handle_input()
{
RTMPPacket packet = { 0 };
int read = RTMP_GetNextMediaPacket(_rtmp, &packet);
if (read <= 0 || read == 2){
return -1;
}
uint8_t *packetBody = (uint8_t *)packet.m_body;
unsigned int nPacketLen = packet.m_nBodySize;
if (_callback && _running){
if (packet.m_packetType == 0x09 && nPacketLen > 5){
_callback->onReceiveFrame(_uid, { packetBody ,nPacketLen ,packet.m_nTimeStamp ,VIDEO_MEDIA });
}else if (packet.m_packetType == 0x08 && nPacketLen > 1){
_callback->onReceiveFrame(_uid, { packetBody ,nPacketLen ,packet.m_nTimeStamp ,AUDIO_MEDIA });
}
}
stat_bytes(packet.m_nBodySize);
RTMPPacket_Free(&packet);
return 0;
}

 这样就解决了这个问题。ui

2.对rtmpdump的扩展

在使用中因为会有网络差的时候,这时用户可能想中止看视频只接收音频,而rtmpdump中无此功能,查看rtmp协议里有receiveAudio receiveVideo cmd消息,将他们添加到rtmpdump中

SAVC(receiveAudio);
int
RTMP_SendReceiveAudio(RTMP *r,int flag)
{
    RTMPPacket packet;
    char pbuf[256], *pend = pbuf + sizeof(pbuf);
    char *enc;
    packet.m_nChannel = 0x03; /* control channel (invoke) */
    packet.m_headerType = 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;
    enc = packet.m_body;
    enc = packet.m_body;
    enc = AMF_EncodeString(enc, pend, &av_receiveAudio);
    enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);
    *enc++ = AMF_NULL;
    enc = AMF_EncodeBoolean(enc, pend,flag);
    packet.m_nBodySize = enc - packet.m_body;
    return RTMP_SendPacket(r, &packet, TRUE);
}

SAVC(receiveVideo);
int
RTMP_SendReceiveVideo(RTMP *r,int flag)
{
    RTMPPacket packet;
    char pbuf[256], *pend = pbuf + sizeof(pbuf);
    char *enc;   
    packet.m_nChannel = 0x03; /* control channel (invoke) */
    packet.m_headerType = 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;
    enc = packet.m_body;
    enc = packet.m_body;
    enc = AMF_EncodeString(enc, pend, &av_receiveVideo);
    enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);
    *enc++ = AMF_NULL;
    enc = AMF_EncodeBoolean(enc, pend,flag);
    packet.m_nBodySize = enc - packet.m_body;
    return RTMP_SendPacket(r, &packet, TRUE);
}


这样用户就能够根据本身的需求来定制须要接收音视频任意一种或两个都接收。

转载请注明原址,谢谢!

附上源码地址  https://github.com/haowei8196/RtmpConnection