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;
    
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容