-------------------------------此文僅做記錄-------------------------------------
iOS 音頻轉(zhuǎn)換成 MP3格式
1. 工具
解壓 lame 庫到桌面,然后將下載后的腳本放到 lame 的文件夾內(nèi)
build-lame.sh有幾處需要修改的地方
#!/bin/sh
CONFIGURE_FLAGS="--disable-shared --disable-frontend"
#選擇你需要集成的架構(gòu)模式裳瘪,一般真機(jī)模式下只需要arm64 armv7s就可以,集成太多的架構(gòu)會對 ipa 包的大小有影響,后期優(yōu)化 app 大小還是要分離出不需要的架構(gòu)模式。
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. 編譯
打開終端泳叠,進(jìn)入 lame 目錄運(yùn)行下面命令
./build-lame.sh
接著等待終端編譯完成,就可以在 lame 目錄的 fat-lame里看到編譯后的.a文件和.h文件
3. 使用
將 libmpslame.a 文件和 lame.h 文件直接拖到工程文件中
這里提供一個將 .wav 文件轉(zhuǎn)換成 .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 被轉(zhuǎn)換的音頻文件位置
//音頻不能為空
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();
/*這邊設(shè)置的參數(shù)需要與錄音時設(shè)置的參數(shù)做對照内列,否則壓縮會出現(xiàn)問題
asbd.mSampleRate = 8000; //采樣率
asbd.mFormatID = kAudioFormatLinearPCM;
asbd.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
asbd.mChannelsPerFrame = 1; //單聲道
asbd.mFramesPerPacket = 1; //每一個packet一偵數(shù)據(jù)
asbd.mBitsPerChannel = 16; //每個采樣點(diǎn)16bit量化
asbd.mBytesPerFrame = (asbd.mBitsPerChannel / 8) * asbd.mChannelsPerFrame;
asbd.mBytesPerPacket = asbd.mBytesPerFrame ;
*/
lame_set_num_channels(lame,1); // 單聲道
//!!!:經(jīng)過測試,這里設(shè)置采樣率為錄音時的采樣率的一半為最佳音效
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 音 質(zhì)
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函數(shù)進(jìn)行壓縮
@param lame_global_flags 全局變量lame
@param const short int buffer_l [] short類型的錄音數(shù)據(jù),這里表示的是左聲道
@param const short int buffer_r [] short類型的錄音數(shù)據(jù),這里表示的是右聲道
@param int num_samples 聲道類型
@param unsigned char* mp3buf 存放壓縮完后數(shù)據(jù)的緩沖區(qū)服傍,注意是unsigned char
@param int mp3buf_size 緩沖區(qū)的長度
@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;
}