对rtmpdump进行了封装、优化。
1. 使用说明请参考雷神文章 http://blog.csdn.net/leixiaohua1020/article/details/14229047
2. 遇到的问题
在ios移植中首先遇到的问题就是PIPE异常奔溃,添加 signal(SIGPIPE, SIG_IGN); 后还是不行,安卓是可以了。
后又在ios时修改为
int on = 1;
setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on));
这时就可以了。
第二个问题 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;
}
这样就解决了这个问题。
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