国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > iOS > 正文

iOS多媒體音頻(下)-錄音及其播放的實(shí)例

2020-07-26 02:59:52
字體:
供稿:網(wǎng)友

上一篇中總結(jié)了iOS中音效和音頻播放的最基本使用方法,其中音頻的播放控制是使用AVFoundation.framework框架中的AVAudioPlayer播放器對象來實(shí)現(xiàn)的,而這里音頻的錄制則是使用了同樣框架下的一個(gè)叫AVAudioRecorder的錄音機(jī)對象來實(shí)現(xiàn),這兩個(gè)類的用法流程非常類似,類的屬性和方法也類似,例如:播放器中需要獲取音頻文件的url,而錄音機(jī)要在沙盒中Docuemnt目錄下創(chuàng)建一個(gè)音頻文件路徑url;

播放器有isPlaying變量判斷是否正在播放,錄音機(jī)中有isRecording變量表示是否正在錄制;currentTime在播放器中表示播放時(shí)間,在錄音機(jī)中則表示錄音時(shí)間;播放器通過prepareToPlay方法加載文件到緩沖區(qū),錄音機(jī)通過prepareToRecord創(chuàng)建緩沖區(qū);播放音頻有play方法,音頻錄制有record方法,另外都有pause暫停方法和stop停止方法等等,具體可直接打開兩個(gè)類的頭文件詳細(xì)了解。

這里實(shí)現(xiàn)最基本的錄音流程以及錄音過程的控制,并通過之前使用的AVAudioPlayer來播放錄制好的音頻。注意iOS錄制的音頻為caf格式,如果需要通用化可以通過lame等插件將caf格式音頻轉(zhuǎn)成mp3格式。

錄音

這里實(shí)現(xiàn)開始錄音,暫停,繼續(xù)以及停止錄音。

創(chuàng)建文件目錄

iOS沙盒內(nèi)胡要有三個(gè)目錄:Documents目錄,tmp目錄以及Library目錄,其中Documents目錄用來存放用戶的應(yīng)用程序數(shù)據(jù),需要定期備份的數(shù)據(jù)要放在這里,和plist文件存儲一樣,我們要找到存放文件的路徑,然后在該路徑下放一個(gè)我們的文件,因此要自定義一個(gè)帶后綴的文件名,將獲得的路徑和文件名拼在一起記得到我們的文件的絕對路徑:

// 文件名#define fileName_caf @"demoRecord.caf"http:// 錄音文件絕對路徑@property (nonatomic, copy) NSString *filepathCaf;// 獲取沙盒Document文件路徑NSString *sandBoxPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];// 拼接錄音文件絕對路徑_filepathCaf = [sandBoxPath stringByAppendingPathComponent:fileName_caf];

創(chuàng)建音頻會話

錄音前要創(chuàng)建一個(gè)音頻會話,同時(shí)要設(shè)置錄音類型,提供的類型有以下幾種:

  • AVF_EXPORT NSString *const AVAudioSessionCategoryAmbient; // 用于錄制背景聲音,像雨聲、汽車引擎發(fā)動噪音等,可和其他音樂混合
  • AVF_EXPORT NSString *const AVAudioSessionCategorySoloAmbient; // 也是背景聲音,但其他音樂會被強(qiáng)制停止
  • AVF_EXPORT NSString *const AVAudioSessionCategoryPlayback; // 音軌
  • AVF_EXPORT NSString *const AVAudioSessionCategoryRecord; // 錄音
  • AVF_EXPORT NSString *const AVAudioSessionCategoryPlayAndRecord; // 錄音和回放
  • AVF_EXPORT NSString *const AVAudioSessionCategoryAudioProcessing; // 用于底層硬件編碼信號處理等
  • AVF_EXPORT NSString *const AVAudioSessionCategoryMultiRoute; // 內(nèi)置硬件相關(guān),iOS 6.0以上可用

常用的是AVAudioSessionCategoryPlayAndRecord類型,便于錄音后播放。

// 創(chuàng)建音頻會話AVAudioSession *audioSession=[AVAudioSession sharedInstance];// 設(shè)置錄音類別(這里選用錄音后可回放錄音類型)[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];[audioSession setActive:YES error:nil];

