Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 4 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ declare namespace RNTrackPlayer {
export const STATE_PAUSED: State;
export const STATE_STOPPED: State;
export const STATE_BUFFERING: State;


export const PLAYBACK_STALLED_SLOW_NETWORK: State;
export const PLAYBACK_STALLED_BEFORE_SONG_END: State;

export const RATING_HEART: RatingType;
export const RATING_THUMBS_UP_DOWN: RatingType;
export const RATING_3_STARS: RatingType;
Expand Down
8 changes: 8 additions & 0 deletions ios/RNTrackPlayer/RNTrackPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public class RNTrackPlayer: RCTEventEmitter, AudioPlayerDelegate {
sendEvent(withName: "playback-state", body: ["state": player.playerState.rawValue])
}

public func audioPlayer(playerDidStalled message: String) {
sendEvent(withName: "playback-stalled", body: ["message": message])
}

public func audioPlayer(itemPlaybackEndedWithReason reason: PlaybackEndedReason) {
if reason == .playedUntilEnd && player.nextItems.count == 0 {
sendEvent(withName: "playback-queue-ended", body: [
Expand Down Expand Up @@ -103,6 +107,9 @@ public class RNTrackPlayer: RCTEventEmitter, AudioPlayerDelegate {
"CAPABILITY_SET_RATING": "NOOP",
"CAPABILITY_JUMP_FORWARD": Capability.jumpForward.rawValue,
"CAPABILITY_JUMP_BACKWARD": Capability.jumpBackward.rawValue,

"PLAYBACK_STALLED_SLOW_NETWORK": PlaybackStalledReason.slowNetwork.rawValue,
"PLAYBACK_STALLED_BEFORE_SONG_END": PlaybackStalledReason.beforeSongEnd.rawValue
]
}

Expand All @@ -113,6 +120,7 @@ public class RNTrackPlayer: RCTEventEmitter, AudioPlayerDelegate {
"playback-state",
"playback-error",
"playback-track-changed",
"playback-stalled",

"remote-stop",
"remote-pause",
Expand Down
13 changes: 12 additions & 1 deletion ios/RNTrackPlayer/Vendor/AudioPlayer/AVPlayerWrapper/AVPlayerWrapper.swift
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class AVPlayerWrapper: AVPlayerWrapperProtocol {
// MARK: - Properties

let avPlayer: AVPlayer
var isStalled: Bool
var playAttempts: Int
let playerObserver: AVPlayerObserver
let playerTimeObserver: AVPlayerTimeObserver
let playerItemNotificationObserver: AVPlayerItemNotificationObserver
Expand All @@ -51,7 +53,8 @@ class AVPlayerWrapper: AVPlayerWrapperProtocol {
self.playerTimeObserver = AVPlayerTimeObserver(player: avPlayer, periodicObserverTimeInterval: timeEventFrequency.getTime())
self.playerItemNotificationObserver = AVPlayerItemNotificationObserver()
self.playerItemObserver = AVPlayerItemObserver()

self.playAttempts = 0
self.isStalled = false
self.playerObserver.delegate = self
self.playerTimeObserver.delegate = self
self.playerItemNotificationObserver.delegate = self
Expand Down Expand Up @@ -188,6 +191,10 @@ extension AVPlayerWrapper: AVPlayerObserverDelegate {
// MARK: - AVPlayerObserverDelegate

func player(didChangeTimeControlStatus status: AVPlayer.TimeControlStatus) {
guard !(self.isStalled == true && status == .paused) else {
self.isStalled = false
return
}
switch status {
case .paused:
if currentItem == nil {
Expand Down Expand Up @@ -246,6 +253,10 @@ extension AVPlayerWrapper: AVPlayerItemNotificationObserverDelegate {
delegate?.AVWrapper(itemPlaybackDoneWithReason: .playedUntilEnd)
}

func didStalled() {
delegate?.AVWrapper(didStalled: true)
}

}

extension AVPlayerWrapper: AVPlayerItemObserverDelegate {
Expand Down
1 change: 1 addition & 0 deletions ios/RNTrackPlayer/Vendor/AudioPlayer/AVPlayerWrapper/AVPlayerWrapperDelegate.swift
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ protocol AVPlayerWrapperDelegate: class {

func AVWrapper(didChangeState state: AVPlayerWrapperState)
func AVWrapper(itemPlaybackDoneWithReason: PlaybackEndedReason)
func AVWrapper(didStalled: Bool)
func AVWrapper(secondsElapsed seconds: Double)
func AVWrapper(failedWithError error: Error?)
func AVWrapper(seekTo seconds: Int, didFinish: Bool)
Expand Down
3 changes: 3 additions & 0 deletions ios/RNTrackPlayer/Vendor/AudioPlayer/AVPlayerWrapper/AVPlayerWrapperProtocol.swift
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ protocol AVPlayerWrapperProtocol {

var reasonForWaitingToPlay: AVPlayer.WaitingReason? { get }

var isStalled: Bool { get set }

var playAttempts: Int { get set }

var rate: Float { get set }

Expand Down
22 changes: 22 additions & 0 deletions ios/RNTrackPlayer/Vendor/AudioPlayer/AudioPlayer.swift
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@ import MediaPlayer

public typealias AudioPlayerState = AVPlayerWrapperState

public enum PlaybackStalledReason: String {
case beforeSongEnd
case slowNetwork
}

public protocol AudioPlayerDelegate: class {

func audioPlayer(playerDidChangeState state: AudioPlayerState)

func audioPlayer(itemPlaybackEndedWithReason reason: PlaybackEndedReason)

func audioPlayer(playerDidStalled: String)

func audioPlayer(secondsElapsed seconds: Double)

func audioPlayer(failedWithError error: Error?)
Expand All @@ -27,6 +34,21 @@ public protocol AudioPlayerDelegate: class {
}

public class AudioPlayer: AVPlayerWrapperDelegate {
func AVWrapper(didStalled: Bool) {
guard self.rate == 0 && self.currentTime > 0 && self.currentTime < self.duration && self.wrapper.currentItem?.isPlaybackBufferEmpty == true && self._wrapper.playAttempts < 5 else {
self._wrapper.playAttempts = 0
self._wrapper.isStalled = false
self.delegate?.audioPlayer(playerDidStalled: PlaybackStalledReason.slowNetwork.rawValue)
return
}
self._wrapper.isStalled = true
if(self._wrapper.playAttempts == 1) {
self.delegate?.audioPlayer(playerDidStalled: PlaybackStalledReason.beforeSongEnd.rawValue)
}
self._wrapper.playAttempts += 1
try? self.play()
}


private var _wrapper: AVPlayerWrapperProtocol

Expand Down
6 changes: 6 additions & 0 deletions ios/RNTrackPlayer/Vendor/AudioPlayer/Observer/AVPlayerItemNotificationObserver.swift
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import AVFoundation

protocol AVPlayerItemNotificationObserverDelegate: class {
func itemDidPlayToEndTime()
func didStalled()
}

/**
Expand All @@ -35,6 +36,7 @@ class AVPlayerItemNotificationObserver {
stopObservingCurrentItem()
observingItem = item
notificationCenter.addObserver(self, selector: #selector(itemDidPlayToEndTime), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: item)
notificationCenter.addObserver(self, selector: #selector(didStalled), name: NSNotification.Name.AVPlayerItemPlaybackStalled, object: item)
}

/**
Expand All @@ -43,6 +45,7 @@ class AVPlayerItemNotificationObserver {
func stopObservingCurrentItem() {
if let observingItem = observingItem {
notificationCenter.removeObserver(self, name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: observingItem)
notificationCenter.removeObserver(self, name: NSNotification.Name.AVPlayerItemPlaybackStalled, object: observingItem)
}
observingItem = nil
}
Expand All @@ -51,4 +54,7 @@ class AVPlayerItemNotificationObserver {
delegate?.itemDidPlayToEndTime()
}

@objc private func didStalled() {
delegate?.didStalled()
}
}
1 change: 0 additions & 1 deletion ios/RNTrackPlayer/Vendor/AudioPlayer/Observer/AVPlayerItemObserver.swift
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class AVPlayerItemObserver: NSObject {

private static var context = 0
private let main: DispatchQueue = .main

private struct AVPlayerItemKeyPath {
static let duration = #keyPath(AVPlayerItem.duration)
static let loadedTimeRanges = #keyPath(AVPlayerItem.loadedTimeRanges)
Expand Down
5 changes: 5 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ function registerEventHandler(handler) {
'playback-error',
'playback-queue-ended',
'playback-track-changed',
'playback-stalled',

'remote-play',
'remote-pause',
Expand Down Expand Up @@ -126,6 +127,10 @@ module.exports.STATE_PAUSED = TrackPlayer.STATE_PAUSED;
module.exports.STATE_STOPPED = TrackPlayer.STATE_STOPPED;
module.exports.STATE_BUFFERING = TrackPlayer.STATE_BUFFERING;

// Playback Stalled Messages
module.exports.PLAYBACK_STALLED_SLOW_NETWORK = TrackPlayer.PLAYBACK_STALLED_SLOW_NETWORK;
module.exports.PLAYBACK_STALLED_BEFORE_SONG_END = TrackPlayer.PLAYBACK_STALLED_BEFORE_SONG_END;

// Capabilities
module.exports.CAPABILITY_PLAY = TrackPlayer.CAPABILITY_PLAY;
module.exports.CAPABILITY_PLAY_FROM_ID = TrackPlayer.CAPABILITY_PLAY_FROM_ID;
Expand Down