距离上次写博客已经好久好久了ZZZzzzzzzz。

首先交代下用处,做的IM项目,需要语音聊天,研究了下AVAudioRecorder。

其实挺简单的,主要步骤就是 创建一个recorder -> recorder.record() -> recorder.stop()

不多说 上代码

 func createRecord(path: String) {if self.recorder != nil {self.resetRecorder()}let url = URL(fileURLWithPath: path)self.cafPathStr = pathself.mp3PathStr = self.recordFileCaf2Mp3(cafPath: path)let setting = self.recordSetting()do {self.recorder = try AVAudioRecorder(url: url, settings: setting)self.recorder?.delegate = selfself.recorder?.isMeteringEnabled = true} catch {XMPPAudioLog("create recorder error:")}}
    func startRecord(path: String) {guard self.recorder == nil else {EdoAssertionFailure("should reset recorder before start record")return}if self.recorder == nil {self.createRecord(path: path)}guard let _ = self.recorder else {assertionFailure("ChatAudio: recorder could not be nil")return}//if isRecording, should stop firstif let _ = self.recorder?.isRecording {self.recorder?.stop()}//stop all playerself.stopAllMusic()let audioSession = AVAudioSession.sharedInstance()do {try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)if let isRecorder = self.recorder?.isRecording, isRecorder == false {self.recorder?.record()}} catch {}}

这里的 mp3PathStr是转换成MP3格式的路径

这里是一些配置还有大小以及mp3路径的转换方法

 func recordSetting() -> [String: Any] {var recordSetting = [String: Any]()//format of record/****kAudioFormatMPEG4AAC压缩格式能在显著减小文件的同时,保证音频的质量。****/recordSetting[AVFormatIDKey] = NSNumber(value: kAudioFormatLinearPCM)//sampling rate of record/******采样率越高,文件越大,质量越好,反之,文件小,质量相对差一些,但是低于普通的音频,人耳并不能明显的分辨出好坏。最终选取哪一种采样率,由我们的耳朵来判断。建议使用标准的采样率,8000、16000、22050、44100。*****/recordSetting[AVSampleRateKey] = NSNumber(value: 8000)//The quality of recordrecordSetting[AVEncoderAudioQualityKey] = NSNumber(value: AVAudioQuality.high.rawValue)//线性采样位数  8、16、24、32recordSetting[AVLinearPCMBitDepthKey] = NSNumber(value: 8)//录音通道数  1 或 2/****AVNumberOfChannelsKey用于指定记录音频的通道数。1为单声道,2为立体声。***/recordSetting[AVNumberOfChannelsKey] = NSNumber(value: 2)return recordSetting}func fileSizeAtPath(path: String) -> String {if FileManager.default.fileExists(atPath: path) {let attributes = try? FileManager.default.attributesOfItem(atPath: path)if let attrs = attributes, let size = attrs[FileAttributeKey(rawValue:"NSFileSize")] as? Int64 {return ByteCountFormatter.string(fromByteCount: size, countStyle: ByteCountFormatter.CountStyle.file)}}return "0 KB"}func recordFileCaf2Mp3(cafPath: String) -> String {var mp3Path = cafPathif cafPath.hasSuffix(".caf") {mp3Path = cafPath.replacingOccurrences(of: "caf", with: "mp3", options: NSString.CompareOptions.caseInsensitive, range: Range(cafPath.index(cafPath.startIndex, offsetBy: cafPath.count - 3)..<cafPath.endIndex))}return mp3Path}

由于我这边是要做语音聊天,所以每次结束都会把recorder销毁掉

func deleteRecording() {guard let recorder = self.recorder, recorder.isRecording == false else {assertionFailure("ChatAudio: recorder must be stopped")return}self.recorder?.deleteRecording()self.resetRecorder()}func resetRecorder() {self.recorder?.stop()self.recorder = nilself.mp3PathStr = ""self.cafPathStr = ""}

emmmm 好像就这么多了  具体一些缘由 为什么这么写什么的 可以参考一下apple的官方资料

然后就是转MP3

转mp3我是用的lame.h 和 libmp3lame.a 然后遇到一个什么 libmp3lame.a 不支持bitcode什么的问题 于是用以下解决

1.http://sourceforge.net/projects/lame/files/lame/3.99/ 下载lame的最新版本并解压

2.https://github.com/kewlbear/lame-ios-build   下载build的脚本 下载之后得到lame-build.sh拷贝到刚才解压后的文件夹

3.用一些编辑器按照注释修改lame-build.sh 如下图

4.cd 到1解压的目录下 执行脚本 chmod 777 lame-build.sh 等待1分钟左右就编译完成了

5.里边生成fat-lame目录和thin-lame目录,分别存放合并所有指令集的静态库,以及各指令集的静态库. 具体用哪个里边的lame.h和libmp3lame.a 我就忘记了。。。试一下吧。

然后就是转MP3文件了

我查了下资料,前人大部分都是用的OC写的 于是我用了一个OC文件转译了一下

+ (BOOL)audio_PCMtoMP3:(NSString *)cafPath mp3Path:(NSString *)mp3Path {@try {int read, write;FILE *pcm = fopen([cafPath cStringUsingEncoding:1], "rb");  //source 被转换的音频文件位置fseek(pcm, 4*1024, SEEK_CUR);                                   //skip file headerFILE *mp3 = fopen([mp3Path 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();//should be equle with AVSampleRateKeylame_set_in_samplerate(lame, 8000.0);lame_set_VBR(lame, vbr_default);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);elsewrite = 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]);return NO;}@finally {NSLog(@"MP3生成成功: %@",mp3Path);return YES;}
}

注意里边有一句

lame_set_in_samplerate(lame, 8000.0);

这里的8000要与recorder设置里的采样率一致,否则会变声。(我感觉一些app的变音就是这么来的,有兴趣可以试试,开始我设置的采样率是8000,这里写的是44100,然后声音特别细)

就这些了 好像有点乱。。。。睡觉

swift 录音 AVAudioRecorder相关推荐

  1. iOS音频开发相关(二)录音 `AVAudioRecorder`

    录音 AVAudioRecorder 初始化方法 AVFormatIDKey AVSampleRateKey AVNumberOfChannelsKey linear PCM keys AVLinea ...

  2. OCiOS开发:录音与音效

    录音 AVAudioRecorder是AVFoundation中的类,提供了简单的录音功能. 常用方法 初始化方法 - (id)initWithURL:(NSURL *)url settings:(N ...

  3. iOS录音和音频播放

    文章目录 简介 `AVAudioRecorder`录音 `AVAudioPlayer`播放音频文件. 简介 最近公司研发了一个语音识别的框架,但这个框架是后端识别,所以需要手机端录音,录音后将音频文件 ...

  4. Swift实现iOS录音与播放音频功能

    Swift实现iOS录音与播放音频功能 作用 AVPLayer:可以用来播放在线及本地音视频 AVAudioSession:音频会话,主要用来管理音频设置与硬件交互 使用时需要导入 #import & ...

  5. 基于Swift的iOS应用程序开发:录音及播放声音

    本文所涉及内容适合在SwiftUI架构下使用.文末提供有完整的封装好的类. 欢迎给我留言,或是写邮件给我: randolph.carter.xu@gmail.com 28300098@qq.com 一 ...

  6. AVAudioRecorder 录音

    苹果提供了AVAudioRecorder类来让我们进行音频录制,是录音变的非常的便捷! 在使用AVAudioRecorder进行录音之前要做几样准备工作, ① .在iOS10及以上,调用系统功能需要在 ...

  7. IPhone之AVAudioRecorder 录音

    #import   需要引入 //获取document目录的路径 - (NSString*) documentsPath {  if (! _documentsPath) {   NSArray *s ...

  8. Swift自定义表情键盘+录音

    老规矩,一图胜千言.Demo 传送门 点我就行 . 运行环境 Xcode10 swift 4.0 前言 这里没有干货,也没有教程,请各位大神手下留情.这个 demo 是平时自己在工作之余学习 swif ...

  9. 解决使用 AVAudioRecorder 录音保存 .WAV 文件遇到的问题

    问题背景 App 实现录音保存音频文件,并实现本地语音识别匹配功能. 通过网络请求上传通过语音匹配的音频文件. 服务器接收到文件并进行语音识别,使用的是第三方微软语音识别,只支持 PCM 数据源的 W ...

最新文章

  1. MySQL索引类型一览 让MySQL高效运行起来
  2. java多线程之API初探(一)
  3. git恢复到上次提交
  4. Android开源框架——网络解析GSON
  5. NeurIPS 2020 | FixMatch:通过图像增强就能实现半监督学习
  6. 分布式文件系统之Tachyon是什么?
  7. 冠军奖10万日元+10公斤柠檬!一个简单的柠檬图像分级竞赛
  8. Android开发中使用startActivityForResult()方法从Activity A跳转Activity B出现B退出时A也同时退出的解决办法...
  9. Linux环境变量配置【转】
  10. viewHolder的作用
  11. P3C-PMD自定义规则实战
  12. excel自动调整列宽_高效使用Excel透视表,必须要注意的十个细节
  13. Node.js学习笔记--进阶之路
  14. Fllutter TabBar中文文字抖动完美解决方案
  15. Unity资源管理图示
  16. where is java_Linux下的搜索查找命令的详解(whereis)
  17. oracle数据库的安装及配置方法
  18. eclipse32位安装教程_Mastercam X6/(32位、64位) 软件安装教程
  19. 全球及中国ICP-OES光谱仪行业产销需求与投资前景预测报告2022~2027年
  20. Nutch 分布式运行模式 (v1.14)

热门文章

  1. ROS小白成长记之---工作空间移植问题
  2. 电压互感器的基础知识原理及注意事项-安科瑞薛炯毅
  3. java Object转List
  4. 基于新生研讨课对地质雷达的一些探究学习
  5. TensorRT学习第一篇:python 中 TensorRT 使用流程之onnx
  6. 搭建微信公众号测试环境
  7. 数据流图的画法,如何画数据流图
  8. cfm在哪些应用服务器可执行,CFM格式文件 如何打开CFM文件 CFM是什么格式的文件 用什么打开 - The X 在线工具...
  9. win10系统cmd运行exe文件
  10. k3梅林单线双拨教程_华硕AC86U单线双拨设置方法。。。