我在android上写了一个视频录制程序,录制时把视频、音频数据放在两个队列里,并开启两个线程去读取数据,写到sd卡中。现在的问题是,如果只写入h264,则视频播放正常(使用videoView,虽然没有声音);但如果同时写入了音频数据,则打不开视频文件。请问可能是什么原因才会造成这种结果呢?
打包h264+aac的代码如下:
//写视频数据
BOOL WriteVideoData(RECORD_PARAM *struRecordParam, char* pVideoData, int nSize, int iFrameRate, int iType, long lTimestemp){
BOOL bResult = FALSE;
if(struRecordParam==NULL || struRecordParam->mp4FileHandle<=0 || struRecordParam->isOpen==FALSE) return FALSE;
if (nSize==0) {//写空帧
if (!MP4WriteSample(struRecordParam->mp4FileHandle,
struRecordParam->videoId,
(const uint8_t*)pVideoData,
nSize,
lTimestemp,
0,
true)) {
return FALSE;
}
return TRUE;
}
if ((pVideoData[4]&0x1f) == 7) {
NSLOGE("writeVideoFrame: if 7");
if (struRecordParam->hasSPS) {
return FALSE;
}
NSLOGE("to MP4AddH264VideoTrack ");
struRecordParam->videoId = MP4AddH264VideoTrack(struRecordParam->mp4FileHandle,
struRecordParam->nVideoTimeScale,
(struRecordParam->nVideoTimeScale/struRecordParam->nVideoFrameRate),
struRecordParam->nVideoWidth,
struRecordParam->nVideoHeight,
pVideoData[5],
pVideoData[6],
pVideoData[7],
3);
if (struRecordParam->videoId == MP4_INVALID_TRACK_ID) {
return FALSE;
}
MP4SetVideoProfileLevel(struRecordParam->mp4FileHandle, 0x7F);
MP4AddH264SequenceParameterSet(struRecordParam->mp4FileHandle,
struRecordParam->videoId,
(const uint8_t*)(pVideoData+4),
nSize-4);
struRecordParam->hasSPS = TRUE;
NSLOGE("MP4AddH264VideoTrack ok");
} else if ((pVideoData[4]&0x1f) == 8) {
NSLOGE("writeVideoFrame: if 8");
if (struRecordParam->hasPPS) {
return FALSE;
}
MP4AddH264PictureParameterSet(struRecordParam->mp4FileHandle,
struRecordParam->videoId,
(const uint8_t*)(pVideoData+4),
nSize-4);
struRecordParam->hasPPS = TRUE;
} else {
NSLOGE("writeVideoFrame: if else");
pVideoData[0] = (nSize-4) >> 24;
pVideoData[1] = (nSize-4) >> 16;
pVideoData[2] = (nSize-4) >> 8;
pVideoData[3] = (nSize-4) & 0xff;
if (!MP4WriteSample(struRecordParam->mp4FileHandle,
struRecordParam->videoId,
(const uint8_t*)(pVideoData),
nSize,
MP4_INVALID_DURATION,
0,
true)) {
return FALSE;
}
}
return TRUE;
}
//写音频数据
BOOL WriteAudioData(RECORD_PARAM *struRecordParam, char* pAudioData, int nSize, long lTimestemp){
if(struRecordParam==NULL || struRecordParam->mp4FileHandle<=0 || struRecordParam->isOpen==FALSE) return FALSE;
BOOL bResult = FALSE;
if (struRecordParam->audioId == MP4_INVALID_TRACK_ID) {
//添加aac音频
NSLOGE("MP4AddAudioTrack");
struRecordParam->audioId = MP4AddAudioTrack(struRecordParam->mp4FileHandle, 48000, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE);
if (struRecordParam->audioId == MP4_INVALID_TRACK_ID) {
return bResult;
}
NSLOGE("MP4SetAudioProfileLevel");
MP4SetAudioProfileLevel(struRecordParam->mp4FileHandle, 0x2);
NSLOGE("MP4SetTrackESConfiguration");
MP4SetTrackESConfiguration(struRecordParam->mp4FileHandle, struRecordParam->audioId, pAudioData, nSize);
}
if (struRecordParam->audioId != MP4_INVALID_TRACK_ID) {
if (!MP4WriteSample(struRecordParam->mp4FileHandle, struRecordParam->audioId,(const uint8_t*)(pAudioData+7),
nSize-7,
lTimestemp,
0,
true)) {
NSLOGE("MP4WriteSample audio failed");
return FALSE;
}
NSLOGE("MP4WriteSample audio failed");
}
bResult = TRUE;
return bResult;
}