Apple Watch音頻錄制,.wav轉(zhuǎn)換.mp3,獲取音頻文件時長

錄音.png
1.音頻錄制

實現(xiàn)在Apple Watch上面的錄制音頻功能,其實難度不大,只需要調(diào)用WKInterfaceController的方法。完整的代碼如下

 NSURL *url =  [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.cn.seven.eg"];
 NSURL *fileUrl = [url URLByAppendingPathComponent:@"record.wav"];

 NSDictionary *audioOptions = [NSDictionary dictionaryWithObjectsAndKeys:@"發(fā)送",
                              WKAudioRecorderControllerOptionsActionTitleKey,
                              [NSNumber numberWithInt:30],
                              WKAudioRecorderControllerOptionsMaximumDurationKey, nil];

[self presentAudioRecorderControllerWithOutputURL:fileUrl preset:WKAudioRecorderPresetHighQualityAudio options:audioOptions completion:^(BOOL didSave, NSError * _Nullable error) {
            
            if (error) {
                return ;
            }
            
            if (didSave) {
                [[RAWETelecastManager sharedManager] sendRunnerTelecastUrl:fileUrl duration:0];
            }
        }];

需要注意的是想要在Watch上錄制音頻,必須打開App Groups這個功能,然后提供Groups路徑給系統(tǒng)來存儲文件。具體設(shè)置路徑Capabilities->App Groups。工程中的Taget都需要在同一個Groups中。不然就算在Watch上面錄制成功了在App上面也讀取不到。
audioOptions參數(shù)是對錄音功能的一些設(shè)置,我這里設(shè)置的是右上角的按鈕Title和最大錄音時長。

App Groups.png

錄制音頻成功后,就可以發(fā)送給App端了,具體的傳送方法可以參考之前的這篇文章Watch開發(fā)中遇到的那些問題(WatchOS 2)

2. wav轉(zhuǎn)換mp3

其實上面的方法支持wav/mp4/m4a三種錄音格式,只需要在保存時提供相應(yīng)的后綴名就可以了,研究類型轉(zhuǎn)換是項目本身上傳到服務(wù)器的文件是mp3類型,直接上代碼。

+ (BOOL)convertFromWavToMp3WithData:(NSData *)data
{
    NSString *cachePath = [NSFileManager cacheDiretory];
    NSString *wavPath = [NSString stringWithFormat:@"%@/watchRecorder.wav",cachePath];
    NSString *mp3Path = [NSString stringWithFormat:@"%@/watchRecorder.mp3",cachePath];
    
    if (![data writeToURL:[NSURL fileURLWithPath:wavPath] atomically:YES]) {
        return NO;
    }
   
    int read, write;
    
    FILE *pcm = fopen([wavPath cStringUsingEncoding:NSUTF8StringEncoding], "rb");  //source
                                      //skip file header
    FILE *mp3 = fopen([mp3Path cStringUsingEncoding:NSUTF8StringEncoding], "wb");  //output
    
    if (!pcm || !mp3)
    {
        fclose(mp3);
        fclose(pcm);
        return NO;
    }
    
    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, 22050);
    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);

    return YES;
}

在調(diào)試上面的方法過程中,出現(xiàn)過音頻被壓縮的情況,后來發(fā)現(xiàn)是錄制音頻時的WKAudioRecorderPresetHighQualityAudio 參數(shù)與轉(zhuǎn)換方法中的lame_set_in_samplerate(lame, 22050)參數(shù)造成的,這兩個相對應(yīng)的參數(shù)是我一次次試出來的,具體的原理還是不懂,只大概知道是音頻赫茲之類的問題。所以如果恰好你了解這塊,請給我解答一下,萬分感謝。

3.獲取音頻文件的時長

在錄制過程中,因為錄音界面是系統(tǒng)的,沒有找到相應(yīng)的接口來獲取錄音時長,所以就查了一下相應(yīng)獲取時長的方法,還是直接上代碼。

 AVURLAsset* audioAsset =[AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:mp3Path] options:nil];
                    
 CMTime audioDuration = audioAsset.duration;
                    
 float audioDurationSeconds =CMTimeGetSeconds(audioDuration);

其實都是些拿來就可以直接用的代碼,坑我都趟過了,如果其他問題也可以留言問我,不過我可能不會。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容