[英]Avplayer AVPlayerItemDidPlayToEndTime notificaton not sending message to observer
我正在使用AVQueuePlayer
播放遠程音頻文件列表。 我想默認實現重復所有。
我的方法是,我正在觀察AVPlayerItemDidPlayToEndTime
通知,並在播放完畢后將 playerItem 添加到隊列的后面。
nextAudio(notification: Notification)
根本沒有運行。 需要這方面的幫助,或者更好的方式來實現無限游戲。
func playAudio(_ items: [AVPlayerItem]) {
let avPlayerVC = AVPlayerViewController()
let player = AVQueuePlayer(items: items)
player.actionAtItemEnd = .pause
avPlayerVC.player = player
for item in items {
NotificationCenter.default.addObserver(self,
selector: #selector(FilesViewController.nextAudio(notification:)),
name: .AVPlayerItemDidPlayToEndTime, object: item)
}
present(avPlayerVC, animated: true) {
self.player.play()
}
}
@objc func nextAudio(notification: Notification) {
debugPrint("nextAudio was called")
guard player != nil else { return }
debugPrint("AVPlayerItemDidPlayToEndTime notif info \(notification.userInfo)")
if let currentItem = notification.userInfo!["object"] as? AVPlayerItem {
currentItem.seek(to: kCMTimeZero)
self.player.advanceToNextItem()
self.player.insert(currentItem, after: nil)
}
}
我相信你已經明白了,但我只是遇到了自己,並決定回答:
當您指定通知對象時,它看起來似乎沒有傳遞(順便說一句,這應該是一種正確的方式)。 可能是iOS中的一個錯誤...
你需要通過nil
代替:
NotificationCenter.default.addObserver(self, selector: #selector(videoDidPlayToEnd), name: .AVPlayerItemDidPlayToEndTime, object: nil)
然后在方法中,您應該檢查通知的對象是您的播放器項目。 文檔實際上並不一致,因為 Apple 聲明通知的對象是AVplayer
但它是AVPlayerItem
:
@objc
private func videoDidPlayToEnd(_ notification: Notification) {
guard let playerItem = notification.object as? AVPlayerItem, let urlAsset = playerItem.asset as? AVURLAsset else { return }
gpLog("Sender urlAsset: \(urlAsset.url.absoluteString)")
// Compare an asset URL.
}
謝謝@Lukasz 的精彩回答! 我遇到了多個視頻在錯誤時間觸發通知的問題。 你的回答幫助我解決了它。
如果有人正在尋找如何在SwiftUI 中使用它的示例,這里是我的代碼:
首先創建一個播放器:
import SwiftUI
import AVKit
struct VideoPlayer : UIViewControllerRepresentable {
func makeCoordinator() -> VideoPlayer.Coordinator {
return VideoPlayer.Coordinator(parent1: self)
}
@Binding var didFinishVideo : Bool
@Binding var player : AVPlayer
var play: Bool
var loop: Bool
var videoName: String
var controller = AVPlayerViewController()
func makeUIViewController(context: UIViewControllerRepresentableContext<VideoPlayer>) -> AVPlayerViewController {
controller.player = player
controller.showsPlaybackControls = false
controller.videoGravity = .resize
NotificationCenter.default.addObserver(context.coordinator, selector: #selector(context.coordinator.playerDidFinishPlaying(_:)), name: .AVPlayerItemDidPlayToEndTime, object: nil)
return controller
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<VideoPlayer>) {
if play {
player.play()
}
}
class Coordinator : NSObject{
var parent : VideoPlayer
init(parent1 : VideoPlayer) {
parent = parent1
}
@objc func playerDidFinishPlaying(_ notification: Notification) {
guard let playerItem = notification.object as? AVPlayerItem, let urlAsset = playerItem.asset as? AVURLAsset else { return }
print("Sender urlAsset: \(urlAsset.url.absoluteString)")
if urlAsset.url.absoluteString.contains(parent.videoName) {
if parent.loop {
parent.player.seek(to: CMTime.zero)
parent.player.play()
} else {
parent.didFinishVideo = true
}
}
}
}
}
您可以使用它來創建多個視頻,如下所示:
import SwiftUI
import AVKit
struct ExampleVideo: View {
@Binding var didFinishVideo : Bool
var play: Bool
@State private var player = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "exampleVideoFileName", ofType: "mp4")!))
var body: some View {
VideoPlayer(didFinishVideo: $didFinishVideo, player: $player, play: play, loop: false, videoName: "exampleVideoFileName")
}
}
struct ExampleVideo_Previews: PreviewProvider {
static var previews: some View {
CeveraIntroVideo(didFinishVideo: .constant(true), play: true)
}
}
這是在加載某些內容后在視圖中使用它的示例:
struct IntroScreens: View {
@State var loadingComplete = false
@State var didFinishVideo = false
var body: some View {
ZStack{
ExampleVideo(didFinishVideo: $didFinishVideo, play: loadingComplete)
.zIndex(loadingComplete ? 3 : 0)
.animation(Animation.easeInOut(duration: 1))
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.