仿QQ錄音以及振幅動畫實現

咱們儘可能的把QQ的錄音功能對應的細節都實現了。。。

本篇實現的功能:git

  • 一、封裝AVAudioRecorder以及AVAudioPlayer實現錄音以及播放功能。
  • 二、實現錄音時的振幅動畫。
  • 三、播放時環形進度條和振幅動畫,以及一些零碎的交互細節。
  • 四、變聲效果。
  • 五、發送時錄音文件的路徑,以及取消發送刪除錄音文件細節都作了。。

先上一個效果圖:github

158AE93346304DEB9426107554826E2A.gif

抓幾個點說一下:數組

錄音以及振幅動畫效果的實現思路:

錄音咱們本身經過封裝AVRecorder實現。振幅動畫的思路:用固定含有10個元素的數組,來表示當前須要顯示的振幅數值,使用一條貝塞爾曲線畫出當前數組的路徑,在CAShapeLayer上作展現。開始錄音時,啓動一個定時器,不間斷獲取音量的分貝值,定時器任務每進行一次,將數組的最後一個元素刪除,最新的分貝添加到數組第一個位置,而後根據數組從新繪製貝塞爾曲線並作展現。重複進行看起來就像在移動同樣。 步驟:bash

  • 一、獲取錄音的分貝大小(-160dB -- 0dB ,咱們把它轉換成0 - 1)。
- (float)levels {
    [self.audioRecorder updateMeters];
    double aveChannel = pow(10, (ALPHA * [self.audioRecorder averagePowerForChannel:0]));
    if (aveChannel <= 0.05f) aveChannel = 0.05f;
    if (aveChannel >= 1.0f) aveChannel = 1.0f;
    return aveChannel;
}
複製代碼
  • 二、開始一個定時器,按照必定的時間從錄音器獲取分貝大小,並將數組按照上面的規則修改。
- (void)updateMeter {
    // 獲取分貝數值
    CGFloat level = [[CWRecorder shareInstance] levels];
    [self.currentLevels removeLastObject];
    [self.currentLevels insertObject:@(level) atIndex:0];
    // 這個allLevels是用來幹嗎的?(在當前無關)在下面會說明,自有大用
    [self.allLevels addObject:@(level)];
    // 重繪bezierPath,從新展現
    [self updateLevelLayer];
}
複製代碼
  • 三、根據數組,從新描述路徑,並從新展現
- (void)updateLevelLayer {
    self.levelPath = [UIBezierPath bezierPath];
    CGFloat height = CGRectGetHeight(self.levelLayer.frame);
    for (int i = 0; i < self.currentLevels.count; i++) {
        CGFloat x = i * (levelWidth + levelMargin) + 5;
        CGFloat pathH = [self.currentLevels[i] floatValue] * height;
        CGFloat startY = height / 2.0 - pathH / 2.0;
        CGFloat endY = height / 2.0 + pathH / 2.0;
        [_levelPath moveToPoint:CGPointMake(x, startY)];
        [_levelPath addLineToPoint:CGPointMake(x, endY)];
    }
    self.levelLayer.path = _levelPath.CGPath;
}
複製代碼

作完振幅就動起來了,很是簡單。。。在錄音結束的時候 暫停定時器就OK了.框架

  • 四、由於QQ錄音的振幅是兩邊對稱的,咱們將視圖的層級作了一下小小的調整,在中間加入了一個複製圖層CAReplicatorLayer。直接將展現的圖層旋轉180度複製一份。就有了對稱的兩條振幅。ide

  • 五、播放錄音時的振幅動畫如何作? 錄音時咱們能獲取當前錄音的分貝,可是播放的時候,不能獲取播放的錄音當前分貝(我暫時無力獲取)怎麼辦?我這邊採起的方式就是在錄音的時候把展現過的分貝值都保存起來,就是上面第二塊代碼中的allLevels。。在結束錄音的時候將這個數組保存在一個單例的模型內,播放的時候直接在這個模型內取出該分貝數據,實現方式就是重複步驟2了。動畫

變聲如何實現?

變聲這塊我粗略的實現了一下,使用到了一個第三方框架 SoundTouchui

最後。。若是要做爲一個真正能使用到聊天內的錄音,錄製的語音格式咱們須要從wav轉成amr,有兩點好處,一個是佔有內存小,另一個是兼容安卓,這個也有一個經常使用的框架AudioConvert,其餘的一些細節就很少說了。。。spa

想了解的兄弟 能夠下載源碼看看code

高仿QQ錄音

再推薦一個 0 耦合的 仿QQ側滑抽屜框架!! 一行代碼集成超低耦合的側滑功能

發現什麼bug能夠留言給我。。謝謝~

相關文章
相關標籤/搜索