gpt4 book ai didi

ios - 在 AVPlayerLooper 上更新 timeRange 属性的推荐方法

转载 作者:行者123 更新时间:2023-11-28 15:02:29 24 4
gpt4 key购买 nike

我正在构建 AVPlayerLooper example code Apple 提供,特别是利用他们在 PlayerLooper.swiftLooperViewController.swiftLooper.swift 协议(protocol)中为您提供的示例 AVPlayerLooper 设置.

我想做的是能够更新在 PlayerLooper.swift 文件中实例化的 AVPlayerLooper 的 timeRange 属性。

为此,我稍微修改了以下实例化并启动播放器循环器的函数:

func start(in parentLayer: CALayer, loopTimeRange: CMTimeRange) {
player = AVQueuePlayer()
playerLayer = AVPlayerLayer(player: player)

guard let playerLayer = playerLayer else { fatalError("Error creating player layer") }
playerLayer.frame = parentLayer.bounds
parentLayer.addSublayer(playerLayer)

let playerItem = AVPlayerItem(url: videoURL)
playerItem.asset.loadValuesAsynchronously(forKeys: [ObserverContexts.playerItemDurationKey], completionHandler: {()->Void in
/*
The asset invokes its completion handler on an arbitrary queue when
loading is complete. Because we want to access our AVPlayerLooper
in our ensuing set-up, we must dispatch our handler to the main queue.
*/
DispatchQueue.main.async(execute: {
guard let player = self.player else { return }

var durationError: NSError? = nil
let durationStatus = playerItem.asset.statusOfValue(forKey: ObserverContexts.playerItemDurationKey, error: &durationError)
guard durationStatus == .loaded else { fatalError("Failed to load duration property with error: \(String(describing: durationError))") }

//self.playerLooper = AVPlayerLooper(player: player, templateItem: playerItem)

self.playerLooper = AVPlayerLooper(player: player, templateItem: playerItem, timeRange: loopTimeRange)

self.startObserving()
player.play()
})
})
}

出于演示目的,在 LooperViewController 中,我创建了一个简单的按钮,它使用新的 CMTimeRange 触发 looper?.start(),如下所示:

looper?.start(in: view.layer, loopTimeRange: CMTimeRange(start: CMTime(value: 0, timescale: 600), duration: CMTime(value: 3000, timescale: 600)))

然而,在调用该函数之前,我调用了 looper?.stop(),它执行以下操作:

func stop() {
player?.pause()
stopObserving()

playerLooper?.disableLooping()
playerLooper = nil

playerLayer?.removeFromSuperlayer()
playerLayer = nil

player = nil
}

我基本上是完全重新实例化 AVPlayerLooper 以便设置新的 timeRange 属性,因为我看不到任何方法来实际访问和重置该属性,一旦它被第一次设置。

问题是,虽然这似乎最初有效并且循环播放器将调整并开始循环播放新的时间范围,但它最终会在循环几次后停止播放。任何地方都不会抛出任何错误,并且代码中已经设置的观察者都没有报告循环正在停止或循环有一些错误。

我的做法完全错误吗? AVPlayerLooper 是要以这种方式进行调整还是我应该寻找另一种方法来拥有可调整的循环播放器?

最佳答案

您实际上可以更新 AVPlayerLooper 而无需拆除整个东西。您需要做的是先从 AVQueuePlayer 中删除所有项目,然后使用新的时间范围重新实例化循环器。像这样:

if self.avQueuePlayer.rate == 0 {
self.avQueuePlayer.removeAllItems()
let range = CMTimeRange(start: self.startTime, end: self.endTime)
self.avPlayerLooper = AVPlayerLooper(player: self.avQueuePlayer, templateItem: self.avPlayerItem, timeRange: range)
self.avQueuePlayer.play()
}

您必须确保 removeAllItems() 否则它会崩溃。否则这将更改时间范围,同时允许您使用当前层等设置来查看播放器。

关于ios - 在 AVPlayerLooper 上更新 timeRange 属性的推荐方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48759288/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com