swift 录制多个音频 并将音频转换为mp3 并合成多个mp3文件为一个文件

我的需求是可以录制多个文件,最后生成的文件格式为mp3形式,查了下各种资料,因为swift无法直接将音频录制为mp3格式,所以最后我采取的解决方案为先将每个单独的文件转为mp3,最后逐一合并形成一个mp3文件

首先第一步录制 简单说明下:

  参考:  http://www.jianshu.com/p/09af208a5663(感谢) http://www.hangge.com/blog/cache/detail_772.html(感谢)

  1. 音频配置,我尝试了下尽可能多加各种配置最后有问题,测试成功的配置如下  

 recorderSeetingsDic: [String: Any] = [
        AVSampleRateKey: NSNumber(value: 16000),//采样率
        AVFormatIDKey: NSNumber(value: kAudioFormatLinearPCM),//音频格式
        AVNumberOfChannelsKey: NSNumber(value: 2),//通道数
        AVEncoderAudioQualityKey: NSNumber(value: AVAudioQuality.min.rawValue)//录音质量
 ]

  2,录制实现(部分代码)

//音频路径
let audioPath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first?.appending("/test.caf"))!

  

let session:AVAudioSession = AVAudioSession.sharedInstance()

try! session.setCategory(AVAudioSessionCategoryPlayAndRecord)

try! session.setActive(true)

do {
                recorder = try AVAudioRecorder(url: URL(string: audioPath)!, settings: recorderSeetingsDic)

                //开启仪表计数功能
                recorder!.isMeteringEnabled = true
                //准备录音
                recorder!.prepareToRecord()

                recorder?.record()
            } catch let err {
                print("录音失败:\(err.localizedDescription)")
}

  第二步将录制的多个caf格式音频转为一个mp3文件,(最初采用的方式是将多个.caf文件合成为m4a文件的 但是找不到m4a转为mp3的解决方法,用lame也行不通,很郁闷)

  1.首先要编译lame 这是将.caf转为mp3第一步,有很多可以参考的方式

    我参考的编译方式:http://blog.csdn.net/cating1314/article/details/46046497(感谢)

    我们需要编译过后的libmp3lame.a与lame.h两个文件,都在编译过后的thin-lame与fat-lame文件中。根据自己的需求选取,我采用的是fat-lame中的两个文件

    不想编译的话可以采用我的,应该也不会有啥问题 https://pan.baidu.com/s/1dFepCIl 提取密码:reck

  2转换以及合成方法 (转换与合成均采用OC写的)

  参考: https://github.com/CharmingLee/RecordingDemo(感谢)

  定义了两个文件convertMp3.h与convertMp3.m

  convertMp3.h文件

  

#import <UIKit/UIKit.h>

@interface convertMp3: NSObject

- (void) audioPCMtoMP3:(NSString *)audioFileSavePath mp3File:(NSString *)mp3FilePath mergeFile:(NSString *)mergeFilePath;

@end

  convertMp3.m文件

#import "convertMp3.h"
#import "lame.h"

#define KFILESIZE (1 * 1024 * 1024)

@interface convertMp3()

@end

@implementation convertMp3

