04.iOS 使用lame将wav转换为mp3
在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相关推荐
- 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 ...
- java+lame实现wav到mp3的转换
lame以及lame命令参数设置请大家自行搜索,这里给大家一个例子,java+lame实现压缩wav to mp3. 注意:lame.exe与java工程src放在同一文件夹,否则请使用绝对路径调用l ...
- mp3转换wav文件_如何将WAV文件转换为MP3
mp3转换wav文件 WAV audio files are a great way to preserve the complete and accurate quality of a record ...
- air中wav转mp3
格式: lame 输入文件 转出文件 这是转换时打印出来的信息,我们能发现里面包含了进度信息,只需要解析该信息就可得到进度信息,解析的正则表达式为://((/s?)(/d+)%/)/|/gi,结果为 ...
- lame,把ios录音转换为mp3格式
在ios设备中进行录音,录音文件的格式为caf.但这种格式在很多设备中没法播放.为了适应终端的播放功能,特将caf转换为mp3格式文件来使用. 在录制caf文件时,需要使用双通道,否则在转换为MP3格 ...
- mplayer配置文件_使用MPlayer和Lame将电影文件转换为wav和mp3文件
mplayer配置文件 (1) convert .avi, .wmv etc. to .wav: (1) 将 .avi,.wmv等转换为.wav: mplayer -ao pcm:file=%7%ou ...
- iOS 使用lame录音文件wav转mp3
LAME 是最好的MP3编码器,编码高品质MP3的最好也是唯一的选择.要编译lame 静态库,可以按一下步骤完成: 1.到点击打开链接 下载最新的lame mp3 encoder, 2.到github ...
- Android AudioRecord录制PCM以及转换为wav和mp3
Android AudioRecord录制PCM以及转换为wav和mp3 1.录制pcm pcm介绍 pcm是指音频裸数据是脉冲编码调制数据.描述一段PCM数据通常以下几个概念: 量化格式(Sampl ...
- android lame wav 转 mp3,Android JNI Lame编解码实现wav到MP3的转换
1.JNI简介 JNI全称为Java Native Interface(JAVA本地调用).从Java1.1开始,JNI成为java平台的一部分,它允许Java代码和其他语言写的代码(如C&C ...
最新文章
- RewriteCond和13个mod_rewrite应用举例Apache伪静态
- springboot 访问httpclient接口
- Errors are values
- hibernate.connection.release_mode
- P3197 [HNOI2008]越狱(快速幂)
- 吉吉影音官网版 v2.7.2.8_p2p播放器​
- Delphi使用ReportMachine制作小计和总计报表
- 北京内推 | 微软亚洲研究院视觉计算组招聘研究与开发实习生
- 差速轮和舵轮的纯跟踪算法
- 真励志!从月薪2300深圳流水线女工,逆袭为年薪80万谷歌工程师,又因疫情失业:我绝不轻易认输...
- 漏洞复现----11、GlassFish任意文件读取
- deny后加to do还是doing_区别的to do和doing用法的小技巧
- factory-method
- 百度竞价推广是什么?信息流推广以及网盟推广是什么?
- java 彩票走势图算法
- Vivado2016如何改变字体大小
- Mac 安装depot_tools
- 记录下今天的搜索成果
- 解决Abaqus有限元分析不收敛的6条建议
- 西部数码网站管理助手 mysql_西部数码网站管理助手v3.0 建站流程
热门文章
- python写入文件后读取空白,写入文件无法读取解决方案
- 管道专用现场金相检测仪
- vue 富文本编辑器 quill (含代码高亮、自定义字体、汉化、鼠标悬浮提示、组件封装等)
- 如何实现 WPF 视频封面查看器
- JS字符串分割转为树结构参考
- 【2021流量主】365王者打卡前后台源码
- 优启通制作系统u盘_优启通(U盘启动制作程序)
- ModbusRTU之CRC校验
- 如果列出10以内自然数中3或5的倍数,则包括3,5,6,9。那么这些数字的和为23。要求计算得出任意正整数n以内中3或5的倍数的自然数之和。
- Windows批处理设置自动获取IP及DNS或固定IP及DNS