librtmp推流使用aac编码音频的html5和flash播放问题

时间:2023-03-09 01:24:52
librtmp推流使用aac编码音频的html5和flash播放问题

公司项目中使用rtmp推流,音频编码aac、视频编码H264。
windows和android平台都没有发现问题。
然而在IOS版本的APP中发现几个问题:
1. 推流后flash播放异常
2. IOS平台微信分享后html5播放异常
但是在PC上播放正常,android平台上html5播放正常。

经过两天的钻研,发现问题如下:
1. rtmp建立连接的时候先发送音视频相关参数。或者第一帧发送的数据应该如下:

 m_pPacketAudio->m_nChannel = 0x04;
m_pPacketAudio->m_headerType = RTMP_PACKET_SIZE_LARGE;
m_pPacketAudio->m_nTimeStamp = ;
m_pPacketAudio->m_nInfoField2 = m_pRtmp->m_stream_id;
m_pPacketAudio->m_hasAbsTimestamp = ; char * szBodyBufferAudio = m_pPacketAudio->m_body;
/*
[UB4]:10,soundformat:aac
[UB2]:3,sample reate,44k
[UB1]:1,bitspersample,16bit
[UB1]:1,channel,2
*/
szBodyBufferAudio[ ] = 0xAF;
//AACPacketType,[UI8],0:AAC sequence header
szBodyBufferAudio[ ] = 0x00;
//AudioSpecificConfig,2 byte
//for AAC LE
//44k ,2-ch aac-lc
szBodyBufferAudio[ ] = 0x12;
szBodyBufferAudio[ ] = 0x10;
m_pPacketAudio->m_nBodySize = ;
m_pPacketAudio->m_packetType = RTMP_PACKET_TYPE_AUDIO;
RTMP_SendPacket(m_pRtmp, m_pPacketAudio, );

2. 后面的音视频流发送rtmp时,写法如下:

 if(dwType == PACKET_VIDEO)
{
// ......
//RTMP_SendPacket(m_pRtmp, m_pPacketVideo, 0);
// ......
}
else if(dwType == PACKET_AUDIO)
{
char * szBodyBufferAudio = m_pPacketAudio->m_body;
/* [UB4]:10,soundformat:aac
[UB2]:3,sample reate,44k
[UB1]:1,bitspersample,16bit
[UB1]:1,channel,2
*/ // 以下两行是最关键的两行
lDataSize -= 7;
pFrameData += 7;
szBodyBufferAudio[ ] = 0xAF;
//AACPacketType,[UI8],1:Raw AAC frame data
szBodyBufferAudio[ ] = 0x01;
m_pPacketAudio->m_nBodySize = lDataSize + ;
m_pPacketAudio->m_nChannel = 0x04;
m_pPacketAudio->m_headerType = RTMP_PACKET_SIZE_MEDIUM;
m_pPacketAudio->m_nInfoField2 = m_pRtmp->m_stream_id;
m_pPacketAudio->m_hasAbsTimestamp = ;
//memcpy(szBodyBufferAudio + 2, pFrameData, lDataSize);
//RTMP_SendPacket(m_pRtmp, m_pPacketAudio, 0); CMQueueUnit* pQu = m_pSendBuffer->StartWrite();
if(pQu)
{
MByte* pBuf = pQu->GetBuf();
if(pBuf){
memcpy(pBuf, m_pPacketAudio, sizeof(RTMPPacket));
((RTMPPacket*)pBuf)->m_body = (char*)(pBuf + sizeof(RTMPPacket) + RTMP_MAX_HEADER_SIZE);
memcpy(((RTMPPacket*)pBuf)->m_body, szBodyBufferAudio, );
memcpy(((RTMPPacket*)pBuf)->m_body + , pFrameData, lDataSize);
m_pSendBuffer->EndWrite(pQu, TRUE);
}
else
m_pSendBuffer->EndWrite(pQu, FALSE);
} #ifdef WIN32
m_dwRemainTimes += ();
m_pPacketAudio->m_nTimeStamp += ;
#elif defined __IPHONE__
m_dwRemainTimes += ();
m_pPacketAudio->m_nTimeStamp += ;
#else
m_dwRemainTimes += (/);
m_pPacketAudio->m_nTimeStamp += ;
#endif
if(m_dwRemainTimes>)
{
m_pPacketAudio->m_nTimeStamp += ;
m_dwRemainTimes -= ;
} m_dwOldTimeStamp = CMHelpFunc::GetCurTimeStamp();
}

3. 视频编码后的数据,处理如下。
那几句一定要注释 不然flash和Html5播放不出视频。

 if( lOutSize ==  || lOutSize > m_lVFrameOutBuffSize )
{
LOGE( "Encoding one video frame failed 2 (%d)", res );
res = MV2_ERR_MEDIASTREAM_VIDEOENCODE;
return res;
}
else
{
MByte * pRawData = m_pVFrameOutBuff; // 以下几句一定要注释
// if(bIsSyncFrame)//first frame ,skip sps/pps header,length is 22,NAL header,length:4
// {
// lOutSize -= 26;
// pRawData += 26;
// m_bFirstVF = MFalse;
// }
// else
// {
// /*just skip NAL Header: 4 byte*/
// lOutSize -= 4;
// pRawData += 4;
// } if( m_pRtmp )
res = m_pRtmp->SendMediaData( pRawData, lOutSize, PACKET_VIDEO, bIsSyncFrame );
}

不然播放出来的将会是这样

librtmp推流使用aac编码音频的html5和flash播放问题