在iOS设备中进行录音,录音文件的格式为wav。但这种格式文件会很大,上传到服务器会消耗大量流量。为了适应终端的播放功能以及文件大小的要求,特将wav转换为mp3格式文件来使用。

注意:
在录制wav文件时,需要使用双通道,否则在转换为MP3格式时,声音不对。

首先,下载lame源码:http://sourceforge.net/projects/lame/files/lame/3.99/,怎么编译可以查看这篇文章。编译完成后,将fat-lame文件夹下的lame.h和libmp3lame.a文件导入项目中。如图:

我们打开物流唐山app,点击首页地图下的发布按钮,在弹出的录音界面中,当我们点击"按住说话"按钮 ,将会开始录音。

录音说明:

1.当录音时间小于2.5s的时候,将会弹出说话时间太短对话框,录音将会取消。

2.当点击按钮,但是在按钮外部松开的时候,录音也将会取消。

3.只有当手指在按钮内部松开,并且录音时间大于2.5s的时候,录音有效,保存为wav格式文件。

所以我们需要添加三个Target,添加按钮的代码如下:

// 说话按钮
UIImage *sayButtonImage = [UIImage imageNamed:@"完成_07"];
self.sayButton = [[UIButton alloc] initWithFrame:CGRectMake((ScreenW - sayButtonImage.size.width) / 2, ScreenH - 60 - sayButtonImage.size.height, sayButtonImage.size.width,sayButtonImage.size.height)];
[self.sayButton setImage:sayButtonImage forState:UIControlStateNormal];
[self.sayButton addTarget:self action:@selector(touchDown) forControlEvents:UIControlEventTouchDown];
[self.sayButton addTarget:self action:@selector(touchUpInside) forControlEvents:UIControlEventTouchUpInside];
[self.sayButton addTarget:self action:@selector(touchOutside) forControlEvents:UIControlEventTouchUpOutside];
[self addSubview:self.sayButton];

接下来就是使用AVAudioRecorder进行录音:

- (void)startRecorder
{//根据当前时间生成文件名NSString *recordFileName = [VoiceConverter getCurrentTimeString];//获取路径self.recordFilePath = [VoiceConverter getPathFromFileName:recordFileName ofType:@"wav"];//初始化录音self.recorder = [[AVAudioRecorder alloc] initWithURL:[NSURL fileURLWithPath:self.recordFilePath] settings:[VoiceConverter GetAudioRecorderSettingDict] error:nil];self.recorder.delegate = self;//准备录音if ([self.recorder prepareToRecord]){[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryRecord error:nil];[[AVAudioSession sharedInstance] setActive:YES error:nil];[self.recorder record];}
}

录音完成会调用 - ( void )audioRecorderDidFinishRecording:( AVAudioRecorder *)recorder successfully:( BOOL )flag;我们可以在这个函数里边将录音文件转换为mp3文件

