Swift iOS實現把PCM語音轉成MP3格式

最近折騰了swift的語音錄制識別和轉碼,這塊還是比較坑的,由于語音識別的準確度實測大概也就80%左右,所以還是需要上傳錄音文件啊。
首先是用訊飛語音SDK實現語音錄制和識別(語音聽寫),第一個坑是訊飛SDK只錄制了PCM格式的文件,這個文件是原始格式,默認比較大,另外播放器支持也不好,因此需要先把它轉成mp3,本來考慮使用系統的AudioConverter轉aac格式,不過aac好像不能在瀏覽器上播放。
轉成mp3需要lame庫支持,注意國內網搜到的lame.a庫不支持64位,所以現在不能用了。
還好已經有人做了這個事情,直接提供了最新編譯腳本和編譯好的framework庫,地址是https://github.com/wuqiong/mp3lame-for-iOS
我直接用了上面編譯的framework,沒有自己去編譯,直接把lame.framework拖到工程里。
然后需要用oc寫個封裝類,我不確定這個封裝類能不能用swift寫,畢竟里面用了很多c的語法,還是用oc橋接一層比較保險。oc封裝類如下:

#import <Foundation/Foundation.h>
#import "AudioWrapper.h"
#import "lame/lame.h"

@implementation AudioWrapper

+ (void)audioPCMtoMP3 :(NSString *)audioFileSavePath :(NSString *)mp3FilePath
{
    
    @try {
        int read, write;
        
        FILE *pcm = fopen([audioFileSavePath 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 converted: %@",mp3FilePath);
    }
    
}
@end

然后在橋接文件XXX-Bridging-Header.h中加入

import "AudioWrapper.h"

最后 swift文件的調用如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { AudioWrapper.audioPCMtoMP3(path, pathMp3)
}

由于轉碼的時間可能會比較長,在主線程直接調用容易出問題,就新開了個線程調用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 最近折騰了Swift的語音錄制識別和轉碼,這塊還是比較坑的,由于語音識別的準確度實測大概也就80%左右,所以還是需...
    offbye西濤閱讀 1,301評論 0 5
  • DAY7 早上走進洗手間的時候,窗外的綠葉輕輕的送來一陣微風,久違的秋風沁人心脾。早起的決心更加堅定,早起的清晨更...
    青衣雨翼_shape閱讀 155評論 0 0
  • 5月20號是周六,從15號開始,市場上的各式鮮花,是一天一個價,突然之間只往上竄,感覺就像是坐了火箭似的,卻不知為...
    沐子2閱讀 303評論 2 2
  • 如果說有一個判斷父母是否靠譜的標準,那一定不是父母的經濟收入水平和社會地位,也一定不是父母的受教育程度,而更多在于...
    四葉草hr閱讀 349評論 0 1