swift 录音 AVAudioRecorder
距离上次写博客已经好久好久了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相关推荐
- iOS音频开发相关(二)录音 `AVAudioRecorder`
录音 AVAudioRecorder 初始化方法 AVFormatIDKey AVSampleRateKey AVNumberOfChannelsKey linear PCM keys AVLinea ...
- OCiOS开发:录音与音效
录音 AVAudioRecorder是AVFoundation中的类,提供了简单的录音功能. 常用方法 初始化方法 - (id)initWithURL:(NSURL *)url settings:(N ...
- iOS录音和音频播放
文章目录 简介 `AVAudioRecorder`录音 `AVAudioPlayer`播放音频文件. 简介 最近公司研发了一个语音识别的框架,但这个框架是后端识别,所以需要手机端录音,录音后将音频文件 ...
- Swift实现iOS录音与播放音频功能
Swift实现iOS录音与播放音频功能 作用 AVPLayer:可以用来播放在线及本地音视频 AVAudioSession:音频会话,主要用来管理音频设置与硬件交互 使用时需要导入 #import & ...
- 基于Swift的iOS应用程序开发:录音及播放声音
本文所涉及内容适合在SwiftUI架构下使用.文末提供有完整的封装好的类. 欢迎给我留言,或是写邮件给我: randolph.carter.xu@gmail.com 28300098@qq.com 一 ...
- AVAudioRecorder 录音
苹果提供了AVAudioRecorder类来让我们进行音频录制,是录音变的非常的便捷! 在使用AVAudioRecorder进行录音之前要做几样准备工作, ① .在iOS10及以上,调用系统功能需要在 ...
- IPhone之AVAudioRecorder 录音
#import 需要引入 //获取document目录的路径 - (NSString*) documentsPath { if (! _documentsPath) { NSArray *s ...
- Swift自定义表情键盘+录音
老规矩,一图胜千言.Demo 传送门 点我就行 . 运行环境 Xcode10 swift 4.0 前言 这里没有干货,也没有教程,请各位大神手下留情.这个 demo 是平时自己在工作之余学习 swif ...
- 解决使用 AVAudioRecorder 录音保存 .WAV 文件遇到的问题
问题背景 App 实现录音保存音频文件,并实现本地语音识别匹配功能. 通过网络请求上传通过语音匹配的音频文件. 服务器接收到文件并进行语音识别,使用的是第三方微软语音识别,只支持 PCM 数据源的 W ...
最新文章
- MySQL索引类型一览 让MySQL高效运行起来
- java多线程之API初探(一)
- git恢复到上次提交
- Android开源框架——网络解析GSON
- NeurIPS 2020 | FixMatch:通过图像增强就能实现半监督学习
- 分布式文件系统之Tachyon是什么?
- 冠军奖10万日元+10公斤柠檬!一个简单的柠檬图像分级竞赛
- Android开发中使用startActivityForResult()方法从Activity A跳转Activity B出现B退出时A也同时退出的解决办法...
- Linux环境变量配置【转】
- viewHolder的作用
- P3C-PMD自定义规则实战
- excel自动调整列宽_高效使用Excel透视表,必须要注意的十个细节
- Node.js学习笔记--进阶之路
- Fllutter TabBar中文文字抖动完美解决方案
- Unity资源管理图示
- where is java_Linux下的搜索查找命令的详解(whereis)
- oracle数据库的安装及配置方法
- eclipse32位安装教程_Mastercam X6/(32位、64位) 软件安装教程
- 全球及中国ICP-OES光谱仪行业产销需求与投资前景预测报告2022~2027年
- Nutch 分布式运行模式 (v1.14)
热门文章
- ROS小白成长记之---工作空间移植问题
- 电压互感器的基础知识原理及注意事项-安科瑞薛炯毅
- java Object转List
- 基于新生研讨课对地质雷达的一些探究学习
- TensorRT学习第一篇:python 中 TensorRT 使用流程之onnx
- 搭建微信公众号测试环境
- 数据流图的画法,如何画数据流图
- cfm在哪些应用服务器可执行,CFM格式文件 如何打开CFM文件 CFM是什么格式的文件 用什么打开 - The X 在线工具...
- win10系统cmd运行exe文件
- k3梅林单线双拨教程_华硕AC86U单线双拨设置方法。。。