zouzhiheng 2016-11-01 03:55 采纳率: 33.3%
浏览 5016
已结题

android上使用MP4v2打包h264+aac,数据错误,不能播放生成的mp4文件

大家好,我在android上写了一个视频录像程序,视音频数据(h264+aac)保存在两个队列里,我想要用MP4v2,开两个线程把数据打包成MP4视频文件,结果发现生成的视频不能使用VideoView播放,去SD卡找到生成的视频文件,使用小米视频能播放,却没有声音,数据也有错误——视频时长显示为11:35:36,实际录像时长只有几秒,能播放的也是那几秒。

网上能查的资料很少,github上也没有可供参考的项目。我自己瞎改了一下参数,没有效果。测试后发现不写入音频数据的话,可以正常播放(没有声音),一写入音频数据,或者说调用了MP4AddAudioTrack找到audio的trackId就会出现该问题,猜测是数据写入错误,具体原因还不清楚,也想不出什么解决方法。请问有哪些可能的原因和解决问题的方向吗?(工作的一个问题,只能用MP4v2,不能用ffmpeg)

已经被这个问题困扰了很久了,所以把全部C币都拿出来悬赏,也不知道大家在意不在意这个C币,希望有了解MP4v2的大神帮忙解惑,万分感谢!


如果这个问题比较复杂,或者说可能的原因有很多,一下子说不完,那么可以给个学习方向上的建议吗?比如应该去哪里学习、补充哪些知识之类,对这个问题,我真的有一种无从下手的感觉。只要给我一个研究方向/建议,我也很感激了!

  • 写回答

6条回答 默认 最新

  • zouzhiheng 2016-11-01 03:59
    关注

    这是代码:

    //写视频数据
    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 (struRecordParam->videoId == MP4_INVALID_TRACK_ID) {
        //
        //              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 WriteEmptyVideoData(RECORD_PARAM *struRecordParam){
        if(struRecordParam==NULL || struRecordParam->isOpen==FALSE) return FALSE;
    
        if (!MP4WriteSample(struRecordParam->mp4FileHandle,
                struRecordParam->videoId,
                NULL,
                0,
                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;
        uint8_t *bufaudio = (uint8_t*)pAudioData;
    
        if (struRecordParam->audioId == MP4_INVALID_TRACK_ID)
        {
            //添加aac音频
            NSLOGE("MP4AddAudioTrack");//add for test
            struRecordParam->audioId = MP4AddAudioTrack(struRecordParam->mp4FileHandle, 48000, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE);
            if (struRecordParam->audioId == MP4_INVALID_TRACK_ID)
            {
                return bResult;
            }
    
            NSLOGE("MP4SetAudioProfileLevel");//add for test
            MP4SetAudioProfileLevel(struRecordParam->mp4FileHandle, 0x02);
            NSLOGE("MP4SetTrackESConfiguration");//add for test
            MP4SetTrackESConfiguration(struRecordParam->mp4FileHandle, struRecordParam->audioId, &bufaudio[0], nSize);
        }
    
        if (struRecordParam->audioId != MP4_INVALID_TRACK_ID) {
    
            NSLOGE("MP4WriteSample audio");//add for test
            MP4WriteSample(struRecordParam->mp4FileHandle,
                        struRecordParam->audioId,
                        &bufaudio[7],
                        nSize-7,
                        lTimestemp,
                        0,
                        true);
        }
    
        bResult = TRUE;
    
        return bResult;
    } 
    
    评论

报告相同问题?

悬赏问题

  • ¥15 FPGA-SRIO初始化失败
  • ¥15 MapReduce实现倒排索引失败
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码
  • ¥50 随机森林与房贷信用风险模型
  • ¥50 buildozer打包kivy app失败
  • ¥30 在vs2022里运行python代码
  • ¥15 不同尺寸货物如何寻找合适的包装箱型谱
  • ¥15 求解 yolo算法问题