需求:想用Mp4V2 库将H264流录成MP4文件

反复折腾了好一下子,才整出来,再次纪录下。

具体实现:

1、下载Mp4v2源码

google code下载地址:http://code.google.com/p/mp4v2/downloads/list,若打不开链接,可以去github里搜索,本人也将其打包全部上传到github。

2、编译IOS上平台上合并库。

编译脚本如下(忘记出处了,不好意思):

#!/bin/shIOS_BASE_SDK=8.2
SOURCE="mp4v2-2.0.0"ROOT=`pwd`
FAT="$ROOT/fat"
THIN="$ROOT/thin"ARCHS="i386 x86_64 armv7 armv7s arm64 "
#ARCHS="i386 x86_64"
CONFIGURE_FLAGS="--disable-gch --disable-debug --disable-util \--enable-shared=no"clean()
{rm -rf $THINrm -rf $FAT
}cleanfor ARCH in $ARCHS
doecho "building $ARCH .."if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]thenPLATFORM="iPhoneSimulator"CPU=if [ "$ARCH" = "x86_64" ]thenSIMULATOR="-mios-simulator-version-min=7.0"HOST=elseSIMULATOR="-mios-simulator-version-min=5.0"HOST="--host=i386-apple-darwin"fielsePLATFORM="iPhoneOS"if [ $ARCH = "armv7s" ]thenCPU="--cpu=swift"elseCPU=fiSIMULATOR=HOST="--host=arm-apple-darwin"fiDEVROOT=`xcode-select -p`/"Platforms/$PLATFORM.platform/Developer"SDKROOT=$DEVROOT/SDKs/$PLATFORM$IOS_BASE_SDK.sdkCFLAGS="-arch $ARCH $SIMULATOR -pipe -no-cpp-precomp -isysroot $SDKROOT -I$SDKROOT/usr/include/"export CFLAGS="$CFLAGS"export CXX="llvm-g++"export CC="llvm-gcc"if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]thenexport LD=$DEVROOT/usr/bin/ldexport LDFLAGS="-L$SDKROOT/usr/lib/"elseexport LD=$DEVROOT/usr/bin/ldexport AR=$DEVROOT/usr/bin/arexport AS=$DEVROOT/usr/bin/asexport NM=$DEVROOT/usr/bin/nmexport RANLIB=$DEVROOT/usr/bin/ranlibexport LDFLAGS="-L$SDKROOT/usr/lib/"export LIBTOOL=$DEVROOT/usr/bin/libtoolexport LIPO=$DEVROOT/usr/bin/lipoexport OTOOL=$DEVROOT/usr/bin/otoolexport NMEDIT=$DEVROOT/usr/bin/nmeditexport DSYMUTIL=$DEVROOT/usr/bin/dsymutilexport STRIP=$DEVROOT/usr/bin/stripfiexport CPPFLAGS=$CFLAGSexport CXXFLAGS=$CFLAGSmake distclean$ROOT/$SOURCE/configure $CONFIGURE_FLAGS $HOST --prefix="$THIN/$ARCH"makemake installecho "build $ARCH done.."
doneecho "building fat .."mkdir -p "${FAT}/lib"set - $ARCHS
CWD=`pwd`cd ${THIN}/$1/lib
for LIB in `ls *.a`
doecho $LIBcd $CWDxcrun -sdk iphoneos lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB
donecd $CWD
cp -rf $THIN/$1/include $FATecho "build fat done.."

3、使用:在写入文件时,需要先写入SPS帧和PPS帧,然后再写入I,B,P帧,不然录像文件播放不了。

