手機錄音 AVAudioRecorder劲弦,并轉(zhuǎn)成mp3格式

蘋果提供了AVAudioRecorder類來讓我們進行音頻錄制倍宾,是錄音變的非常的便捷!
在使用AVAudioRecorder進行錄音之前要做幾樣準備工作晴叨,
① 凿宾、在iOS10及以上矾屯,調(diào)用系統(tǒng)功能需要在info.plist文件里添加相應的key兼蕊,如圖,在info.plist文件下添加Key: Privacy - Microphone Usage Description, Value值可以自己隨便寫哦件蚕!


Key

② 孙技、進行權(quán)限驗證,如下代碼:

AVAudioSession *session = [AVAudioSession sharedInstance];
 if ([session respondsToSelector:@selector(requestRecordPermission:)]) {
        
        [session performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) {
            if (granted) {
                
                // 用戶同意獲取麥克風排作,一定要在主線程中執(zhí)行UI操作G@病!妄痪!
                dispatch_queue_t queueOne = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
                dispatch_async(queueOne, ^{
                    
                    dispatch_async(dispatch_get_main_queue(), ^{
                        
                        //在主線程中執(zhí)行UI哈雏,這里主要是執(zhí)行錄音和計時的UI操作
                        [self record];
                    });
                });
            } else {
                
                // 用戶不同意獲取麥克風
                UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"麥克風不可用" message:@"請在“設置 - 隱私 - 麥克風”中允許XXX訪問你的麥克風" preferredStyle:UIAlertControllerStyleAlert];
                UIAlertAction *openAction = [UIAlertAction actionWithTitle:@"前往開啟" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                    
                    //如果要讓用戶直接跳轉(zhuǎn)到設置界面,則可以進行下面的操作衫生,如不需要裳瘪,就忽略下面的代碼
                    /*
                     *iOS10 開始蘋果禁止應用直接跳轉(zhuǎn)到系統(tǒng)單個設置頁面,只能跳轉(zhuǎn)到應用所有設置頁面
                     *iOS10以下可以添加單個設置的系統(tǒng)路徑罪针,并在info里添加URL Type彭羹,將URL schemes 設置路徑為prefs即可。
                     *@"prefs:root=Sounds"
                     */
                    NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                    
                    if([[UIApplication sharedApplication] canOpenURL:url]) {
                        
                        [[UIApplication sharedApplication] openURL:url];
                    }
                }];
                
                [alertController addAction:openAction];
                [self presentViewController:alertController animated:YES completion:nil];
            }
        }];
    }

3?? 泪酱、為了知道你正在錄音派殷,肯定得搞個錄音的計時器吧!
首先搞個label顯示時間

- (void)addTimerLabel {
    
    //這個是自己封裝的創(chuàng)建label的方法墓阀!
    _timerLabel = [CommonLib createLabelFrame:CGRectMake(20, 120, kScreenWidth - 40, TimerLabelH) text:@"00:00:00" alignment:NSTextAlignmentCenter textColor:[UIColor greenColor] font:TimerLabelH];
    [self.view addSubview:_timerLabel];
}

//要計時當然少不了計時器了,這里計時器設置成每秒更新毡惜,因為這里設定的最小時間單位是秒,若最小時間單位是毫秒斯撮,就把1.0经伙,改成0.01!這個方法在你點擊錄音的時候調(diào)用
- (void)startTimer {
    
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateSecond:) userInfo:nil repeats:YES];
}

//執(zhí)行更新UI的操作吮成,每秒執(zhí)行
- (void)updateSecond:(NSTimer *)timer {
    
    _second ++;
    if (_second == 1) {
        
        [self enbleBtn];
    }
    //這個方法是把時間顯示成時分秒的形式顯示在label上
    NSString *timerStr = [self convertTimeToString:_second];
    _timerLabel.text = timerStr;
}

 //規(guī)范時間格式
- (NSString *)convertTimeToString:(NSInteger)second {
   
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"HH:mm:ss"];
    NSDate *date = [formatter dateFromString:@"00:00:00"];
    date = [date dateByAddingTimeInterval:second];
    NSString *timeString = [formatter stringFromDate:date];
    return timeString;
}

