錄音(PCM格式)、播放、lame轉碼成MP3
阿新 • • 發佈:2019-02-19
/**
* 音訊轉碼,由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;
* 音訊轉碼,由PCM轉碼為MP3
*/
- (void)convertToMP3
{
NSString * mp3FileName = @"sendRecord.mp3";
NSString * documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *mp3FilePath = [documentPath stringByAppendingPathComponent:mp3FileName];
NSLog(@"audioPath:%@", audioFilePath);
@try {
int read, write;
FILE *pcm = fopen([audioFilePath cStringUsingEncoding:1], "rb"); //source 被轉換的音訊檔案位置 fseek(pcm, 4*1024,
const int MP3_SIZE = 8192;
short int pcm_buffer[PCM_SIZE*2];
unsigned char mp3_buffer[MP3_SIZE];
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;