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

时间:2017-02-03 08:30:19

标签: ios swift avplayer seek

我想用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 个答案:

答案 0 :(得分:1)

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

averageBitRate = totalBytes / duration
offset = seekTime * averageBitRate

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

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