好了橱乱,以上步驟走完,就可以開始錄音的操作了粱甫!

//設置后臺播放,下面這段是錄音和播放錄音的設置
_session = [AVAudioSession sharedInstance];
NSError *sessionError;
[_session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
//判斷后臺有沒有播放
if (_session == nil) {
            
        SIMEILog(@"Error creating sessing:%@", [sessionError description]);
} else {
//關閉其他音頻播放泳叠,把自己設為活躍狀態(tài)
        [_session setActive:YES error:nil];
}
        
if (![_timer isValid]) {
            
            [self startTimer];
} else {
            
            //這個方法是寫了一個NSTimer的拓展類 Category,具體方法在下面附上代碼
            [_timer continueTimer];
}

//設置AVAudioRecorder
if (!self.recorder) {
            
            NSDictionary *settings = @{AVFormatIDKey  :  @(kAudioFormatLinearPCM), AVSampleRateKey : @(11025.0), AVNumberOfChannelsKey :@2, AVEncoderBitDepthHintKey : @16, AVEncoderAudioQualityKey : @(AVAudioQualityHigh)};

            //開始錄音,將所獲取到得錄音存到文件里 _recordUrl
是存放錄音的文件路徑,在下面附上
            self.recorder = [[AVAudioRecorder alloc] initWithURL:_recordUrl settings:settings error:nil];
            
            /*
             * settings 參數(shù)
             1.AVNumberOfChannelsKey 通道數(shù) 通常為雙聲道 值2
             2.AVSampleRateKey 采樣率 單位HZ 通常設置成44100 也就是44.1k,采樣率必須要設為11025才能使轉(zhuǎn)化成mp3格式后不會失真
             3.AVLinearPCMBitDepthKey 比特率 8 16 24 32
             4.AVEncoderAudioQualityKey 聲音質(zhì)量
             ① AVAudioQualityMin  = 0, 最小的質(zhì)量
             ② AVAudioQualityLow  = 0x20, 比較低的質(zhì)量
             ③ AVAudioQualityMedium = 0x40, 中間的質(zhì)量
             ④ AVAudioQualityHigh  = 0x60,高的質(zhì)量
             ⑤ AVAudioQualityMax  = 0x7F 最好的質(zhì)量
             5.AVEncoderBitRateKey 音頻編碼的比特率 單位Kbps 傳輸?shù)乃俾?一般設置128000 也就是128kbps
             
             */
        }
        
        //準備記錄錄音
        [_recorder prepareToRecord];
        
        //開啟儀表計數(shù)功能,必須開啟這個功能茶宵,才能檢測音頻值
        [_recorder setMeteringEnabled:YES];
        //啟動或者恢復記錄的錄音文件
        [_recorder record];

下面附上NSTimer的Category危纫,怎么創(chuàng)建Category呢,右擊New Files -> ObjectC - Files -> File Type選擇Category, Class 選擇NSTimer ,File文件名自己隨便取

在.h文件中添加兩個方法

//暫停計時
- (void)pauseTimer;

//繼續(xù)計時
- (void)continueTimer;

在.m文件中實現(xiàn)兩個方法

- (void)pauseTimer {
    
    //如果已被釋放則return!isValid對應invalidate
    if (![self isValid]) return;
    //啟動時間為很久以后
    [self setFireDate:[NSDate distantFuture]];
}

- (void)continueTimer {
    
    if (![self isValid]) return;
    //啟動時間為現(xiàn)在
    [self setFireDate:[NSDate date]];
}

附上_recordUrl的路徑創(chuàng)建

//因為錄音文件比較大种蝶,所以我們把它存在Temp文件里契耿,Temp文件里的文件在app重啟的時候會自動刪除
_recordFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent: @"record.caf"];
    //創(chuàng)建臨時文件來存放錄音文件
_recordUrl = [NSURL fileURLWithPath:self.recordFilePath];

下面我們就要把錄音文件轉(zhuǎn)成mp3格式了,在網(wǎng)上查了很多方法螃征,發(fā)現(xiàn)大部分人都推薦使用lame來轉(zhuǎn)換mp3搪桂!
所以下面附上lame轉(zhuǎn)換mp3的方法,lame的github下載鏈接https://github.com/rbrito/lame

