简体   繁体   English

AVPlayer未同步

[英]AVPlayer not synchronized

I'm really out of ideas so I'll have to ask you guys again... 我真的没有想法,所以我不得不再问你们......

I'm building an iPhone application which uses three instances of AVPlayer. 我正在构建一个使用三个AVPlayer实例的iPhone应用程序。 They all play at the same time and it's very important that they do so. 他们都在同一时间玩,他们这样做是非常重要的。 I used to run this code: 我以前运行这段代码:

CMClockRef syncTime = CMClockGetHostTimeClock();
CMTime hostTime = CMClockGetTime(hostTime);
[self.playerOne setRate:1.0f time:kCMTimeInvalid atHostTime:hostTime];
[self.playerTwo setRate:1.0f time:kCMTimeInvalid atHostTime:hostTime];
[self.playerThree setRate:1.0f time:kCMTimeInvalid atHostTime:hostTime];

which worked perfectly. 这很完美。 But a few days ago it just stopped working, the three players are delayed by about 300-400ms (which is way to much, everything under 100ms would be okay). 但是几天前它刚停止工作,三个玩家被推迟了大约300-400ms(这是很多,100ms以下的一切都没问题)。 Two of these AVPlayer have some Audio processing, which takes some time more than the "normal" AVPlayer, but it used to work before and the currentTime property tells me, that these players are delayed, so the syncing seems to fail. 其中两个AVPlayer有一些音频处理,比“普通”AVPlayer需要花费一些时间,但它曾经工作过,而且currentTime属性告诉我,这些播放器都被延迟了,所以同步似乎失败了。

I have no idea why it stopped working, I didn't really changed something, but I'm using an observer where i can ask the self.playerX.currentTime property, which gives me a delay of about .3-.4 seconds... I already tried to resync the players if delay>.1f but the delay is still there. 我不知道它为什么停止工作,我没有真正改变一些东西,但我正在使用一个观察者,我可以询问self.playerX.currentTime属性,这给了我大约.3-.4秒的延迟。 ..如果延迟> .1f,我已经尝试重新同步玩家,但延迟仍在那里。 So I think the audio processing of player1 and 2 can't be responsable for the delay, as the currentTime property does know they are delayed (i hope you know what I mean). 所以我认为播放器1和2的音频处理不能对延迟负责,因为currentTime属性确实知道它们被延迟了(我希望你知道我的意思)。 Maybe someone of you guys know why I'm having such a horrible delay, or is able to provide me another idea. 也许你们中的某些人知道为什么我有这么可怕的延迟,或者能够给我另一个想法。

Thanks in advance! 提前致谢!

So, I found the solution. 所以,我找到了解决方案。 I forgot to [self.playerX prerollAtRate:]. 我忘了[self.playerX prerollAtRate:]。 I thought if the observer is AVPlayerReadyToPlay it means, that the player is "really" ready. 我想如果观察者是AVPlayerReadyToPlay意味着玩家“真的”准备好了。 In fact, it does not. 事实上,它没有。 After AVPlayer is readyToPlay, it has to be pre rolled. 在AVPlayer readyToPlay之后,它必须预先滚动。 Once that is done you can sync your placer. 完成后,您可以同步您的布局器。 The delay is now somewhere at 0.000006 seconds. 延迟现在是0.000006秒。

Full func to sync avplayer's across multiple iOS devices 全功能可在多个iOS设备上同步avplayer

private func startTribePlayer() {
    let dateFormatterGet = DateFormatter()
    dateFormatterGet.dateFormat = "yyyy-MM-dd"
    guard let refDate = dateFormatterGet.date(from: "2019-01-01") else { return }
    let tsRef = Date().timeIntervalSince(refDate)
    //currentDuration is avplayeritem.duration().seconds
    let remainder = tsRef.truncatingRemainder(dividingBy: currentDuration)
    let ratio = remainder / currentDuration
    let seekTime = ratio * currentDuration
    let bufferTime = 0.5
    let bufferSeekTime = seekTime + bufferTime
    let mulFactor = 10000.0
    let timeScale = CMTimeScale(mulFactor)
    let seekCMTime = CMTime(value: CMTimeValue(CGFloat(bufferSeekTime * mulFactor)), timescale: timeScale)
    let syncTime = CMClockGetHostTimeClock()
    let hostTime = CMClockGetTime(syncTime)
    tribeMusicPlayer?.seek(to: seekCMTime, toleranceBefore: .zero, toleranceAfter: .zero, completionHandler: { [weak self] (successSeek) in
        guard let tvc = self, tvc.tribeMusicPlayer?.currentItem?.status == .readyToPlay else { return }
        tvc.tribeMusicPlayer?.preroll(atRate: 1.0, completionHandler: { [tvc] (successPreroll) in
            tvc.tribePlayerDidPlay = true
            tvc.tribeMusicPlayer?.setRate(1.0, time: seekCMTime, atHostTime: hostTime)
        })
    })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM