
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和最大錄音時長。

錄制音頻成功后,就可以發(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);
其實都是些拿來就可以直接用的代碼,坑我都趟過了,如果其他問題也可以留言問我,不過我可能不會。