下載完成后倒入過程中盯滚,在Build Phases 下的Link Binary With Library 下添加lame


lame

一般導入后Library Search Paths 就會自動添加上lame文件在工程中的路徑踢械,若沒有添加上,就自己手動添加上魄藕,否則會報錯D诹小!背率!

導入成功后话瞧,就開始使用lame轉(zhuǎn)換mp3了,一大段的C代碼寝姿,C語言好的同學看著就比較得心應手了

首先#import "lame.h"

//然后開始寫轉(zhuǎn)換的代碼
    //如果要保存下來自己聽交排,就講mp3保存到到Document中,如下代碼会油,如果不的話个粱,就保存到Temp文件中
    NSString *fileName = [NSString stringWithFormat:@"/%@.mp3", nowTime];
    NSString *filePath = [[NSHomeDirectory() stringByAppendingFormat:@"/Documents/"] stringByAppendingPathComponent:fileName];
    _mp3Url = [NSURL URLWithString:filePath];
    
    @try {
        int read, write;
        
        FILE *pcm = fopen([_recordFilePath cStringUsingEncoding:1], "rb");   //source 被轉(zhuǎn)換的音頻文件位置
        fseek(pcm, 4 * 1024, SEEK_CUR);//刪除頭,否則在前一秒鐘會有雜音
        FILE *mp3 = fopen([filePath 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的配置要跟AVAudioRecorder的配置一致都许,否則會造成轉(zhuǎn)換不成功
        lame_t lame = lame_init();
        lame_set_in_samplerate(lame, 11025.0);//采樣率
        lame_set_VBR(lame, vbr_default);
        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);
            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生成成功!!!");
}

好了以上就是錄音和轉(zhuǎn)mp3的主要代碼了,最后說一下嫂冻,這個demo上傳github的時候出了點問題胶征,所以如果要demo的同學把郵箱留一下哈!若是對你有幫助的話桨仿,隨手點個贊哦??K驯洹H纤浮味廊!

附上lame編譯:
先到官網(wǎng)下載lame文件
再到github上下載外國網(wǎng)友上傳的編譯腳本文件
將編譯腳本文件build-lame.sh 復制到lame文件夾下
修改腳本文件
打開終端
chmod 777 build-lame.sh //chmod 777 是修改權(quán)限的指令
./build-lame.sh 開始編譯
大概需要一分鐘左右
編譯完成后lame文件下會生成fat-lame和thin-lame兩個文件夾
將fat-lame中的lame.h 和 libmp3lame.a導入工程即可

ps: 如果我沒有及時回復节猿,可以先下載swift版的哦!
https://github.com/jieming123/RecordToMP3

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吹零,一起剝皮案震驚了整個濱河市罩抗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌灿椅,老刑警劉巖套蒂,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钞支,死亡現(xiàn)場離奇詭異,居然都是意外死亡操刀,警方通過查閱死者的電腦和手機烁挟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來骨坑,“玉大人撼嗓,你說我怎么就攤上這事】▎” “怎么了静稻?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長匈辱。 經(jīng)常有香客問我,道長杀迹,這世上最難降的妖魔是什么亡脸? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮树酪,結(jié)果婚禮上浅碾,老公的妹妹穿的比我還像新娘。我一直安慰自己续语,他們只是感情好垂谢,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疮茄,像睡著了一般滥朱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上力试,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天徙邻,我揣著相機與錄音,去河邊找鬼畸裳。 笑死缰犁,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的怖糊。 我是一名探鬼主播帅容,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼伍伤!你這毒婦竟也來了并徘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤嚷缭,失蹤者是張志新(化名)和其女友劉穎饮亏,沒想到半個月后耍贾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡路幸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年荐开,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片简肴。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡晃听,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出砰识,到底是詐尸還是另有隱情能扒,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布辫狼,位于F島的核電站初斑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏膨处。R本人自食惡果不足惜见秤,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望真椿。 院中可真熱鬧鹃答,春花似錦、人聲如沸突硝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽解恰。三九已至锋八,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間修噪,已是汗流浹背查库。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留黄琼,地道東北人樊销。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像脏款,于是被迫代替她去往敵國和親围苫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容