錄音設(shè)置

錄音前要根據(jù)需要對錄音進(jìn)行一些相應(yīng)的基本設(shè)置,例如錄音格式(LinearPCM)、采樣率、通道數(shù)等等,設(shè)置保存在一個(gè)字典內(nèi)并作為初始化錄音機(jī)的一個(gè)參數(shù)。

// 錄音設(shè)置-(NSDictionary *)getAudioSetting{  // LinearPCM 是iOS的一種無損編碼格式,但是體積較為龐大  // 錄音設(shè)置信息字典  NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];  // 錄音格式  [recordSettings setValue :@(kAudioFormatLinearPCM) forKey: AVFormatIDKey];  // 采樣率  [recordSettings setValue :@11025.0 forKey: AVSampleRateKey];  // 通道數(shù)(雙通道)  [recordSettings setValue :@2 forKey: AVNumberOfChannelsKey];  // 每個(gè)采樣點(diǎn)位數(shù)(有8、16、24、32)  [recordSettings setValue :@16 forKey: AVLinearPCMBitDepthKey];  // 采用浮點(diǎn)采樣  [recordSettings setValue:@YES forKey:AVLinearPCMIsFloatKey];  // 音頻質(zhì)量  [recordSettings setValue:@(AVAudioQualityMedium) forKey:AVEncoderAudioQualityKey];  // 其他可選的設(shè)置  // ... ...  return recordSettings;}

創(chuàng)建錄音機(jī)對象

錄音機(jī)對象的創(chuàng)建主要是利用上面的保存路徑和錄音設(shè)置進(jìn)行初始化得到:

// 懶加載錄音機(jī)對象get方法- (AVAudioRecorder *)audioRecorder {  if (!_audioRecorder) {    // 保存錄音文件的路徑url    NSURL *url = [NSURL URLWithString:_filepathCaf];    // 創(chuàng)建錄音格式設(shè)置setting    NSDictionary *setting = [self getAudioSetting];    // error    NSError *error=nil;    _audioRecorder = [[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error];    _audioRecorder.delegate = self;    _audioRecorder.meteringEnabled = YES;// 監(jiān)控聲波    if (error) {      NSLog(@"創(chuàng)建錄音機(jī)對象時(shí)發(fā)生錯誤,錯誤信息:%@",error.localizedDescription);      return nil;    }  }  return _audioRecorder;}

錄音控制方法

錄音過程控制主要是開始錄音、暫停、繼續(xù)和停止錄音,其中開始錄音和繼續(xù)錄音都是record方法。

// 開始錄音或者繼續(xù)錄音- (IBAction)startOrResumeRecord {  // 注意調(diào)用audiorecorder的get方法  if (![self.audioRecorder isRecording]) {    // 如果該路徑下的音頻文件錄制過則刪除    [self deleteRecord];    // 開始錄音,會取得用戶使用麥克風(fēng)的同意    [_audioRecorder record];  }}// 錄音暫停- (IBAction)pauseRecord {  if (_audioRecorder) {    [_audioRecorder pause];  }}// 結(jié)束錄音- (IBAction)stopRecord {  [_audioRecorder stop];}

錄音播放

錄音的播放很簡單,就是之前AVAudioPlayer音頻播放的簡單應(yīng)用,播放的路徑即我們錄音時(shí)創(chuàng)建好的音頻路徑。但這里注意為了保證每次都播放最新錄制的音頻,播放器的get方法要每次重新創(chuàng)建初始化。

