Mp4V2库编译及使用
需求:想用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库编译及使用相关推荐
- 第七季2:MP4v2库的移植与播放实战
以下内容源于朱有鹏课程,如有侵权,请告知删除. 本节主要内容: (1)移植MP4V2库,该开源库实现了对视频流(如h264视频流)的打包与封装(如MP4格式). (2)部署和运行打包代码,测试打包生成 ...
- 【Android 安装包优化】WebP 应用 ( libwebp 源码下载 | Android.mk 和 Application.mk 构建脚本修改 | libwebp 函数库编译 )
文章目录 一. libwebp 源码下载 二. libwebp 源码编译脚本修改 三. libwebp 函数库编译 四.参考资料 一. libwebp 源码下载 Google 提供了一系列的 WebP ...
- 将STM32的标准库编译成lib
转载自:http://www.cnblogs.com/zyqgold/p/3189719.html 以前一直使用STM32的标准库,需要一步步地将代码加进去,将编译选项设置好,然后再编译整个工程. 这 ...
- linux 安装库 编译提示-lcrypto 无法链接,缺少 crypto 库
linux 安装库 缺少 crypto 库 编译提示-lcrypto 无法链接,缺少 crypto 库 方法一 ------------------------------------- crypto ...
- 如何将内核静态库编译连接到驱动程序中去【转】
转自:http://blog.csdn.net/ganjianfeng2003/article/details/8089551 如何将内核静态库编译连接到驱动程序中去 2010-12-07 08:27 ...
- buildroot自带程序(库)编译并安装
前几天情绪有点低落,经过周末的调整重新恢复状态,谢谢有爱的朋友们留言和点赞,有你们的陪伴我会更加努力,让我们一起开心写程序..... buildroot简介: 引用官方的简述: Buildroot是一 ...
- Boost库编译安装
一.Boost库介绍 Boost库是一个经过千锤百炼.可移植.提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一.Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成 ...
- ubuntu下flann库编译报错处理
ubuntu下flann库编译报错处理 编译flann的时候显示以下报错: CMake Error at src/cpp/CMakeLists.txt:33 (add_library):No SOUR ...
- pthread-win32库编译及使用方法注意事项
"该文引用自 CruiseYoung的:pthread-win32库编译及使用方法注意事项 http://blog.csdn.net/fksec/article/details/415179 ...
最新文章
- android自定义布局的使用!
- thinkphp当前php路径,分析thinkphp常见路径用法分析
- 猛然发现,已经第100篇随笔了
- Php的if自动转换类型,php类型的自动转换
- 【现代机器人学】名词概念的理解
- 学编程怎样入门?这是最有效的学习方法
- 强大好看的dz论坛社区源码手机端
- mtk开机声音与关机声音修改(原创)
- 关于LTE下行导频信号
- 电脑维修的基本原则和方法
- 动环监控系统的监控对象有哪些?动环监控系统作用
- 2019牛客暑期多校训练营(第九场)A——The power of Fibonacci(循环节+中国剩余定理(互质)||广义BM)
- Linux ifconfig命令无效的解决方法
- Java API VIII
- SPA、MPA 的优缺点
- 整理18、19、20年关于《人工智能》的标准和评估规范
- linux毁了所有数据,小心!数据在你不注意的时候居然偷偷损毁了
- 心理测评软件php mysql_中学心理测评软件
- 跟我一起写 Makefile(浅显易懂版)
- 急速扩张的银隆曝出欠款,董明珠的梦想与现实