首页 文章

avplayer seek在音频文件中播放错误的位置

提问于
浏览
2

我想用AVPlayer在iphone上播放音频文件 . 音频文件是来自设备上本地存储的mp3文件 . 我需要将它(播放的文件)与外部时间源同步 . 播放期间此时间源可能会发生变化,因此需要不时进行同步 . 我使用以下代码更改播放音频文件中的时间:

player.play()

//sth here......


//the code which is executed periodically whene it is time to synchronize
let currentShowTime = ...... //time in miliseconds
print("current show time \(currentShowTime)")
let timescale = player.currentItem!.asset.duration.timescale
let currentTime = CMTime(value:Int64(Float64(currentShowTime!) * Float64(timescale) / 1000.0), timescale:timescale)

//alternative way I count the seek time but the effect is the same
//let currentTime = CMTimeMakeWithSeconds(Float64(currentShowTime!)/1000.0, 1000)

print("currenttime \(currentTime)")
player!.seek(to: currentTime,toleranceBefore:kCMTimeZero, toleranceAfter:kCMTimeZero ){done in
  print("done: \(done)")                                                        
  print("player currenttime \(self.player!.currentItem!.currentTime().seconds)")
}

问题是音频文件播放错误 . 所有参数:当前显示时间,当前时间和播放器当前时间相同(打印相同的值) . 但我听说声音已经改变了 . 当播放文件的开头时,移位很小(可能是500毫秒),但是当它结束时(文件的20分钟),移位要大得多(大约8秒) . 我还注意到,当我提供较小的mp3文件(比特率较低)时,移位较小但是当文件质量较好时,移位最多为20秒 . 我做错了还是AVPlayer中的错误?

1 回答

  • 1

    我假设您使用的文件是VBR(可变比特率)mp3文件 . AVFoundation在寻找VBR文件方面存在问题 - 它使用

    averageBitRate = totalBytes / duration
    offset = seekTime * averageBitRate
    

    但对于VBR文件, averageBitRate 在整个文件中不是常量,因此 offset 可能会被错误计算 .

    您需要以恒定的比特率重新编码您的mp3 .

相关问题