// audioPlayer懶加載getter方法- (AVAudioPlayer *)audioPlayer {  _audioRecorder = NULL; // 每次都創(chuàng)建新的播放器,刪除舊的  // 資源路徑  NSURL *url = [NSURL fileURLWithPath:_filepathCaf];  // 初始化播放器,注意這里的Url參數(shù)只能為本地文件路徑,不支持HTTP Url  NSError *error = nil;  _audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];  //設(shè)置播放器屬性  _audioPlayer.numberOfLoops = 0;// 不循環(huán)  _audioPlayer.delegate = self;  _audioPlayer.volume = 0.5; // 音量  [_audioPlayer prepareToPlay];// 加載音頻文件到緩存【這個(gè)函數(shù)在調(diào)用play函數(shù)時(shí)會自動調(diào)用】  if(error){    NSLog(@"初始化播放器過程發(fā)生錯誤,錯誤信息:%@",error.localizedDescription);    return nil;  }  return _audioPlayer;}// 播放錄制好的音頻- (IBAction)playRecordedAudio {  // 沒有文件不播放  if (![[NSFileManager defaultManager] fileExistsAtPath:self.filepathCaf]) return;  // 播放最新的錄音  [self.audioPlayer play];}

完整源碼和Demo下載

//// ViewController.m// IOSRecorderDemo//// Created by Xinhou Jiang on 29/12/16.// Copyright © 2016年 Xinhou Jiang. All rights reserved.//#import "ViewController.h"#import <AVFoundation/AVFoundation.h>// 文件名#define fileName_caf @"demoRecord.caf"@interface ViewController ()// 錄音文件絕對路徑@property (nonatomic, copy) NSString *filepathCaf;// 錄音機(jī)對象@property (nonatomic, strong) AVAudioRecorder *audioRecorder;// 播放器對象,和上一章音頻播放的方法相同,只不過這里簡單播放即可@property (nonatomic, strong) AVAudioPlayer *audioPlayer;// 用一個(gè)processview顯示聲波波動情況@property (nonatomic, weak) IBOutlet UIProgressView *processView;// 用一個(gè)label顯示錄制時(shí)間@property (nonatomic, weak) IBOutlet UILabel *recordTime;// UI刷新監(jiān)聽器@property (nonatomic, strong) NSTimer *timer;@end@implementation ViewController- (void)viewDidLoad {  [super viewDidLoad];  // 初始化工作  [self initData];}// 初始化- (void)initData {  // 獲取沙盒Document文件路徑  NSString *sandBoxPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  // 拼接錄音文件絕對路徑  _filepathCaf = [sandBoxPath stringByAppendingPathComponent:fileName_caf];  // 1.創(chuàng)建音頻會話  AVAudioSession *audioSession=[AVAudioSession sharedInstance];  // 設(shè)置錄音類別(這里選用錄音后可回放錄音類型)  [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];  [audioSession setActive:YES error:nil];  // 2.開啟定時(shí)器  [self timer];}#pragma mark -錄音設(shè)置工具函數(shù)// 懶加載錄音機(jī)對象get方法- (AVAudioRecorder *)audioRecorder {  if (!_audioRecorder) {    // 保存錄音文件的路徑url    NSURL *url = [NSURL URLWithString:_filepathCaf];    // 創(chuàng)建錄音格式設(shè)置setting    NSDictionary *setting = [self getAudioSetting];    // error    NSError *error=nil;    _audioRecorder = [[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error];    _audioRecorder.delegate = self;    _audioRecorder.meteringEnabled = YES;// 監(jiān)控聲波    if (error) {      NSLog(@"創(chuàng)建錄音機(jī)對象時(shí)發(fā)生錯誤,錯誤信息:%@",error.localizedDescription);      return nil;    }  }  return _audioRecorder;}// audioPlayer懶加載getter方法- (AVAudioPlayer *)audioPlayer {  _audioRecorder = NULL; // 每次都創(chuàng)建新的播放器,刪除舊的  // 資源路徑  NSURL *url = [NSURL fileURLWithPath:_filepathCaf];  // 初始化播放器,注意這里的Url參數(shù)只能為本地文件路徑,不支持HTTP Url  NSError *error = nil;  _audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];  //設(shè)置播放器屬性  _audioPlayer.numberOfLoops = 0;// 不循環(huán)  _audioPlayer.delegate = self;  _audioPlayer.volume = 0.5; // 音量  [_audioPlayer prepareToPlay];// 加載音頻文件到緩存【這個(gè)函數(shù)在調(diào)用play函數(shù)時(shí)會自動調(diào)用】  if(error){    NSLog(@"初始化播放器過程發(fā)生錯誤,錯誤信息:%@",error.localizedDescription);    return nil;  }  return _audioPlayer;}// 計(jì)時(shí)器get方法- (NSTimer *)timer {  if (!_timer) {    _timer = [NSTimer scheduledTimerWithTimeInterval:0.1f repeats:YES block:^(NSTimer * _Nonnull timer) {      if(_audioRecorder) {        // 1.更新錄音時(shí)間,單位秒        int curInterval = [_audioRecorder currentTime];        _recordTime.text = [NSString stringWithFormat:@"%02d:%02d",curInterval/60,curInterval%60];        // 2.聲波顯示        //更新聲波值        [self.audioRecorder updateMeters];        //第一個(gè)通道的音頻,音頻強(qiáng)度范圍:[-160~0],這里調(diào)整到0~160        float power = [self.audioRecorder averagePowerForChannel:0] + 160;        [_processView setProgress:power/160.0];      }    }];  }  return _timer;}// 錄音設(shè)置-(NSDictionary *)getAudioSetting{  // LinearPCM 是iOS的一種無損編碼格式,但是體積較為龐大  // 錄音設(shè)置信息字典  NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];  // 錄音格式  [recordSettings setValue :@(kAudioFormatLinearPCM) forKey: AVFormatIDKey];  // 采樣率  [recordSettings setValue :@11025.0 forKey: AVSampleRateKey];  // 通道數(shù)(雙通道)  [recordSettings setValue :@2 forKey: AVNumberOfChannelsKey];  // 每個(gè)采樣點(diǎn)位數(shù)(有8、16、24、32)  [recordSettings setValue :@16 forKey: AVLinearPCMBitDepthKey];  // 采用浮點(diǎn)采樣  [recordSettings setValue:@YES forKey:AVLinearPCMIsFloatKey];  // 音頻質(zhì)量  [recordSettings setValue:@(AVAudioQualityMedium) forKey:AVEncoderAudioQualityKey];  // 其他可選的設(shè)置  // ... ...  return recordSettings;}// 刪除filepathCaf路徑下的音頻文件-(void)deleteRecord{  NSFileManager* fileManager=[NSFileManager defaultManager];  if ([[NSFileManager defaultManager] fileExistsAtPath:self.filepathCaf]) {    // 文件已經(jīng)存在    if ([fileManager removeItemAtPath:self.filepathCaf error:nil]) {      NSLog(@"刪除成功");    }else {      NSLog(@"刪除失敗");    }  }else {    return; // 文件不存在無需刪除  }}#pragma mark -錄音流程控制函數(shù)// 開始錄音或者繼續(xù)錄音- (IBAction)startOrResumeRecord {  // 注意調(diào)用audiorecorder的get方法  if (![self.audioRecorder isRecording]) {    // 如果該路徑下的音頻文件錄制過則刪除    [self deleteRecord];    // 開始錄音,會取得用戶使用麥克風(fēng)的同意    [_audioRecorder record];  }}// 錄音暫停- (IBAction)pauseRecord {  if (_audioRecorder) {    [_audioRecorder pause];  }}// 結(jié)束錄音- (IBAction)stopRecord {  [_audioRecorder stop];}#pragma mark -錄音播放// 播放錄制好的音頻- (IBAction)playRecordedAudio {  // 沒有文件不播放  if (![[NSFileManager defaultManager] fileExistsAtPath:self.filepathCaf]) return;  // 播放最新的錄音  [self.audioPlayer play];}@end

Demo下載:demo

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 铜山县| 本溪市| 体育| 宜兴市| 射阳县| 万安县| 修武县| 界首市| 西充县| 留坝县| 峨边| 南平市| 霍邱县| 元谋县| 通州区| 南昌县| 东安县| 扶余县| 分宜县| 镶黄旗| 涟水县| 沂南县| 博爱县| 大同市| 阿巴嘎旗| 建昌县| 涟水县| 略阳县| 浑源县| 梓潼县| 涟水县| 黄龙县| 岗巴县| 偃师市| 隆林| 河北省| 桦甸市| 泾阳县| 钦州市| 安化县| 南召县|