引入下面两个库。lame是个第三方库。
#import
<AVFoundation/AVFoundation.h>
#import "lame.framework/Headers/lame.h"
#pragma mark -
音频转码
/**
*
音频转码,由
PCM
转码为
MP3
*/
- (
void
)convertToMP3
{
NSString
* mp3FileName =
@"sendRecord.mp3"
;
NSString
* documentPath = [
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
lastObject
];
NSString
*mp3FilePath = [documentPath
stringByAppendingPathComponent
:mp3FileName];
NSString
* audioFilePath = [
NSString
stringWithFormat
:
@"%@/audio.caf"
, documentPath];
NSLog
(
@"audioPath:%@"
, audioFilePath);
@try
{
int
read, write;
FILE
*pcm =
fopen
([audioFilePath
cStringUsingEncoding
:
1
],
"rb"
);
//source
被转换的音频文件位置
fseek
(pcm,
4
*
1024
,
SEEK_CUR
);
//skip file header
FILE
*mp3 =
fopen
([mp3FilePath
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
();
lame_set_in_samplerate
(lame,
11025.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);
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
生成成功
:%@"
, mp3FilePath);
}
}
#pragma mark -
取得录音文件保存路径
/**
*
取得录音原始文件保存路径
*
*
@return
录音原始文件路径
*/
- (
NSURL
*)getSavePath{
NSString
*urlStr=[
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
lastObject
];
urlStr=[urlStr
stringByAppendingPathComponent
:
@"audio.caf"
];
NSURL
*url=[
NSURL
fileURLWithPath
:urlStr];
return
url;
}
- (
NSString
*)getSavePathToString{
NSString
*urlStr=[
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
lastObject
];
urlStr=[urlStr
stringByAppendingPathComponent
:
@"audio.caf"
];
return
urlStr;
}
/**
*
取得
MP3
文件保存路径
*
*
@return
MP3
文件路径
*/
- (
NSURL
*)getMP3Path
{
//
播放
MP3
NSString
* mp3FileName =
@"sendRecord.mp3"
;
NSString
* documentPath = [
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
lastObject
];
NSString
*mp3FilePath = [documentPath
stringByAppendingPathComponent
:mp3FileName];
return
[
NSURL
fileURLWithPath
:mp3FilePath];
}
- (
NSString
*)getMP3PathToString
{
//
播放
MP3
NSString
* mp3FileName =
@"sendRecord.mp3"
;
NSString
* documentPath = [
NSSearchPathForDirectoriesInDomains
(
NSDocumentDirectory
,
NSUserDomainMask
,
YES
)
lastObject
];
NSString
*mp3FilePath = [documentPath
stringByAppendingPathComponent
:mp3FileName];
return
mp3FilePath;
}
#pragma mark -
取得录音文件设置
/**
*
取得录音文件设置
*
*
@return
录音设置
*/
-(
NSDictionary
*)getAudioSetting{
NSMutableDictionary
*dicM=[
NSMutableDictionary
dictionary
];
//
设置录音格式
[dicM
setObject
:
@(
kAudioFormatLinearPCM
)
forKey
:
AVFormatIDKey
];
//
设置录音采样率,
8000
是电话采样率,对于一般录音已经够了
[dicM
setObject
:
@(11025.0)
forKey
:
AVSampleRateKey
];
//
设置通道
,
这里采用单声道
[dicM
setObject
:
@(2)
forKey
:
AVNumberOfChannelsKey
];
//
每个采样点位数
,
分为
8
、
16
、
24
、
32
[dicM
setObject
:
@(16)
forKey
:
AVLinearPCMBitDepthKey
];
//
是否使用浮点数采样
// [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
//
音频编码质量
[dicM
setObject
:
@(
AVAudioQualityLow
)
forKey
:
AVEncoderAudioQualityKey
];
//....
其他设置等
return
dicM;
}
#pragma mark -
懒加载
- (
AVAudioRecorder
*)audioRecorder{
if
(
_audioRecorder
==
nil
) {
//
录音相关
AVAudioSession
*audioSession=[
AVAudioSession
sharedInstance
];
//
设置为播放和录音状态,以便可以在录制完之后播放录音
[audioSession
setCategory
:
AVAudioSessionCategoryPlayAndRecord
error
:
nil
];
[audioSession
setActive
:
YES
error
:
nil
];
//
创建录音文件保存路径
NSURL
* url = [
self
getSavePath
];
//
创建录音格式设置
NSDictionary
* setting = [
self
getAudioSetting
];
//
创建录音机
NSError
* error =
nil
;
_audioRecorder
= [[
AVAudioRecorder
alloc
]
initWithURL
:url
settings
:setting
error
:&error];
_audioRecorder
.
delegate
=
self
;
if
(error) {
NSLog
(
@"
创建录音机对象时发生错误,错误信息:
%@"
, error.
localizedDescription
);
return
nil
;
}
}
return
_audioRecorder
;
}
/**
*
创建播放器
*
*
@return
播放器
*/
- (
AVAudioPlayer
*)audioPlayer{
if
(
_audioPlayer
==
nil
) {
//
录音相关
AVAudioSession
*audioSession=[
AVAudioSession
sharedInstance
];
//
设置为播放和录音状态,以便可以在录制完之后播放录音
[audioSession
setCategory
:
AVAudioSessionCategoryPlayback
error
:
nil
];
[audioSession
setActive
:
YES
error
:
nil
];
NSURL
* url = [
self
getSavePath
];
NSError
* error =
nil
;
_audioPlayer
= [[
AVAudioPlayer
alloc
]
initWithContentsOfURL
:url
error
:&error];
_audioPlayer
.
volume
=
1.0
;
_audioPlayer
.
numberOfLoops
=
0
;
_audioPlayer
.
delegate
=
self
;
[
_audioPlayer
prepareToPlay
];
if
(error) {
NSLog
(
@"
创建播放器过程中发生错误,错误信息:
%@"
, error.
localizedDescription
);
return
nil
;
}
}
return
_audioPlayer
;
}