iOS 音频转换成 MP3格式

-------------------------------此文仅做记录-------------------------------------


iOS 音频转换成 MP3格式

1. 工具

  1. Lame 库
  2. 编译 lame 库的脚本

解压 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;
    
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容