如何實現遊戲陪玩系統中語音的錄製與播放?

雲豹科技程式設計師發表於2021-10-22

前言

隨著網際網路技術的發展,人們的通訊方式發生了巨大變化,哪怕是遊戲陪玩系統的開發,使用者之間的交流方式除了文字、圖片等,也增加了語音的傳送功能。那麼語音的錄製與播放具體是如何實現的呢?

1.語音錄製動作分解

1)按下按鈕,開始錄製,遊戲陪玩系統顯示錄音指示介面;

2)手指上滑,暫停錄製,顯示“鬆開手指取消傳送”,如果這個時候鬆開手指,取消錄製,並不會傳送;

3)手指滑回錄製按鈕位置,繼續錄音;

4)鬆開手指,錄音完成,傳送;

5)錄製時長小於1秒,顯示時間太短,不傳送;

6)錄製時長超過60秒,自動結束錄製,並自動傳送。

2.語音錄製實現

目前,大多數iOS遊戲陪玩系統採用.caf格式儲存和傳送語音檔案。因為這個格式在保證聲音質量的前提下體積更小。安卓遊戲陪玩系統大多數採用amr格式,所以要播放安卓遊戲陪玩系統傳送過來的語音還需要轉碼,這個後面講。

要錄製語音,當然要用到蘋果自帶的AVFoundation中的AVAudioRecorder和AVAudioSession。

遊戲陪玩系統程式碼中如何操作才可以開始錄音呢?這裡貼一段程式碼,寫了註釋。

- (void)startRecord {
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    NSError *err = nil;
    //設定AVAudioSession
    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&err];
    if(err) {
        return;
    }
    
    //設定錄音輸入源
    UInt32 doChangeDefaultRoute = 1;
    AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof (doChangeDefaultRoute), &doChangeDefaultRoute);
    err = nil;
    [audioSession setActive:YES error:&err];
    if(err) {
        return;
    }
    //設定檔案儲存路徑和名稱
    NSString *fileName = [NSString stringWithFormat:@"/voice-%5.2f.caf", [[NSDate date] timeIntervalSince1970] ];
    self.recordPath = [self.recordPath stringByAppendingPathComponent:fileName];
    NSURL *recordedFile = [NSURL fileURLWithPath:self.recordPath];
    NSDictionary *dic = [self recordingSettings];
    //初始化AVAudioRecorder
    err = nil;
    _recorder = [[AVAudioRecorder alloc] initWithURL:recordedFile settings:dic error:&err];
    if(_recorder == nil) {
        return;
    }
    //準備和開始錄音
    [_recorder prepareToRecord];
    self.recorder.meteringEnabled = YES;
    [self.recorder record];
    [_recorder recordForDuration:0];
    if (self.levelTimer) {
        [self.levelTimer invalidate];
        self.levelTimer = nil;
    }
    self.levelTimer = [NSTimer scheduledTimerWithTimeInterval: 0.0001 target: self selector: @selector(levelTimerCallback:) userInfo: nil repeats: YES];
}

結束錄音的核心程式碼就是呼叫AVAudioRecorder的stop方法:

[self.recorder stop];

錄音結束後,開啟沙盒,找到自己設定的路徑,就可以在遊戲陪玩系統中看到以.caf字尾的語音檔案。

3.語音播放

語音播放主要用到AVFoundation中的AVAudioPlayer。遊戲陪玩系統程式碼中要想播放一段語音檔案,那麼首先得知道這段語音的檔案路徑。這個路徑在錄音之後需要記錄下來,然後在播放的時候拿到路徑,呼叫相關方法就可以了。又要上程式碼了,播放的核心程式碼如下:

   _audioPlayer = [[AVAudioPlayer alloc] initWithData:audioData error:&audioPlayerError];
