使用MP4v2封装h264流时,出现FindTrackIndex: Track id 0 doesn’t exist。需要设置MP4TrackId。
MP4TrackId m_videoTrack = MP4AddH264VideoTrack(m_hFile, 90000, 90000/25, nWidth, nHeight, nalu.data[1], nalu.data[2], nalu.data[3], DEFAULT_VIDEO_TRACK_NUM);
相关代码如下:下面代码不全,是用于解决参考链接代码使用时遇到的问题。
typedef struct _MP4_Nalu
{
int type;
int size;
unsigned char *data;
}MP4_Nalu;
MP4FileHandle m_hFile;
MP4TrackId m_videoTrack;
int ReadOneNaluFromBuf(const unsigned char *buffer,unsigned int nBufferSize,unsigned int offSet,MP4_Nalu &nalu)
{
int i = offSet;
while(i<nBufferSize)
{
if(buffer[i++] == 0x00 &&
buffer[i++] == 0x00 &&
buffer[i++] == 0x00 &&
buffer[i++] == 0x01
)
{
int pos = i;
while (pos<nBufferSize)
{
if(buffer[pos++] == 0x00 &&
buffer[pos++] == 0x00 &&
buffer[pos++] == 0x00 &&
buffer[pos++] == 0x01
)
{
break;
}
}
if(pos == nBufferSize)
{
nalu.size = pos-i;
}
else
{
nalu.size = (pos-4)-i;
}
nalu.type = buffer[i]&0x1f;
nalu.data =(unsigned char*)&buffer[i];
return (nalu.size+i-offSet);
}
}
return 0;
}
int MP4Encoder::MP4CreateFile(const char* sFileName, int Movie_Time_Scale)
{
m_hFile = MP4Create(sFileName);
if (m_hFile == MP4_INVALID_FILE_HANDLE)
{
printf("create mp4 file error!\n");
return -1;
}
if (!MP4SetTimeScale(m_hFile, Movie_Time_Scale))
{
printf("set time Scale error!\n");
return -1;
}
return 0;
}
int MP4CreateFile(const char* sFileName, int Movie_Time_Scale)
{
m_hFile = MP4Create(sFileName);
if (m_hFile == MP4_INVALID_FILE_HANDLE)
{
printf("create mp4 file error!\n");
return -1;
}
if (!MP4SetTimeScale(m_hFile, Movie_Time_Scale))
{
printf("set time Scale error!\n");
return -1;
}
return 0;
}
//由于h264中可能有多个sps导致生成MP4文件只能播放一部分。所以只对第一次进行封装。
int MP4WriteH264Data(MP4_Nalu nalu, int& spsFirst, int& ppsFirst, int nWidth, int nHeight)
{
int result = 0;
if(0x07 == nalu.type && spsFirst == 0)
{
printf("sps frame\n");
m_videoTrack = MP4AddH264VideoTrack(m_hFile, 90000, 90000/25, nWidth, nHeight, nalu.data[1], nalu.data[2], nalu.data[3], DEFAULT_VIDEO_TRACK_NUM);
MP4SetVideoProfileLevel(m_hFile, DEFAULT_VIDEO_PROFILE_LEVEL);
MP4AddH264SequenceParameterSet(m_hFile, m_videoTrack, nalu.data, nalu.size);
spsFirst = 1;
}
else if(0x08 == nalu.type && ppsFirst == 0)
{
printf("pps frame\n");
MP4AddH264PictureParameterSet(m_hFile, m_videoTrack, nalu.data, nalu.size);
ppsFirst = 1;
}
if(spsFirst == 1 && ppsFirst == 1)
{
int datalen = nalu.size + 4;
unsigned char *data = (unsigned char *)calloc(datalen, 1);
printf("frame datalen:%d\n", datalen);
data[0] = nalu.size >> 24;
data[1] = nalu.size >> 16;
data[2] = nalu.size >> 8;
data[3] = nalu.size & 0xff;
memcpy(data+4, nalu.data, nalu.size);
if(0x05 == nalu.type)
{
result = MP4WriteSample(m_hFile, m_videoTrack, data, datalen, MP4_INVALID_DURATION, 0, true);
}
else
{
result = MP4WriteSample(m_hFile, m_videoTrack, data, datalen, MP4_INVALID_DURATION, 0, false);
}
free(data);
}
}
参考链接:
https://blog.csdn.net/stn_lcd/article/details/74541860