-------------------------------此文仅做记录-------------------------------------
iOS 音频转换成 MP3格式
1. 工具
解压 lame 库到桌面,然后将下载后的脚本放到 lame 的文件夹内
image.png
build-lame.sh有几处需要修改的地方
#!/bin/sh
CONFIGURE_FLAGS="--disable-shared --disable-frontend"
#选择你需要集成的架构模式,一般真机模式下只需要arm64 armv7s就可以,集成太多的架构会对 ipa 包的大小有影响,后期优化 app 大小还是要分离出不需要的架构模式。
ARCHS="arm64 armv7s x86_64 i386 armv7"
#ARCHS="arm64 armv7s armv7"
# directories
SOURCE=""
#生成的libmp3lame.a文件目录和lame.h文件目录
FAT="fat-lame"
#解压的 lame 目录
SCRATCH="/Users/tongxing/Desktop/lame"
# must be an absolute path
THIN=`pwd`/"thin-lame"
COMPILE="y"
LIPO="y"
if [ "$*" ]
then
if [ "$*" = "lipo" ]
then
# skip compile
COMPILE=
else
ARCHS="$*"
if [ $# -eq 1 ]
then
# skip lipo
LIPO=
fi
fi
fi
if [ "$COMPILE" ]
then
CWD=`pwd`
for ARCH in $ARCHS
do
echo "building $ARCH..."
mkdir -p "$SCRATCH/$ARCH"
cd "$SCRATCH/$ARCH"
if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]
then
PLATFORM="iPhoneSimulator"
if [ "$ARCH" = "x86_64" ]
then
SIMULATOR="-mios-simulator-version-min=7.0"
HOST=x86_64-apple-darwin
else
SIMULATOR="-mios-simulator-version-min=5.0"
HOST=i386-apple-darwin
fi
else
PLATFORM="iPhoneOS"
SIMULATOR=
HOST=arm-apple-darwin
fi
XCRUN_SDK=`echo $PLATFORM | tr '[:upper:]' '[:lower:]'`
CC="xcrun -sdk $XCRUN_SDK clang -arch $ARCH"
#AS="$CWD/$SOURCE/extras/gas-preprocessor.pl $CC"
CFLAGS="-arch $ARCH $SIMULATOR"
if ! xcodebuild -version | grep "Xcode [1-6]\."
then
CFLAGS="$CFLAGS -fembed-bitcode"
fi
CXXFLAGS="$CFLAGS"
LDFLAGS="$CFLAGS"
CC=$CC $CWD/$SOURCE/configure \
$CONFIGURE_FLAGS \
--host=$HOST \
--prefix="$THIN/$ARCH" \
CC="$CC" CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS"
make -j3 install
cd $CWD
done
fi
if [ "$LIPO" ]
then
echo "building fat binaries..."
mkdir -p $FAT/lib
set - $ARCHS
CWD=`pwd`
cd $THIN/$1/lib
for LIB in *.a
do
cd $CWD
lipo -create `find $THIN -name $LIB` -output $FAT/lib/$LIB
done
cd $CWD
cp -rf $THIN/$1/include $FAT
fi
2. 编译
打开终端,进入 lame 目录运行下面命令
./build-lame.sh
接着等待终端编译完成,就可以在 lame 目录的 fat-lame里看到编译后的.a文件和.h文件
3. 使用
将 libmpslame.a 文件和 lame.h 文件直接拖到工程文件中
image.png
这里提供一个将 .wav 文件转换成 .mp3文件的方法
+(NSString *)stransformToMp3ByUrlWithUrl:(NSString *)docPath{
NSError *error;
NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSFileManager *fm = [NSFileManager defaultManager];
if (YES != [fm fileExistsAtPath:path]) {
if (YES != [fm createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]) {
PCDLog(@"create dir path=%@, error=%@", path, error);
}
}
NSString *prefix = [docPath stringByDeletingPathExtension];
NSString *mp3FileName = [prefix stringByAppendingPathExtension:@"mp3"];
#8000是电话的采样率,基本可以满足
int mSampleRate = 8000.0;
if ([[NSFileManager defaultManager] fileExistsAtPath:mp3FileName]) {
//删除
NSError *error = nil;
[[NSFileManager defaultManager] removeItemAtPath:mp3FileName error:&error];
}
@try {
int read, write;
FILE *pcm = fopen([docPath cStringUsingEncoding:1], "rb"); //source 被转换的音频文件位置
//音频不能为空
if (!pcm) {
return nil;
}
fseek(pcm, 4*1024, SEEK_CUR); //skip file header
FILE *mp3 = fopen([mp3FileName cStringUsingEncoding:1], "wb"); //output 输出生成的Mp3文件位置
const int PCM_SIZE = 8192;
const int MP3_SIZE = 8192;
short int pcm_buffer[PCM_SIZE*2];
unsigned char mp3_buffer[MP3_SIZE];
lame_t lame = lame_init();
/*这边设置的参数需要与录音时设置的参数做对照,否则压缩会出现问题
asbd.mSampleRate = 8000; //采样率
asbd.mFormatID = kAudioFormatLinearPCM;
asbd.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
asbd.mChannelsPerFrame = 1; //单声道
asbd.mFramesPerPacket = 1; //每一个packet一侦数据
asbd.mBitsPerChannel = 16; //每个采样点16bit量化
asbd.mBytesPerFrame = (asbd.mBitsPerChannel / 8) * asbd.mChannelsPerFrame;
asbd.mBytesPerPacket = asbd.mBytesPerFrame ;
*/
lame_set_num_channels(lame,1); // 单声道
//!!!:经过测试,这里设置采样率为录音时的采样率的一半为最佳音效
lame_set_in_samplerate(lame, mSampleRate); //8000 // 采样率
lame_set_VBR(lame, vbr_default);
lame_set_brate(lame, 16); //压缩的比特率为16K
lame_set_mode(lame, 2); // 四种类型的声道
lame_set_quality(lame, 5);// 2=high 5 = medium 7=low 音 质
lame_init_params(lame);
do {
read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
if (read == 0)
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
else
/**
采用lame_encode_buffer_interleaved函数进行压缩
@param lame_global_flags 全局变量lame
@param const short int buffer_l [] short类型的录音数据,这里表示的是左声道
@param const short int buffer_r [] short类型的录音数据,这里表示的是右声道
@param int num_samples 声道类型
@param unsigned char* mp3buf 存放压缩完后数据的缓冲区,注意是unsigned char
@param int mp3buf_size 缓冲区的长度
@return N/A
*/
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
fwrite(mp3_buffer, write, 1, mp3);
} while (read != 0);
lame_close(lame);
fclose(mp3);
fclose(pcm);
}
@catch (NSException *exception) {
PCDLog(@"%@",[exception description]);
}
@finally {
PCDLog(@"MP3生成成功: %@",mp3FileName);
}
return mp3FileName;
}