录音、播放、转码
- 录音
- 播放
- 转成MP3
- base64转码
- caf转码MP3
- 调用
- 分享心得:
录音
#import <AVFoundation/AVFoundation.h>
#import "lame.h"
@interface RecorderTestController ()<AVAudioRecorderDelegate,AVAudioPlayerDelegate>
{
AVAudioPlayer * player;
}
@property (nonatomic,strong) AVAudioRecorder * audioRecorder;
开始录音,下面这部分代码可以直接复制使用
-(void)startRecordcase{
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"testRecorder.WAV"]]) {
[fileManager removeItemAtPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"testRecorder.WAV"] error:nil];
}
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:8000] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityMax] forKey:AVEncoderAudioQualityKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsNonInterleaved];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
NSURL * recordUrl = [NSURL URLWithString:[NSTemporaryDirectory()stringByAppendingPathComponent:@"testRecorder.WAV"]];
NSError * error;
self.audioRecorder = [[AVAudioRecorder alloc] initWithURL:recordUrl settings:recordSetting error:&error];
if (error) {
NSLog(@"%@",error.description);
return;
}
self.audioRecorder.delegate = self;
self.audioRecorder.meteringEnabled = YES;
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
if (![self.audioRecorder isRecording]) {
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession setActive:YES error:nil];
[self.audioRecorder prepareToRecord];
[self.audioRecorder record];
}
}
- (void)endRecord
{
[self.audioRecorder stop];
}
-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
[[AVAudioSession sharedInstance] setActive:NO error:nil];
if (!flag) return;
}
播放
- (void)playWav{
NSData * wavData = [NSData dataWithContentsOfFile:[NSTemporaryDirectory() stringByAppendingPathComponent:@"testRecorder.WAV"]];
NSError * error;
player = [[AVAudioPlayer alloc]initWithData:wavData error:&error];
player.delegate = self;
if (error) {
NSLog(@"语音播放失败,%@",error);
return;
}
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
player.volume = 1.0;
player.pan = -1;
player.rate = 2.0;
player.numberOfLoops = 0;
[player prepareToPlay];
[player play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
if (flag) {
[player stop];
player = nil;
}
}
转成MP3
-(void)convertToMp3SouceFilePathName:(NSString *)sourcePath isDeleteSourchFile:(BOOL)isDelete
{
NSString *inPath = sourcePath;
NSFileManager *fm = [NSFileManager defaultManager];
if (![fm fileExistsAtPath:sourcePath]) {
NSLog(@"文件不存在");
}
NSString *outPath = [[sourcePath stringByDeletingPathExtension] stringByAppendingString:@".MP3"];
@try {
int read, write;
FILE *pcm = fopen([inPath cStringUsingEncoding:1], "rb");
fseek(pcm, 4*1024, SEEK_CUR);
FILE *mp3 = fopen([outPath cStringUsingEncoding:1], "wb");
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, 8000);
lame_set_num_channels(lame, 2);
lame_set_quality(lame, 0);
lame_set_VBR(lame, vbr_default);
lame_set_brate(lame, 8);
lame_init_params(lame);
do {
size_t size = (size_t)(2 * sizeof(short int));
read = (int)fread(pcm_buffer, size, 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 {
NSLog(@"MP3生成成功:");
if (isDelete) {
NSError *error;
[fm removeItemAtPath:sourcePath error:&error];
if (error == nil) {
NSLog(@"删除源文件成功");
}
}
return outPath;
}
}
base64转码
-(NSString *)recordmp3ToBASE64;
{
NSString *strdatamp3 = [self convertToMp3SouceFilePathName:[NSTemporaryDirectory() stringByAppendingPathComponent:@"testRecorder.WAV"] isDeleteSourchFile:YES];
NSData *mp3Data = [[NSData dataWithContentsOfFile:strdatamp3] base64EncodedDataWithOptions:0];
NSString * encodedRecordStr = [[NSString alloc]initWithData:mp3Data encoding:NSUTF8StringEncoding];
return encodedRecordStr;
}
caf转码MP3
以上就是整个录音的过程,其中录音文件的名称以及后缀是可以更改的,后缀可以更改为caf格式。
testRecorder.WAV可以更改为testRecorder.caf。更改之后就是caf转MP3,可以根据项目要求进行格式更换。
调用
完成以上工作之后,就可以在使用的地方直接调用了。必须完成以上代码!!!
比如开始录音:
[self startRecordcase];
结束录音:
[self endRecord];
播放录音:
[self playWav];
通过接口上传录音:
[self recordmp3ToBASE64];
分享心得:
以上就是我在项目上使用的方法。其实在第一次写转码的时候出现了转码之后的文件全部是杂音的问题。找了很长时间才找到原因。
第一:
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsNonInterleaved]; //交叉的录制
// 设置录制音频采用高位优先的记录格式
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
// 设置采样信号采用浮点数
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
以上三种参数必须设置为No,转码之后的MP3文件就都是杂音。
第二:转成MP3需要lame文件。所以必须下载lame文件。这个在网上是都可以搜到。下载下来的lame文件包含了两个,如下图所示:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)