diff --git a/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/AVPlayerItemMonitor.swift b/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/AVPlayerItemMonitor.swift index e7941521..3b3d6d72 100644 --- a/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/AVPlayerItemMonitor.swift +++ b/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/AVPlayerItemMonitor.swift @@ -8,6 +8,7 @@ final class AVPlayerItemMonitor { private let completelyDownloadedMonitor: CompletelyDownloadedMonitor private let readyToPlayMonitor: ReadyToPlayMonitor private let inStreamMetadataMonitor: DJSessionTransitionMonitor + private let playerItemDidPlayToEndTimeMonitor: ItemPlayedToEndMonitor init( _ playerItem: AVPlayerItem, @@ -15,6 +16,7 @@ final class AVPlayerItemMonitor { onStall: @escaping (AVPlayerItem) -> Void, onCompletelyDownloaded: @escaping (AVPlayerItem) -> Void, onReadyToPlayToPlay: @escaping (AVPlayerItem) -> Void, + onItemPlayedToEnd: @escaping (AVPlayerItem) -> Void, onDjSessionTransition: @escaping (AVPlayerItem, DJSessionTransition) -> Void ) { failureMonitor = FailureMonitor(playerItem, onFailure) @@ -22,6 +24,7 @@ final class AVPlayerItemMonitor { stallMonitor = StallMonitor(playerItem, onStall) completelyDownloadedMonitor = CompletelyDownloadedMonitor(playerItem, onCompletelyDownloaded) readyToPlayMonitor = ReadyToPlayMonitor(playerItem, onReadyToPlayToPlay) + playerItemDidPlayToEndTimeMonitor = ItemPlayedToEndMonitor(playerItem: playerItem, onPlayedToEnd: onItemPlayedToEnd) inStreamMetadataMonitor = DJSessionTransitionMonitor( with: playerItem, and: DispatchQueue.global(qos: .default), diff --git a/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/AVQueuePlayerWrapper.swift b/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/AVQueuePlayerWrapper.swift index a24f86e3..eef3bc37 100644 --- a/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/AVQueuePlayerWrapper.swift +++ b/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/AVQueuePlayerWrapper.swift @@ -401,6 +401,7 @@ private extension AVQueuePlayerWrapper { onStall: stalled, onCompletelyDownloaded: downloaded, onReadyToPlayToPlay: loaded, + onItemPlayedToEnd: playedToEnd, onDjSessionTransition: receivedDjSessionTransition ) } @@ -631,6 +632,12 @@ private extension AVQueuePlayerWrapper { self.delegates.djSessionTransition(asset: asset, transition: transition) } } + + func playedToEnd(playerItem: AVPlayerItem) { + if featureFlagProvider.shouldNotPerformActionAtItemEnd() { + self.player.remove(playerItem) + } + } } // MARK: AssetFactoryDelegate diff --git a/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/Legacy/AVQueuePlayerWrapperLegacy.swift b/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/Legacy/AVQueuePlayerWrapperLegacy.swift index 12803bc3..d51aa56b 100644 --- a/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/Legacy/AVQueuePlayerWrapperLegacy.swift +++ b/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/Legacy/AVQueuePlayerWrapperLegacy.swift @@ -372,6 +372,7 @@ private extension AVQueuePlayerWrapperLegacy { onStall: stalled, onCompletelyDownloaded: downloaded, onReadyToPlayToPlay: loaded, + onItemPlayedToEnd: playedToEnd, onDjSessionTransition: receivedDjSessionTransition ) } @@ -530,6 +531,8 @@ private extension AVQueuePlayerWrapperLegacy { let asset = self.playerItemAssets.removeValue(forKey: oldPlayerItem) self.delegates.completed(asset: asset) + self.player.remove(oldPlayerItem) + guard let newPlayerItem = self.player.currentItem else { self.reset() return @@ -560,6 +563,12 @@ private extension AVQueuePlayerWrapperLegacy { self.delegates.djSessionTransition(asset: asset, transition: transition) } } + + func playedToEnd(playerItem: AVPlayerItem) { + if featureFlagProvider.shouldNotPerformActionAtItemEnd() { + self.player.remove(playerItem) + } + } } private extension AVQueuePlayerWrapperLegacy { diff --git a/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/Observers/ItemPlayedToEndMonitor.swift b/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/Observers/ItemPlayedToEndMonitor.swift new file mode 100644 index 00000000..2739a598 --- /dev/null +++ b/Sources/Player/PlaybackEngine/Internal/AVQueuePlayer/Observers/ItemPlayedToEndMonitor.swift @@ -0,0 +1,34 @@ +import AVFoundation +import Foundation + +final class ItemPlayedToEndMonitor { + private let playerItem: AVPlayerItem + private let onPlayedToEnd: (AVPlayerItem) -> Void + + init(playerItem: AVPlayerItem, onPlayedToEnd: @escaping (AVPlayerItem) -> Void) { + self.playerItem = playerItem + self.onPlayedToEnd = onPlayedToEnd + + NotificationCenter.default.addObserver( + self, + selector: #selector(playerItemDidPlayToEndTime(notification:)), + name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, + object: playerItem + ) + } + + deinit { + NotificationCenter.default.removeObserver( + self, + name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, + object: playerItem + ) + } + + @objc + private func playerItemDidPlayToEndTime(notification: Notification) { + if let playerItem = notification.object as? AVPlayerItem { + onPlayedToEnd(playerItem) + } + } +}