AVPlayer 在 iOS 15.4 中寻求 completionHandler 返回 false
AVPlayer seek completionHandler returning false in iOS 15.4
我们正在尝试在我们的 SwiftUI 应用程序中实现 AVPlayer 搜索,它在 iOS 15.4 之前有效,但在更新之后无效。
let playerCurrentTime = CMTimeGetSeconds(player.currentTime())
let newTime = playerCurrentTime + 45
let time2: CMTime = CMTimeMake(value: Int64(newTime * 1000 as Float64), timescale: 1000)
player.seek(to: time2, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) { success in
print(success)
}
completionHandler 被立即调用,success = false。
没有其他seek操作运行,AVPlayer状态为readyToPlay.
我们正在使用以下初始化代码从 URL 流式传输 MP3 文件:
playerItem = AVPlayerItem(url: url)
player = AVPlayer(playerItem: playerItem)
player.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 2), queue: DispatchQueue.main) { _ in
if self.player.currentItem?.status == .readyToPlay {
self.currentTimeInSeconds = CMTimeGetSeconds(self.player.currentTime())
self.progressInPct = Double(self.currentTimeInSeconds) / Double(self.totalTimeInSeconds)
self.nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = 1
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
self.setupNowPlaying()
} else {
self.nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = 0
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
}
}
我们也尝试在 currentItem 上搜索,但这也没有用。
player.currentItem?.seek(to: time, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero)
有没有其他人遇到过这样的事情,有什么指点吗?
更新:
尝试进行完整的简单尝试,但结果仍然相同:
struct testView: View {
var player = AVPlayer()
var body: some View {
Button {
self.startPlayer(url: episode.streamUrl!)
}
label: {
Text("Test")
}
}
func startPlayer(url: String) {
let playerItem = AVPlayerItem(url: URL(string: url) !)
self.player.replaceCurrentItem(with: playerItem)
player.play()
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
let time2: CMTime = CMTimeMake(value: Int64(45 * 1000 as Float64), timescale: 1000)
player.seek(to: time2, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) {
success in
print(success)
}
}
}
}
打印“假”。
为了进行比较,我附上了一段用于时间观察和 3 种搜索功能的代码。到目前为止,它在 iOS 15.4 上运行良好(尽管在 UIKit 和 .m3u8 播放列表上)。希望它能以某种方式帮助你。
求函数:
func seek1() {
let videoDuration = (avPlayer.currentItem?.duration.seconds ?? 0)!
let elapsedTime: Float64 = videoDuration * Float64(archiveControlsView.seekSlider.value)
let toTime = CMTime.init(seconds: elapsedTime,
preferredTimescale: 100)
avPlayer.seek(to: toTime,completionHandler: { (completed: Bool) -> Void in
//do whatever you need
})
}
func seek2() {
let diff: TimeInterval = 60
self.avPlayer.seek(to: CMTime.init(seconds: diff, preferredTimescale: 100))
}
func seekToZero() {
self.avPlayer.seek(to: kCMTimeZero)
}
时间观测功能
var timeObserver: AnyObject!
func createTimer() {
let timeInterval: CMTime = CMTime.init(seconds: 1.0, preferredTimescale: 10)
timeObserver = avPlayer.addPeriodicTimeObserver(forInterval: timeInterval,
queue: DispatchQueue.main) {
(elapsedTime: CMTime) -> Void in
guard self.status != .Seeking else { return }
self.observeTime(elapsedTime)
let duration = (self.avPlayer.currentItem?.duration.seconds ?? 0)!
let elapsedTime = elapsedTime.seconds
// do whatever you need with elapsed and duration
} as AnyObject?
}
我们正在尝试在我们的 SwiftUI 应用程序中实现 AVPlayer 搜索,它在 iOS 15.4 之前有效,但在更新之后无效。
let playerCurrentTime = CMTimeGetSeconds(player.currentTime())
let newTime = playerCurrentTime + 45
let time2: CMTime = CMTimeMake(value: Int64(newTime * 1000 as Float64), timescale: 1000)
player.seek(to: time2, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) { success in
print(success)
}
completionHandler 被立即调用,success = false。 没有其他seek操作运行,AVPlayer状态为readyToPlay.
我们正在使用以下初始化代码从 URL 流式传输 MP3 文件:
playerItem = AVPlayerItem(url: url)
player = AVPlayer(playerItem: playerItem)
player.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 2), queue: DispatchQueue.main) { _ in
if self.player.currentItem?.status == .readyToPlay {
self.currentTimeInSeconds = CMTimeGetSeconds(self.player.currentTime())
self.progressInPct = Double(self.currentTimeInSeconds) / Double(self.totalTimeInSeconds)
self.nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = 1
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
self.setupNowPlaying()
} else {
self.nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = 0
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
}
}
我们也尝试在 currentItem 上搜索,但这也没有用。
player.currentItem?.seek(to: time, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero)
有没有其他人遇到过这样的事情,有什么指点吗?
更新: 尝试进行完整的简单尝试,但结果仍然相同:
struct testView: View {
var player = AVPlayer()
var body: some View {
Button {
self.startPlayer(url: episode.streamUrl!)
}
label: {
Text("Test")
}
}
func startPlayer(url: String) {
let playerItem = AVPlayerItem(url: URL(string: url) !)
self.player.replaceCurrentItem(with: playerItem)
player.play()
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
let time2: CMTime = CMTimeMake(value: Int64(45 * 1000 as Float64), timescale: 1000)
player.seek(to: time2, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero) {
success in
print(success)
}
}
}
}
打印“假”。
为了进行比较,我附上了一段用于时间观察和 3 种搜索功能的代码。到目前为止,它在 iOS 15.4 上运行良好(尽管在 UIKit 和 .m3u8 播放列表上)。希望它能以某种方式帮助你。
求函数:
func seek1() { let videoDuration = (avPlayer.currentItem?.duration.seconds ?? 0)! let elapsedTime: Float64 = videoDuration * Float64(archiveControlsView.seekSlider.value) let toTime = CMTime.init(seconds: elapsedTime, preferredTimescale: 100) avPlayer.seek(to: toTime,completionHandler: { (completed: Bool) -> Void in //do whatever you need }) } func seek2() { let diff: TimeInterval = 60 self.avPlayer.seek(to: CMTime.init(seconds: diff, preferredTimescale: 100)) } func seekToZero() { self.avPlayer.seek(to: kCMTimeZero) }
时间观测功能
var timeObserver: AnyObject! func createTimer() { let timeInterval: CMTime = CMTime.init(seconds: 1.0, preferredTimescale: 10) timeObserver = avPlayer.addPeriodicTimeObserver(forInterval: timeInterval, queue: DispatchQueue.main) { (elapsedTime: CMTime) -> Void in guard self.status != .Seeking else { return } self.observeTime(elapsedTime) let duration = (self.avPlayer.currentItem?.duration.seconds ?? 0)! let elapsedTime = elapsedTime.seconds // do whatever you need with elapsed and duration } as AnyObject? }