簡體   English   中英

AVAudioRecorder currentTime 給出錯誤的值

[英]AVAudioRecorder currentTime giving bad values

我有如下設置,在 iOS 10.3 的 iPhone 5s 上進行測試,包括調試和未調試。

  • AVAudioRecorder觸發record(forDuration: 5.0)
  • CADisplayLink記錄器的級別(記錄器已啟用meteringEnabled ),同步 animation,並跟蹤recorder.currentTime (但可以通過在顯示鏈接中最少地跟蹤時間來重現問題)
  • recorder.currentTime的報告始終達到 > 5 的值(通常是 5.2 到 5.5)。 結果與recorder.deviceTimeCFAbsoluteTimeGetCurrent的值基本一致
  • 我初始化一個AVAudioPlayer並驗證聲音資產的持續時間是否恰好為 5.0 秒。

根據我的理解,錄音機的currentTime以秒為單位測量,並在 recorder.isRecording 恢復為 false 時重置為 0.0,這在錄音機停止時立即發生(這與我在audioRecorderDidFinishRecording中看到的一致)......所以用CADisplayLink觀察應該產生嚴格小於 5.0 的 currentTime 值嗎?

問題是:這里可能出了什么問題? 恰好 5 秒后,錄音機正常停止,但內部認為它錄制了超過 5 秒? 我正在聽我所有的錄音,它們聽起來不錯。

我不確定它是否相關,但我的AVAudioSessionAVAudioSessionCategoryPlayAndRecord類型,我的音頻設置如下(所有這些除了采樣率都是以后分析所必需的):

audioSettings = [
    AVFormatIDKey: Int(kAudioFormatLinearPCM),
    AVSampleRateKey: 44100,
    AVNumberOfChannelsKey: 2,
    AVLinearPCMIsBigEndianKey: 0,
    AVLinearPCMIsFloatKey: 0,
    AVLinearPCMBitDepthKey: 16,
    AVLinearPCMIsNonInterleaved: 0
]

我已經嘗試擺弄所有這些,但沒有看到任何變化行為。

CADisplayLink是通過主線程添加的

recorderDisplayLink?.add(to: RunLoop.current, forMode: RunLoopMode.commonModes)

我在堆棧交換中可以找到的唯一類似問題是這個,但問題未明確說明,答案也無濟於事(至少對我而言)。
起初我認為問題可能出在主隊列超載上,因此記錄器的時間感不知何故變得臃腫(我認為這仍然會構成不良行為),但是在禁用 animation 之后(並且還嘗試使用 Timer 而不是CADisplayLink),問題依然存在,., 或許它仍然是一個線程問題:但我不明白為什么會這樣。 如果我確實需要多線程,我可以在理解和實施方面使用一些幫助 :) 任何想法表示贊賞。

在我使用過AVAudioRecorder所有時間AVAudioRecorder ,我最終不得不更換它。 AVAudioRecorder是一個通用的錄音課程,所以一旦你的要求變得有點專業化,它就會讓你失望。

然而,它確實做了計量,這吸引了很多人。 所以也許這種情況可以得到挽救。

可能性:

一個。 如果currentTime不值得信賴,那就不要觀察了! 你有5秒鍾的文件,所以也許可以找到一些其他的方法來標記你的應用程序中的那段時間。

屬性currentTime ,頭文件說:

  only valid while recording 

您是否只在錄制時采樣currentTime 如果是這樣可能是問題。 在這種情況下,您可以使用deviceCurrentTime屬性,該屬性始終有效,但您必須減去初始的deviceCurrentTime

如果AVAudioRecorder這種情況,你可以很快用AVAudioEngineAVAudioFile替換AVAudioFile ,但這是另一天的問題。

我在定時器上更新的 UILabel 遇到了同樣的問題,但能夠通過檢查定時器觸發器之間的間隙是否太大並將增量記住為 currentRecordTimeOffset 來解決它。

     if ( self.recorder.recording ) {
         float adjustedRecordTime = self.recorder.currentTime;
         if(self.currentRecordTimeOffset == 0){
             if(self.recorder.currentTime - self.lastRecordedTime > 1.0){    // current time should be updated every 0.1 so a 1 Sec delta indicates offset needed
                 self.currentRecordTimeOffset = self.recorder.currentTime;
                 adjustedRecordTime = self.recorder.currentTime - self.currentRecordTimeOffset;
             }
         }
         else{
             adjustedRecordTime = self.recorder.currentTime - self.currentRecordTimeOffset;     // get rid of the unusual offset
         }
         self.lastRecordedTime = self.recorder.currentTime;
         self.durationLabel.text = [NSString stringWithFormat:@"%.2f", adjustedRecordTime];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM