ใช้ NotificationCenter ฟัง AVPlayerItemDidPlayToEndTime Notification
โค้ดพื้นฐาน
import AVFoundation
class VideoPlayerViewController: UIViewController {
var player: AVPlayer!
var playerLayer: AVPlayerLayer!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
setupPlayer()
addObserver()
}
func setupPlayer() {
guard let url = Bundle.main.url(forResource: "video", withExtension: "mp4") else { return }
player = AVPlayer(url: url)
playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = view.bounds
playerLayer.videoGravity = .resizeAspect
view.layer.addSublayer(playerLayer)
player.play()
}
func addObserver() {
NotificationCenter.default.addObserver(
self,
selector: #selector(videoDidEnd(_:)),
name: .AVPlayerItemDidPlayToEndTime,
object: player.currentItem
)
}
@objc func videoDidEnd(_ notification: Notification) {
print("🎬 Video ended")
// Action: Replay, Show Next, Dismiss, etc.
player.seek(to: .zero)
player.play() // Loop
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
Modern Swift (Combine / Async)
import Combine
// Publisher สำหรับ Video End
extension AVPlayerItem {
var didPlayToEndTimePublisher: AnyPublisher {
NotificationCenter.default
.publisher(for: .AVPlayerItemDidPlayToEndTime, object: self)
.map { _ in () }
.eraseToAnyPublisher()
}
}
// ใช้งาน
var cancellables = Set()
player.currentItem?.didPlayToEndTimePublisher
.sink { [weak self] in
print("Video ended via Combine")
self?.handleVideoEnd()
}
.store(in: &cancellables)
การ Loop Video (AVPlayerLooper)
import AVKit
let item = AVPlayerItem(url: videoURL)
let queuePlayer = AVQueuePlayer(playerItem: item)
let looper = AVPlayerLooper(player: queuePlayer, templateItem: item)
// Loop อัตโนมัติ ไม่ต้อง Observer
Observing อื่นๆ ที่มีประโยชน์
.AVPlayerItemFailedToPlayToEndTime- เล่นล้มเหลว.AVPlayerItemNewAccessLogEntry- Network Stats.AVPlayerItemNewErrorLogEntry- Error Logsplayer.currentItem?.status- .readyToPlay, .failed, .unknown
Memory Management
- ต้อง
removeObserverในdeinit(Memory Leak) - ใช้
weak selfใน Closure - Combine: เก็บใน
cancellablesจะ Cancel อัตโนมัติ