#include "mp4record.h"
#include <stdlib.h>typedef struct MP4V2_CONTEXT{int m_vWidth,m_vHeight,m_vFrateR,m_vTimeScale;MP4FileHandle m_mp4FHandle;MP4TrackId m_vTrackId,m_aTrackId;double m_vFrameDur;
} MP4V2_CONTEXT;struct MP4V2_CONTEXT * recordCtx = NULL;int initMp4Encoder(const char * filename,int width,int height){int ret = -1;recordCtx = malloc(sizeof(struct MP4V2_CONTEXT));if (!recordCtx) {printf("error : malloc context \n");return ret;}recordCtx->m_vWidth = width;recordCtx->m_vHeight = height;recordCtx->m_vFrateR = 25;recordCtx->m_vTimeScale = 90000;recordCtx->m_vFrameDur = 300;recordCtx->m_vTrackId = 0;recordCtx->m_aTrackId = 0;recordCtx->m_mp4FHandle = MP4Create(filename,0);if (recordCtx->m_mp4FHandle == MP4_INVALID_FILE_HANDLE) {printf("error : MP4Create  \n");return ret;}MP4SetTimeScale(recordCtx->m_mp4FHandle, recordCtx->m_vTimeScale);//------------------------------------------------------------------------------------- audio track
//    recordCtx->m_aTrackId = MP4AddAudioTrack(recordCtx->m_mp4FHandle, 44100, 1024, MP4_MPEG4_AUDIO_TYPE);
//    if (recordCtx->m_aTrackId == MP4_INVALID_TRACK_ID){
//        printf("error : MP4AddAudioTrack  \n");
//        return ret;
//    }
//
//    MP4SetAudioProfileLevel(recordCtx->m_mp4FHandle, 0x2);
//    uint8_t aacConfig[2] = {18,16};
//    MP4SetTrackESConfiguration(recordCtx->m_mp4FHandle,recordCtx->m_aTrackId,aacConfig,2);
//    printf("ok  : initMp4Encoder file=%s  \n",filename);return 0;
}
int mp4VEncode(uint8_t * _naluData ,int _naluSize){int index = -1;if(_naluData[0]==0 && _naluData[1]==0 && _naluData[2]==0 && _naluData[3]==1 && _naluData[4]==0x67){index = _NALU_SPS_;}if(index!=_NALU_SPS_ && recordCtx->m_vTrackId == MP4_INVALID_TRACK_ID){return index;}if(_naluData[0]==0 && _naluData[1]==0 && _naluData[2]==0 && _naluData[3]==1 && _naluData[4]==0x68){index = _NALU_PPS_;}if(_naluData[0]==0 && _naluData[1]==0 && _naluData[2]==0 && _naluData[3]==1 && _naluData[4]==0x65){index = _NALU_I_;}if(_naluData[0]==0 && _naluData[1]==0 && _naluData[2]==0 && _naluData[3]==1 && _naluData[4]==0x41){index = _NALU_P_;}//switch(index){case _NALU_SPS_:if(recordCtx->m_vTrackId == MP4_INVALID_TRACK_ID){recordCtx->m_vTrackId = MP4AddH264VideoTrack(recordCtx->m_mp4FHandle,recordCtx->m_vTimeScale,recordCtx->m_vTimeScale / recordCtx->m_vFrateR,recordCtx->m_vWidth,     // widthrecordCtx->m_vHeight,    // height_naluData[5], // sps[1] AVCProfileIndication_naluData[6], // sps[2] profile_compat_naluData[7], // sps[3] AVCLevelIndication3);           // 4 bytes length before each NAL unitif (recordCtx->m_vTrackId == MP4_INVALID_TRACK_ID)  {return -1;}MP4SetVideoProfileLevel(recordCtx->m_mp4FHandle, 0x7F); //  Simple Profile @ Level 3}MP4AddH264SequenceParameterSet(recordCtx->m_mp4FHandle,recordCtx->m_vTrackId,_naluData+4,_naluSize-4);//break;case _NALU_PPS_:MP4AddH264PictureParameterSet(recordCtx->m_mp4FHandle,recordCtx->m_vTrackId,_naluData+4,_naluSize-4);break;case _NALU_I_:{uint8_t * IFrameData = malloc(_naluSize+1);//IFrameData[0] = (_naluSize-3) >>24;IFrameData[1] = (_naluSize-3) >>16;IFrameData[2] = (_naluSize-3) >>8;IFrameData[3] = (_naluSize-3) &0xff;memcpy(IFrameData+4,_naluData+3,_naluSize-3);
//            if(!MP4WriteSample(recordCtx->m_mp4FHandle, recordCtx->m_vTrackId, IFrameData, _naluSize+1, recordCtx->m_vFrameDur/44100*90000, 0, 1)){
//                return -1;
//            }
//            recordCtx->m_vFrameDur = 0;if(!MP4WriteSample(recordCtx->m_mp4FHandle, recordCtx->m_vTrackId, IFrameData, _naluSize+1, MP4_INVALID_DURATION, 0, 1)){return -1;}free(IFrameData);//break;}case _NALU_P_:{_naluData[0] = (_naluSize-4) >>24;  _naluData[1] = (_naluSize-4) >>16;  _naluData[2] = (_naluSize-4) >>8;  _naluData[3] = (_naluSize-4) &0xff;//            if(!MP4WriteSample(recordCtx->m_mp4FHandle, recordCtx->m_vTrackId, _naluData, _naluSize, recordCtx->m_vFrameDur/44100*90000, 0, 1)){
//                return -1;
//            }
//            recordCtx->m_vFrameDur = 0;if(!MP4WriteSample(recordCtx->m_mp4FHandle, recordCtx->m_vTrackId, _naluData, _naluSize, MP4_INVALID_DURATION, 0, 1)){return -1;}break;}}return 0;
}int mp4AEncode(uint8_t * data ,int len){if(recordCtx->m_vTrackId == MP4_INVALID_TRACK_ID){return -1;}MP4WriteSample(recordCtx->m_mp4FHandle, recordCtx->m_aTrackId, data, len , MP4_INVALID_DURATION, 0, 1);recordCtx->m_vFrameDur += 1024;return 0;
}void closeMp4Encoder(){if(recordCtx){if (recordCtx->m_mp4FHandle != MP4_INVALID_FILE_HANDLE) {MP4Close(recordCtx->m_mp4FHandle,0);recordCtx->m_mp4FHandle = NULL;}free(recordCtx);recordCtx = NULL;}printf("ok  : closeMp4Encoder  \n");}

