Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(darwin): Start observing AVPlayerItem.status before being assigned to AVPlayer #1549

Merged
merged 27 commits into from
Sep 26, 2023
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
83ff794
fix: start observing `AVPlayerItem.status` before setting it on `AVPl…
blaugold Jun 17, 2023
257a6a7
Remove debug print
blaugold Jun 17, 2023
aa9449c
Fix spelling
blaugold Jun 19, 2023
d8ff1a7
Merge branch 'main' into fix/player-item-status
Gustl22 Jul 28, 2023
711fe1f
chore: update darwin dependencies
Gustl22 Jul 28, 2023
58b1868
refactor(darwin): cast maps
Gustl22 Jul 28, 2023
47388e8
refactor: format
Gustl22 Jul 28, 2023
b4eb212
refactor: rearrange methods
Gustl22 Jul 28, 2023
f2ba251
refactor: releaseSync to release
Gustl22 Jul 28, 2023
b11351a
reafactor(darwin): create player item as own method
Gustl22 Jul 28, 2023
20657c7
refactor(darwin): setUpPlayerItemStatusObservation as own method
Gustl22 Jul 28, 2023
f922ed5
refactor(darwin): setUpPositionObserver as own method
Gustl22 Jul 28, 2023
fda9f4d
refactor(darwin): setUpSoundCompletedObserver
blaugold Jul 28, 2023
51b49e7
Merge branch 'gustl22/darwin-refactor' into fix/player-item-status
Gustl22 Jul 28, 2023
dabf06f
Merge branch 'fix/player-item-status' of https://github.com/blaugold/…
Gustl22 Jul 28, 2023
ba4d121
Merge remote-tracking branch 'upstream/main' into fix/player-item-status
Gustl22 Aug 1, 2023
d4b2812
Merge branch 'main' into fix/player-item-status
Gustl22 Sep 9, 2023
3403df8
swift-format
Gustl22 Sep 9, 2023
c79df69
Merge remote-tracking branch 'upstream/main' into fix/player-item-status
Gustl22 Sep 23, 2023
69b347c
avoid catching unknown errors
Gustl22 Sep 23, 2023
2634da6
remove log
Gustl22 Sep 23, 2023
52de571
darwin: simplify assignment
Gustl22 Sep 23, 2023
00d0285
darwin: observer improvements
Gustl22 Sep 23, 2023
67478d4
darwin: Make player not nullable
Gustl22 Sep 24, 2023
2c62ba7
recreate ios folder
Gustl22 Sep 25, 2023
9429b76
recreate macos folder
Gustl22 Sep 25, 2023
98c04b6
Merge branch 'main' into fix/player-item-status
Gustl22 Sep 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,19 @@ class WrappedMediaPlayer {
var looping: Bool

private var reference: SwiftAudioplayersDarwinPlugin
private var player: AVPlayer?
private var player: AVPlayer
private var playbackRate: Double
private var volume: Double
private var url: String?

private var observers: [TimeObserver]
private var positionObserver: TimeObserver!
private var completionObserver: TimeObserver?
private var playerItemStatusObservation: NSKeyValueObservation?

init(
reference: SwiftAudioplayersDarwinPlugin,
eventHandler: AudioPlayersStreamHandler,
player: AVPlayer? = nil,
player: AVPlayer = AVPlayer.init(),
playbackRate: Double = defaultPlaybackRate,
volume: Double = defaultVolume,
looping: Bool = defaultLooping,
Expand All @@ -33,14 +34,16 @@ class WrappedMediaPlayer {
self.reference = reference
self.eventHandler = eventHandler
self.player = player
self.observers = []
self.completionObserver = nil
self.playerItemStatusObservation = nil

self.isPlaying = false
self.playbackRate = playbackRate
self.volume = volume
self.looping = looping
self.url = url

self.setUpPositionObserver(player)
}

func setSourceUrl(
Expand All @@ -49,29 +52,16 @@ class WrappedMediaPlayer {
completer: Completer? = nil,
completerError: CompleterError? = nil
) {
let playbackStatus = player?.currentItem?.status
let playbackStatus = player.currentItem?.status

if self.url != url || playbackStatus == .failed || playbackStatus == nil {
reset()
self.url = url
let playerItem = createPlayerItem(url, isLocal)
let player: AVPlayer
if let existingPlayer = self.player {
reset()
self.url = url
existingPlayer.replaceCurrentItem(with: playerItem)
player = existingPlayer
} else {
player = AVPlayer.init(playerItem: playerItem)
configParameters(player: player)

self.player = player
self.observers = []
self.url = url

setUpPositionObserver(player)
}

setUpSoundCompletedObserver(player, playerItem)
// Need to observe item status immediately after creating:
setUpPlayerItemStatusObservation(playerItem, completer, completerError)
player.replaceCurrentItem(with: playerItem)
setUpSoundCompletedObserver(self.player, playerItem)
} else {
if playbackStatus == .readyToPlay {
completer?()
Expand All @@ -95,41 +85,39 @@ class WrappedMediaPlayer {

func pause() {
isPlaying = false
player?.pause()
player.pause()
}

func resume() {
isPlaying = true
if let player = self.player {
configParameters(player: player)
if #available(iOS 10.0, macOS 10.12, *) {
player.playImmediately(atRate: Float(playbackRate))
} else {
player.play()
}
updateDuration()
configParameters(player: player)
if #available(iOS 10.0, macOS 10.12, *) {
player.playImmediately(atRate: Float(playbackRate))
} else {
player.play()
}
updateDuration()
}

func setVolume(volume: Double) {
self.volume = volume
player?.volume = Float(volume)
player.volume = Float(volume)
}

func setPlaybackRate(playbackRate: Double) {
self.playbackRate = playbackRate
player?.rate = Float(playbackRate)
player.rate = Float(playbackRate)
}

func seek(time: CMTime, completer: Completer? = nil) {
guard let currentItem = player?.currentItem else {
guard let currentItem = player.currentItem else {
completer?()
return
}
currentItem.seek(to: time) {
finished in
if !self.isPlaying {
self.player?.pause()
self.player.pause()
}
self.eventHandler.onSeekComplete()
if finished {
Expand All @@ -153,16 +141,17 @@ class WrappedMediaPlayer {

func dispose(completer: Completer? = nil) {
release {
NotificationCenter.default.removeObserver(self.positionObserver.observer)
completer?()
}
}

private func getDurationCMTime() -> CMTime? {
return player?.currentItem?.asset.duration
return player.currentItem?.asset.duration
}

private func getCurrentCMTime() -> CMTime? {
return player?.currentItem?.currentTime()
return player.currentItem?.currentTime()
}

private func createPlayerItem(_ url: String, _ isLocal: Bool) -> AVPlayerItem {
Expand All @@ -176,8 +165,7 @@ class WrappedMediaPlayer {
private func setUpPlayerItemStatusObservation(
_ playerItem: AVPlayerItem, _ completer: Completer?, _ completerError: CompleterError?
) {
let newplayerItemStatusObservation = playerItem.observe(\AVPlayerItem.status) {
(playerItem, change) in
playerItemStatusObservation = playerItem.observe(\AVPlayerItem.status) { (playerItem, change) in
let status = playerItem.status
self.eventHandler.onLog(message: "player status: \(status), change: \(change)")

Expand All @@ -192,9 +180,6 @@ class WrappedMediaPlayer {
break
}
}

playerItemStatusObservation?.invalidate()
playerItemStatusObservation = newplayerItemStatusObservation
}

private func setUpPositionObserver(_ player: AVPlayer) {
Expand All @@ -203,7 +188,7 @@ class WrappedMediaPlayer {
[weak self] time in
self?.onTimeInterval(time: time)
}
self.observers.append(TimeObserver(player: player, observer: observer))
self.positionObserver = TimeObserver(player: player, observer: observer)
}

private func setUpSoundCompletedObserver(_ player: AVPlayer, _ playerItem: AVPlayerItem) {
Expand All @@ -215,7 +200,7 @@ class WrappedMediaPlayer {
[weak self] (notification) in
self?.onSoundComplete()
}
self.observers.append(TimeObserver(player: player, observer: observer))
self.completionObserver = TimeObserver(player: player, observer: observer)
}

private func configParameters(player: AVPlayer) {
Expand All @@ -228,15 +213,15 @@ class WrappedMediaPlayer {
private func reset() {
playerItemStatusObservation?.invalidate()
playerItemStatusObservation = nil
for observer in observers {
NotificationCenter.default.removeObserver(observer.observer)
if let cObserver = completionObserver {
NotificationCenter.default.removeObserver(cObserver.observer)
completionObserver = nil
}
observers = []
player?.replaceCurrentItem(with: nil)
player.replaceCurrentItem(with: nil)
}

private func updateDuration() {
guard let duration = player?.currentItem?.asset.duration else {
guard let duration = player.currentItem?.asset.duration else {
return
}
if CMTimeGetSeconds(duration) > 0 {
Expand Down