【问题标题】:iOS 11 AVPlayer/mp3 currentTime not accurateiOS 11 AVPlayer/mp3 currentTime 不准确
【发布时间】:2017-11-07 13:02:12
【问题描述】:

我正在开发一个由动画和播放歌曲组成的卡拉 OK 应用程序。这里最重要的是两者之间非常精确的同步。

我在几个月前实现了它,在 iOS 9/10 上一切正常。我们在使用 Android 应用程序 (ExoPlayer) 时遇到了问题,因为播放和动画之间的延迟太大。最后我们发现问题是由错误的歌曲格式(mp3)引起的 - 在这里解释:https://github.com/google/ExoPlayer/issues/3233。我们通过将歌曲打包成 mp4 格式来修复它(在 iOS 上仍然使用 mp3)。

我将 AVPlayer 与 HLS 一起使用

self.player = AVPlayer(url: url)

//
var currentTime_: Double {
    if let player = self.player {
        return player.currentTime().seconds
    }

    return 0
}

在 iOS 11 发布之前一切正常。在 iOS 11 上存在与 Android 上相同的去同步化(player.currentTime 不准确)。 有趣的是,即使是基于 iOS 10 SDK 构建并在 AppStore 上可用的应用程序也无法在 iOS 11 上正常运行 - 但它在 iOS 10 上仍然运行良好。

服务器端没有任何改变。所以苹果不得不在解码/缓冲方面做出一些改变。现在我们正在努力改变音频格式/解码,但我仍然很好奇 - 为什么会发生这种情况?有人遇到过类似情况吗?

问候

【问题讨论】:

    标签: android ios synchronization delay avplayer


    【解决方案1】:

    创建 AVURLAsset 时需要使用该选项

    let asset = AVURLAsset(url: url, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
    

    如果不使用此选项,AVPlayer 会根据文件长度测量 mp3 音频的时长,因此获取时长的误差很小。

    【讨论】:

    • 就是这样!谢谢 ;) 所以看起来 currentTime 返回的只是百分比乘以持续时间 - 这就是它在这里导致不同步的原因。
    【解决方案2】:

    正如 woosiki 指出的那样,您需要使用 AVURLAsset。请记住,由于预先计算了精确的持续时间,加载大文件需要更长的时间。您可能需要放置一个加载器指示器。

      func prepareAudioFile(with track: Track) {
        
        guard let url = URL(string: track.streamURL) else {
          return
        }
            
        let asset = AVURLAsset(url: url,
                               options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
        
        let playerItem = AVPlayerItem(asset: asset)
    
        player = AVPlayer(playerItem: playerItem)
        observePlayerProgress()
      }
    
      private func observePlayerProgress() {
    
        let interval = CMTimeMake(value: 1, timescale: 5)
        
        player.addPeriodicTimeObserver(forInterval: interval, queue: .main) { [weak self] time in
          
          if let track = self?.player.currentItem, track.status == .readyToPlay {
            // Once the loading is finished this callback will return
            // Here you can calculate and set duration and elapsed time (track.duration, time.seconds)
          }
        }
      }
    
    

    【讨论】:

      猜你喜欢
      • 2014-08-17
      • 1970-01-01
      • 1970-01-01
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-06
      • 1970-01-01
      相关资源
      最近更新 更多