附:有网友提出编译不过,报错。

原因:需要添加系统库libc++.dylib,添加即可。

参考网址:

http://blog.csdn.net/skdkjzz/article/details/40506473

https://github.com/Thinkerfans/lib-mp4v2

Mp4V2库编译及使用相关推荐

  1. 第七季2:MP4v2库的移植与播放实战

    以下内容源于朱有鹏课程,如有侵权,请告知删除. 本节主要内容: (1)移植MP4V2库,该开源库实现了对视频流(如h264视频流)的打包与封装(如MP4格式). (2)部署和运行打包代码,测试打包生成 ...

  2. 【Android 安装包优化】WebP 应用 ( libwebp 源码下载 | Android.mk 和 Application.mk 构建脚本修改 | libwebp 函数库编译 )

    文章目录 一. libwebp 源码下载 二. libwebp 源码编译脚本修改 三. libwebp 函数库编译 四.参考资料 一. libwebp 源码下载 Google 提供了一系列的 WebP ...

  3. 将STM32的标准库编译成lib

    转载自:http://www.cnblogs.com/zyqgold/p/3189719.html 以前一直使用STM32的标准库,需要一步步地将代码加进去,将编译选项设置好,然后再编译整个工程. 这 ...

  4. linux 安装库 编译提示-lcrypto 无法链接,缺少 crypto 库

    linux 安装库 缺少 crypto 库 编译提示-lcrypto 无法链接,缺少 crypto 库 方法一 ------------------------------------- crypto ...

  5. 如何将内核静态库编译连接到驱动程序中去【转】

    转自:http://blog.csdn.net/ganjianfeng2003/article/details/8089551 如何将内核静态库编译连接到驱动程序中去 2010-12-07 08:27 ...

  6. buildroot自带程序(库)编译并安装

    前几天情绪有点低落,经过周末的调整重新恢复状态,谢谢有爱的朋友们留言和点赞,有你们的陪伴我会更加努力,让我们一起开心写程序..... buildroot简介: 引用官方的简述: Buildroot是一 ...

  7. Boost库编译安装

    一.Boost库介绍 Boost库是一个经过千锤百炼.可移植.提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一.Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成 ...

  8. ubuntu下flann库编译报错处理

    ubuntu下flann库编译报错处理 编译flann的时候显示以下报错: CMake Error at src/cpp/CMakeLists.txt:33 (add_library):No SOUR ...

  9. pthread-win32库编译及使用方法注意事项

    "该文引用自 CruiseYoung的:pthread-win32库编译及使用方法注意事项 http://blog.csdn.net/fksec/article/details/415179 ...

最新文章

  1. android自定义布局的使用!
  2. thinkphp当前php路径,分析thinkphp常见路径用法分析
  3. 猛然发现,已经第100篇随笔了
  4. Php的if自动转换类型,php类型的自动转换
  5. 【现代机器人学】名词概念的理解
  6. 学编程怎样入门?这是最有效的学习方法
  7. 强大好看的dz论坛社区源码手机端
  8. mtk开机声音与关机声音修改(原创)
  9. 关于LTE下行导频信号
  10. 电脑维修的基本原则和方法
  11. 动环监控系统的监控对象有哪些?动环监控系统作用
  12. 2019牛客暑期多校训练营(第九场)A——The power of Fibonacci(循环节+中国剩余定理(互质)||广义BM)
  13. Linux ifconfig命令无效的解决方法
  14. Java API VIII
  15. SPA、MPA 的优缺点
  16. 整理18、19、20年关于《人工智能》的标准和评估规范
  17. linux毁了所有数据,小心!数据在你不注意的时候居然偷偷损毁了
  18. 心理测评软件php mysql_中学心理测评软件
  19. 跟我一起写 Makefile(浅显易懂版)
  20. 急速扩张的银隆曝出欠款,董明珠的梦想与现实

热门文章

  1. Git GUI汉化,设置成中文
  2. php strftime 毫秒,php strftime函数获取日期时间(switch用法)
  3. UG NX二次开发(C#)-分析-测量曲面的面积
  4. 力扣1089 的本手妙手俗手
  5. int *p() ; int (*p)();
  6. 三种常见的SQL插入语句
  7. 用正交表设计测试用例
  8. 软件测试——缺陷密度、缺陷数据分析的重要性、缺陷数据分析的数据指标
  9. 【计算机系统结构】Self-modifying code 自修改代码
  10. [共享软件]共享软件如何赚钱