- (void)audioPCMtoMP3 :(NSString *)audioFileSavePath mp3File:(NSString *)mp3FilePath mergeFile:(NSString *)mergeFilePath
{

    @try {
        int read, write;

        FILE *pcm = fopen([audioFileSavePath cStringUsingEncoding:1], "rb");  //source 被转换的音频文件位置
        fseek(pcm, 4*1024, SEEK_CUR);                                   //skip file header
        FILE *mp3 = fopen([mp3FilePath 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();
        lame_set_in_samplerate(lame, 16000);
        lame_set_VBR(lame, vbr_off);
        lame_init_params(lame);

        do {
            read = (int)fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);

            if (read == 0)
                write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
            else
                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) {
        NSLog(@"%@",[exception description]);
    }
    @finally {
        //从第二个文件才开始合并 第一个文件mergeFilePath与mp3FilePath相同 即第一个转换后的文件地址就是最终合成的完整的mp3文件地址
        if([mergeFilePath isEqualToString:mp3FilePath] == NO) {
            [self pieceFileA:mergeFilePath withFileB:mp3FilePath];
        }
    }

}

- (BOOL)pieceFileA:(NSString *)filePathA withFileB:(NSString *)filePathB {
    //合成过后的文件路径 之后不管多少文件 都是在这个filePathA文件之后继续写入的
    NSString *synthesisFilePath = filePathA;

    // 更新的方式读取文件A
    NSFileHandle *handleA = [NSFileHandle fileHandleForUpdatingAtPath:synthesisFilePath];
    [handleA seekToEndOfFile];

    NSDictionary *fileBDic =
    [[NSFileManager defaultManager] attributesOfItemAtPath:filePathB
                                                     error:nil];
    long long fileSizeB = fileBDic.fileSize;

    // 大于xM分片拼接xM
    if (fileSizeB > KFILESIZE) {

        // 分片
        long long pieces = fileSizeB / KFILESIZE; // 整片
        long long let = fileSizeB % KFILESIZE;    // 剩余片

        long long sizes = pieces;
        // 有余数
        if (let > 0) {
            // 加多一片
            sizes += 1;
        }

        NSFileHandle *handleB = [NSFileHandle fileHandleForReadingAtPath:filePathB];
        for (int i = 0; i < sizes; i++) {

            [handleB seekToFileOffset:i * KFILESIZE];
            NSData *tmp = [handleB readDataOfLength:KFILESIZE];
            [handleA writeData:tmp];
        }

        [handleB synchronizeFile];

        // 大于xM分片读xM(最后一片可能小于xM)
    } else {

        [handleA writeData:[NSData dataWithContentsOfFile:filePathB]];
    }

    [handleA synchronizeFile];
     NSLog(@"合并完成");
    // 将B文件删除
    //    [[NSFileManager defaultManager] removeItemAtPath:filePathB error:nil];

    return YES;
}

@end

  在桥接文件中加入头文件 #import "convertMp3.h"

  3.调用OC文件开始合并

 

//合并
    func transferAudio(num: Int) {

        let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! as NSURL
        let stringDate = BaseController().getCurrentTimeMillisecond()
        let mp3Path: URL = (documentDirectoryURL.appendingPathComponent(BaseController().randomMD5(str: stringDate) + ".mp3")! as URL as NSURL) as URL!

        if num == 0 {
            self.audioPath = mp3Path.path
        }

        convertMp3().audioPCMtoMP3(self.audioLocalUrls[num],mp3File: mp3Path.path,mergeFile: self.audioPath)

        if num == self.audioLocalUrls.count - 1{
            self.uploadAudio()//上传
        }else{
            let order = num + 1
            transferAudio(num: order)
        }
    }

 调用transferAudio(num:0) 开始一个一个caf文件转换合并 这样流程走通了  录制多个caf文件 逐个将其转为mp3 在合并为一个完整mp3文件,刚接触swift没多长时间 东拼西凑实现的功能 如果有哪里不对 希望及时告诉我  谢谢,希望对其它有次需求的人有个参考,毕竟折磨我很长时间

  

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #e44448 }
span.s1 { color: #d28f5a }
span.s2 { }

时间: 2024-10-29 23:33:26

swift 录制多个音频 并将音频转换为mp3 并合成多个mp3文件为一个文件的相关文章

RDP协议集、音频输出、音频输入重定向虚拟通道

一.RDP协议集及子协议之间如何交互 由于目前Windows Server的版本已经进入到了2016版,因此在本文中,终端服务一律称为其最新名称:远程桌面服务(RDS). 以下组件对于了解远程桌面服务协议至关重要: RDP客户端:支持远程桌面服务协议的客户端称为RDP客户端,因为客户端安装了支持远程处理的软件组件.使用此RDP客户端,用户连接到RD会话主机服务器以登录到远程桌面计算机或远程应用程序. 远程桌面会话主机(RD会话主机):RDP客户端与之通信的服务器称为远程桌面会话主机(RD会话主机

Android音频系统之音频框架(转http://blog.csdn.net/uiop78uiop78/article/details/8796492)

1.1 音频框架 转载请注明,From LXS, http://blog.csdn.net/uiop78uiop78/article/details/8796492 Android的音频系统在很长一段时间内都是外界诟病的焦点.的确,早期的Android系统在音频处理上相比于IOS有一定的差距,这也是很多专业的 音乐播放软件开发商没有推出Android平台产品的一个重要原因.但这并不代表它的音频框架一无是处,相反,基于Linux系统的Android平台有 很多值得我们学习的地方. 1.1.1 Li

iOS 9音频应用播放音频之控制播放速度

iOS 9音频应用播放音频之控制播放速度 iOS 9音频控制播放速度 iOS9音频文件在播放时是以一定的速度进行的.这个速度是可以进行更改的,从而实现iOS9音频文件的快速播放和慢速播放功能.要实现iOS9播放速度的更改需要使用AVAudioPlayer类中的rate属性实现.其语法形式如下: var rate: Float 其中,该属性设置的值为浮点类型,范围在0.5到2.0之间.如果该属性的值设置为1.0表示正常播放,它也是默认值.2.0表示以最快的速度进行播放,0.5表示以最慢的速度进行播

iOS 9音频应用播放音频之播放控制暂停停止前进后退的设置

iOS 9音频应用播放音频之播放控制暂停停止前进后退的设置 ios9音频应用播放控制 在“iOS 9音频应用播放音频之ios9音频基本功能”一文可以看到AVAudioPlayer类有很多的属性以及方法.本节将AVAudioPlayer类中常使用到的属性和方法进行详细的讲解. ios9音频应用暂停/停止 在音乐应用程序中都会有一个使音乐停止播放的按钮.当用户轻拍该按钮,正在播放的音乐就会停止.在iOS要想要正在播放的音频停止下来,可以使用AVAudioPlayer类中的pause()方法和stop

iOS 9音频应用播放音频之第一个ios9音频实例2

iOS 9音频应用播放音频之第一个ios9音频实例2 ios9音频应用关联 iOS9音频应用中对于在主视图上添加的视图或控件,在使用它们时必须要与插座变量进行关联.ios9插座变量其实就是为主视图中的视图或者控件起的别名,类似于实例化的对象.将主ios9视图中的Play Button按钮控件与插座变量playButton进行关联.具体的操作步骤如下: (1)使用设置编辑器的三个视图方式的图标,如图2.14所示,将Xcode的界面调整为如图2.15所示的效果. 图2.14  编辑器的三个视图方式的

Java 获取amr音频格式的音频长度

import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; public class GetAmrDuration { /** * 得到amr的时长 * * @param file * @return * @throws IOException */ public static int getAmrDuration(File file) throws IOException { long du

iOS 9音频应用播放音频之ios9音频基本功能

iOS 9音频应用播放音频之ios9音频基本功能 在iOS 9音频应用开发中最为简单和常用的就是AVFoundation框架中的AVAudioPlayer类.虽然AVAudioPlayer类不能播放网络上的音频文件,但是它可以播放本地音频文件,以及缓冲区的文件.本章将讲解最为基础的音频播放--本地音频文件的播放. iOS 9音频应用开发基本功能 实现音频的播放需要使用到AVAudioPlayer类.AVAudioPlayer是AVFoundation.framework框架里面最基本的一个音频播

Android音频系统之音频框架

http://blog.csdn.net/xuesen_lin/article/details/8796492 我们可以结合目前已有的知识,想一下每一个层次都会包含哪些模块(先不考虑蓝牙音频部分)? ·        APP 这是整个音频体系的最上层,因而并不是Android系统实现的重点.比如厂商根据特定需求自己写的一个音乐播放器,游戏中使用到声音,或者调节音频的一类软件等等. ·        Framework 相信大家可以马上想到MediaPlayer和MediaRecorder,因为这

音频处理 (一) 音频文件

音频文件 音频文件是对声音进行数字转换之后存放的数据文件,了解音频数据必须先知道几个重要概念. 1. 采样:对声音信息录入时,行进的最小操作单位,一般一次采样具有左右2个声道,每个声道用1或2个字节来存储: 这样采样的量化位数是8位,或16位(样本位宽),量化位数越高声音音质越好:就像11位电话号码表示的号码比7位要多得多: 2. 采样频率:每秒采样次数,单位Hz,一般的音频文件有11.025kHz.22.05kHz.44.10kHz等:显然,这种模-数信息的转换,每秒采样次数越多,声音就越精确