Mp4V2库编译及使用
来源:互联网 发布:精益数据分析 微盘 编辑:程序博客网 时间:2024/05/16 09:39
需求:想用Mp4V2 库将H264流录成MP4文件
反复折腾了好一下子,才整出来,再次纪录下。
具体实现:
1、下载Mp4v2源码
google code下载地址:http://code.google.com/p/mp4v2/downloads/list,若打不开链接,可以去github里搜索,本人也将其打包全部上传到github。
2、编译IOS上平台上合并库。
编译脚本如下(忘记出处了,不好意思):
#!/bin/shIOS_BASE_SDK=8.2SOURCE="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 $THIN rm -rf $FAT}cleanfor ARCH in $ARCHSdo echo "building $ARCH .." if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ] then PLATFORM="iPhoneSimulator" CPU= if [ "$ARCH" = "x86_64" ] then SIMULATOR="-mios-simulator-version-min=7.0" HOST= else SIMULATOR="-mios-simulator-version-min=5.0" HOST="--host=i386-apple-darwin" fi else PLATFORM="iPhoneOS" if [ $ARCH = "armv7s" ] then CPU="--cpu=swift" else CPU= fi SIMULATOR= HOST="--host=arm-apple-darwin" fi DEVROOT=`xcode-select -p`/"Platforms/$PLATFORM.platform/Developer" SDKROOT=$DEVROOT/SDKs/$PLATFORM$IOS_BASE_SDK.sdk CFLAGS="-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" ] then export LD=$DEVROOT/usr/bin/ld export LDFLAGS="-L$SDKROOT/usr/lib/" else export LD=$DEVROOT/usr/bin/ld export AR=$DEVROOT/usr/bin/ar export AS=$DEVROOT/usr/bin/as export NM=$DEVROOT/usr/bin/nm export RANLIB=$DEVROOT/usr/bin/ranlib export LDFLAGS="-L$SDKROOT/usr/lib/" export LIBTOOL=$DEVROOT/usr/bin/libtool export LIPO=$DEVROOT/usr/bin/lipo export OTOOL=$DEVROOT/usr/bin/otool export NMEDIT=$DEVROOT/usr/bin/nmedit export DSYMUTIL=$DEVROOT/usr/bin/dsymutil export STRIP=$DEVROOT/usr/bin/strip fi export CPPFLAGS=$CFLAGS export CXXFLAGS=$CFLAGS make distclean $ROOT/$SOURCE/configure $CONFIGURE_FLAGS $HOST --prefix="$THIN/$ARCH" make make install echo "build $ARCH done.."doneecho "building fat .."mkdir -p "${FAT}/lib"set - $ARCHSCWD=`pwd`cd ${THIN}/$1/libfor LIB in `ls *.a`do echo $LIB cd $CWD xcrun -sdk iphoneos lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIBdonecd $CWDcp -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, // width recordCtx->m_vHeight, // height _naluData[5], // sps[1] AVCProfileIndication _naluData[6], // sps[2] profile_compat _naluData[7], // sps[3] AVCLevelIndication 3); // 4 bytes length before each NAL unit if (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
0 0
- Mp4V2库编译及使用
- VS2010下编译mp4v2及在项目中的使用
- VS2010下编译mp4v2及在项目中的使用
- VS2010下编译mp4v2及在项目中的使用
- 编译MP4v2
- 编译MP4v2
- 编译MP4v2
- android mp4v2的编译和使用
- MP4V2 使用——编译、录制
- MP4V2库与MP4AV库编译
- MP4V2库与MP4AV库编译
- MP4V2库与MP4AV库编译
- iOS如何编译MP4v2静态库
- android 编译mp4v2 2.0.0生成动态库
- android 编译mp4v2 2.0.0生成动态库
- android 编译mp4v2 2.0.0生成动态库
- ios上关于编译MP4v2静态库的问题
- arm版mp4v2-2.0.0链接库编译方法
- 罗马数字--简洁版
- 读书笔记-《程序员生存定律》
- (总结)Nginx配置文件nginx.conf中文详解
- GET和POST在线测试
- 剑指offer之实现Singleton(单例)模式
- Mp4V2库编译及使用
- Activity, Service,Task, Process and Thread之间的关系
- OC内存管理总结
- Jxl读写Excel文件
- 数组的查找,插入元素保证数组有序
- FreeMarker 集合Map遍历
- 罗马数字
- U盘启动引导安装linux
- icon图标下载