if (!_audioPlayer || !audioData) {
    [self setAudioPlayerState:LGAudioPlayerStateCancel];
    return;
}
[[UIDevice currentDevice] setProximityMonitoringEnabled:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(proximityStateChanged:) name:UIDeviceProximityStateDidChangeNotification object:nil];
_audioPlayer.volume = 1.0f;
_audioPlayer.delegate = self;
[_audioPlayer prepareToPlay];
[self setAudioPlayerState:LGAudioPlayerStatePlaying];
[_audioPlayer play];

其中的URLString就是遊戲陪玩系統語音檔案的路徑。
那麼停止播放呢?和停止錄製一樣,呼叫stop方法

- (void)stopAudioPlayer {
    if (_audioPlayer) {
        _audioPlayer.playing ? [_audioPlayer stop] : nil;
        _audioPlayer.delegate = nil;
        _audioPlayer = nil;
        [[LGAudioPlayer sharePlayer] setAudioPlayerState:LGAudioPlayerStateCancel];
    }
}

4.amr檔案轉碼

前面說過,很多安卓遊戲陪玩系統傳送語音採用amr格式,而amr檔案在iOS中不能被直接播放,這就需要轉碼。這裡推薦兩個amr轉wave的工具(注:轉成wave格式就可以在iOS中播放了):

1.iOS-amr

2.amrFileCodec

5.語音傳送

在遊戲陪玩系統中完成語音錄製之後,需要把語音訊息傳送出去。傳送語音分為兩個步驟:語音檔案上傳;語音訊息傳送。

5.1 語音檔案上傳

上傳方法當然很簡單,用AFN或者ASI就可以。這裡要說的是語音訊息的上傳機制。

語音檔案轉成二進位制資料,上傳至遊戲陪玩系統伺服器成功後,伺服器會返回一個檔案在伺服器的儲存“地址”,暫且把這個“地址”命名為partUrl,這個partUrl可以是一個完整的URL,也可以是URL的一部分。一般情況下,為了安全考慮,partUrl是一個URL除過協議部分和域名部分的其餘部分。例如完整的URL是“http://blog.csdn.NET/gang544043963/article/details/52266903”,那麼這個partUrl就是“gang544043963/article/details/52266903”。我們拿到遊戲陪玩系統伺服器返回的這個partUrl之後呢,把它組裝成一條要傳送的訊息傳送出去。這樣,一個語音傳送的動作就完成了。

5.2 語音訊息下載與快取

當在遊戲陪玩系統中接收別人發來的語音訊息時,首先接收到的是不包含語音檔案的XML資料,這串資料中就包含5.1提到的partUrl。然後解析出partUrl,再用約定好的規則進行拼接,形成完整的URL,用這個URL就可以下載相應的語音檔案。

語音快取可以借鑑SDWebImage快取圖片的方法。URL中會包含‘檔名’部分,用‘檔名’作為下載要快取語音檔案的真實檔名。

6.揚聲器切換

在遊戲陪玩系統中播放語音的時候,手機貼近耳朵,自動切換聽筒播放;遠離耳朵,自動切換為揚聲器播放。這個功能實現其實很簡單,iOS系統自動檢測貼近(proximity)動作,併傳送通知。我們只需要監聽這個通知,並在響應方法中切換AVAudioSession的Category。

新增監聽:

[[UIDevice currentDevice] setProximityMonitoringEnabled:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(proximityStateChanged:) name:UIDeviceProximityStateDidChangeNotification object:nil];

響應方法中切換揚聲器:

- (void)proximityStateChanged:(NSNotification *)notification {
    if ([[UIDevice currentDevice] proximityState] == YES) {
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
    }else {
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
    }
}

結束語

本文從程式碼角度講解了遊戲陪玩系統中語音錄製和播放的實現,僅供入行不久的同行和想快速上手的同學參考,希望對大家有幫助。

本文轉載自網路,轉載僅為分享乾貨知識,如有侵權歡迎聯絡雲豹科技進行刪除處理
原文連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69996194/viewspace-2838829/,如需轉載,請註明出處,否則將追究法律責任。

相關文章