#pragma mark - 录音结束返回的信息
- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{NSFileManager *manager = [[NSFileManager alloc] init];if (![manager fileExistsAtPath:self.recordFilePath]) {return;// 如果文件不存在自己返回}// 获取转换后的mp3文件路径NSString *mp3FilePath = [VoiceConverter getPathFromFileName:@"lvRecord1" ofType:@"mp3"];if ([VoiceConverter ConvertWavToMp3:self.recordFilePath mp3SavePath:mp3FilePath]) {[manager removeItemAtPath:self.recordFilePath error:NULL];// 删除录音文件}TSLPutAudioView *putView = [[TSLPutAudioView alloc] init];putView.filePath = mp3FilePath;[putView show];
}

在上面两个函数中,都出现了 VoiceConverter这个类,这是我自己定义的一个工具类,用于配置录音以及将wav转换为mp3。以下是其代码:

VoiceConverter.h

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>@interface VoiceConverter : NSObject/***  转换wav到mp3**  @param aWavPath  wav文件路径*  @param aSavePath mp3保存路径**  @return 0失败 1成功*/
+ (int)ConvertWavToMp3:(NSString *)aWavPath mp3SavePath:(NSString *)aSavePath;
/**获取录音设置.建议使用此设置,如有修改,则转换amr时也要对应修改参数,比较麻烦@returns 录音设置*/
+ (NSDictionary*)GetAudioRecorderSettingDict;/***  获取缓存路径**  @return 缓存路径*/
+ (NSString *)getCacheDirectory;/***  生成当前时间字符串*/
+ (NSString *)getCurrentTimeString;
/***  通过名字及类型获得文件路径**  @param fileName 文件名*  @param type     文件类型**  @return 文件路径*/
+ (NSString *)getPathFromFileName:(NSString *)fileName ofType:(NSString *)type;
@end

VoiceConverter.mm

#import "VoiceConverter.h"
#import "lame.h"@implementation VoiceConverter//获取录音设置
+ (NSDictionary*)GetAudioRecorderSettingDict{NSDictionary *recordSetting = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithFloat: 8000.0],AVSampleRateKey, //采样率[NSNumber numberWithInt: kAudioFormatLinearPCM],AVFormatIDKey,[NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,//采样位数 默认 16[NSNumber numberWithInt: 2], AVNumberOfChannelsKey,//通道的数目//                                   [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,//大端还是小端 是内存的组织方式//                                   [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,//采样信号是整数还是浮点数//                                   [NSNumber numberWithInt: AVAudioQualityMedium],AVEncoderAudioQualityKey,//音频编码质量nil];return recordSetting;
}+ (int)ConvertWavToMp3:(NSString *)aWavPath mp3SavePath:(NSString *)aSavePath
{int state = 0;@try {int read, write;FILE *pcm = fopen([aWavPath cStringUsingEncoding:NSASCIIStringEncoding], "rb");  //sourcefseek(pcm, 4*1024, SEEK_CUR);                                   //skip file headerFILE *mp3 = fopen([aSavePath cStringUsingEncoding:NSASCIIStringEncoding], "wb");  //outputconst 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_num_channels(lame, 2); // 双声道lame_set_in_samplerate(lame, 8000); // 8k采样率lame_set_brate(lame, 16);  // 压缩的比特率为16lame_set_quality(lame, 2);  // mp3音质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);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);state = 1;}@catch (NSException *exception) {state = 0;}@finally {return state;}
}#pragma mark - 通过名字及类型获得文件路径
/***  通过名字及类型获得文件路径**  @param fileName 文件名*  @param type     文件类型**  @return 文件路径*/
+ (NSString *)getPathFromFileName:(NSString *)fileName ofType:(NSString *)type
{NSString *filePath = [[[self getCacheDirectory]stringByAppendingPathComponent:fileName]stringByAppendingPathExtension:type];NSFileManager *filemanager = [[NSFileManager alloc]init];if ([filemanager fileExistsAtPath:filePath]){ // 如果文件已存在,删除文件[filemanager removeItemAtPath:filePath error:NULL];}return filePath;
}#pragma mark - 获得缓存路径
/***  获取缓存路径**  @return 缓存路径*/
+ (NSString *)getCacheDirectory
{NSString *cache = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];NSString *voicePath = [cache stringByAppendingPathComponent:@"Voice"];NSFileManager *filemanager = [[NSFileManager alloc]init];if (![filemanager fileExistsAtPath:voicePath]){[filemanager createDirectoryAtPath:voicePath withIntermediateDirectories:YES attributes:nil error:NULL];}return voicePath;
}#pragma mark - 生成当前时间字符串
+ (NSString *)getCurrentTimeString{NSDateFormatter *dateformat = [[NSDateFormatter  alloc]init];[dateformat setDateFormat:@"yyyyMMddHHmmss"];return [dateformat stringFromDate:[NSDate date]];
}@end

说明:

+ (NSDictionary*)GetAudioRecorderSettingDict;//该函数返回录音设置参数
+ (int)ConvertWavToMp3:(NSString *)aWavPath mp3SavePath:(NSString *)aSavePath;//该函数将wav文件转换为mp3文件

由于在VoiceConverter.mm文件中使用了第三方静态库,所以VoiceConverter.mm后缀是mm,用于混合编译。

录音完成以后,会弹出提交录音对话框:

使用AFNetworking将录音文件提交到服务器即可。

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:@"http://www.560315.com/MobileAPI/AudioAdd" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {[formData appendPartWithFileData:[NSDatadataWithContentsOfFile:self.filePath] name:@"upname" fileName:[self.filePathlastPathComponent] mimeType:@"audio/mp3"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {// 上传成功
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];

未完待续。。。

04.iOS 使用lame将wav转换为mp3相关推荐

  1. mp3如何转换为wav_将WAV转换为MP3或MP3转换为WAV

    mp3如何转换为wav Boy I would have loved this post a decade ago when I was ripping CDs from my local libra ...

  2. java+lame实现wav到mp3的转换

    lame以及lame命令参数设置请大家自行搜索,这里给大家一个例子,java+lame实现压缩wav to mp3. 注意:lame.exe与java工程src放在同一文件夹,否则请使用绝对路径调用l ...

  3. mp3转换wav文件_如何将WAV文件转换为MP3

    mp3转换wav文件 WAV audio files are a great way to preserve the complete and accurate quality of a record ...

  4. air中wav转mp3

    格式: lame 输入文件  转出文件 这是转换时打印出来的信息,我们能发现里面包含了进度信息,只需要解析该信息就可得到进度信息,解析的正则表达式为://((/s?)(/d+)%/)/|/gi,结果为 ...

  5. lame,把ios录音转换为mp3格式

    在ios设备中进行录音,录音文件的格式为caf.但这种格式在很多设备中没法播放.为了适应终端的播放功能,特将caf转换为mp3格式文件来使用. 在录制caf文件时,需要使用双通道,否则在转换为MP3格 ...

  6. mplayer配置文件_使用MPlayer和Lame将电影文件转换为wav和mp3文件

    mplayer配置文件 (1) convert .avi, .wmv etc. to .wav: (1) 将 .avi,.wmv等转换为.wav: mplayer -ao pcm:file=%7%ou ...

  7. iOS 使用lame录音文件wav转mp3

    LAME 是最好的MP3编码器,编码高品质MP3的最好也是唯一的选择.要编译lame 静态库,可以按一下步骤完成: 1.到点击打开链接 下载最新的lame mp3 encoder, 2.到github ...

  8. Android AudioRecord录制PCM以及转换为wav和mp3

    Android AudioRecord录制PCM以及转换为wav和mp3 1.录制pcm pcm介绍 pcm是指音频裸数据是脉冲编码调制数据.描述一段PCM数据通常以下几个概念: 量化格式(Sampl ...

  9. android lame wav 转 mp3,Android JNI Lame编解码实现wav到MP3的转换

    1.JNI简介 JNI全称为Java Native Interface(JAVA本地调用).从Java1.1开始,JNI成为java平台的一部分,它允许Java代码和其他语言写的代码(如C&C ...

最新文章

  1. RewriteCond和13个mod_rewrite应用举例Apache伪静态
  2. springboot 访问httpclient接口
  3. Errors are values
  4. hibernate.connection.release_mode
  5. P3197 [HNOI2008]越狱(快速幂)
  6. 吉吉影音官网版 v2.7.2.8_p2p播放器​
  7. Delphi使用ReportMachine制作小计和总计报表
  8. 北京内推 | 微软亚洲研究院视觉计算组招聘研究与开发实习生
  9. 差速轮和舵轮的纯跟踪算法
  10. 真励志!从月薪2300深圳流水线女工,逆袭为年薪80万谷歌工程师,又因疫情失业:我绝不轻易认输...
  11. 漏洞复现----11、GlassFish任意文件读取
  12. deny后加to do还是doing_区别的to do和doing用法的小技巧
  13. factory-method
  14. 百度竞价推广是什么?信息流推广以及网盟推广是什么?
  15. java 彩票走势图算法
  16. Vivado2016如何改变字体大小
  17. Mac 安装depot_tools
  18. 记录下今天的搜索成果
  19. 解决Abaqus有限元分析不收敛的6条建议
  20. 西部数码网站管理助手 mysql_西部数码网站管理助手v3.0 建站流程

热门文章

  1. python写入文件后读取空白,写入文件无法读取解决方案
  2. 管道专用现场金相检测仪
  3. vue 富文本编辑器 quill (含代码高亮、自定义字体、汉化、鼠标悬浮提示、组件封装等)
  4. 如何实现 WPF 视频封面查看器
  5. JS字符串分割转为树结构参考
  6. 【2021流量主】365王者打卡前后台源码
  7. 优启通制作系统u盘_优启通(U盘启动制作程序)
  8. ModbusRTU之CRC校验
  9. 如果列出10以内自然数中3或5的倍数,则包括3,5,6,9。那么这些数字的和为23。要求计算得出任意正整数n以内中3或5的倍数的自然数之和。
  10. Windows批处理设置自动获取IP及DNS或固定IP及DNS