mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-09-01 07:30:00 +02:00
Added sleep timer
This commit is contained in:
parent
9701c767b2
commit
4203654ec8
4 changed files with 124 additions and 41 deletions
|
@ -23,4 +23,10 @@ CAP_PLUGIN(AbsAudioPlayer, "AbsAudioPlayer",
|
||||||
CAP_PLUGIN_METHOD(seekBackward, CAPPluginReturnPromise);
|
CAP_PLUGIN_METHOD(seekBackward, CAPPluginReturnPromise);
|
||||||
|
|
||||||
CAP_PLUGIN_METHOD(getCurrentTime, CAPPluginReturnPromise);
|
CAP_PLUGIN_METHOD(getCurrentTime, CAPPluginReturnPromise);
|
||||||
|
|
||||||
|
CAP_PLUGIN_METHOD(cancelSleepTimer, CAPPluginReturnPromise);
|
||||||
|
CAP_PLUGIN_METHOD(decreaseSleepTime, CAPPluginReturnPromise);
|
||||||
|
CAP_PLUGIN_METHOD(increaseSleepTime, CAPPluginReturnPromise);
|
||||||
|
CAP_PLUGIN_METHOD(getSleepTimerTime, CAPPluginReturnPromise);
|
||||||
|
CAP_PLUGIN_METHOD(setSleepTimer, CAPPluginReturnPromise);
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,9 +13,12 @@ public class AbsAudioPlayer: CAPPlugin {
|
||||||
override public func load() {
|
override public func load() {
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(sendMetadata), name: NSNotification.Name(PlayerEvents.update.rawValue), object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(sendMetadata), name: NSNotification.Name(PlayerEvents.update.rawValue), object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(sendPlaybackClosedEvent), name: NSNotification.Name(PlayerEvents.closed.rawValue), object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(sendPlaybackClosedEvent), name: NSNotification.Name(PlayerEvents.closed.rawValue), object: nil)
|
||||||
self.bridge?.webView?.allowsBackForwardNavigationGestures = true;
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(sendMetadata), name: UIApplication.didBecomeActiveNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(sendMetadata), name: UIApplication.didBecomeActiveNotification, object: nil)
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(sendMetadata), name: UIApplication.willEnterForegroundNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(sendMetadata), name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(sendSleepTimerSet), name: NSNotification.Name(PlayerEvents.sleepSet.rawValue), object: nil)
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(sendSleepTimerEnded), name: NSNotification.Name(PlayerEvents.sleepEnded.rawValue), object: nil)
|
||||||
|
|
||||||
|
self.bridge?.webView?.allowsBackForwardNavigationGestures = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func prepareLibraryItem(_ call: CAPPluginCall) {
|
@objc func prepareLibraryItem(_ call: CAPPluginCall) {
|
||||||
|
@ -69,15 +72,15 @@ public class AbsAudioPlayer: CAPPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func playPause(_ call: CAPPluginCall) {
|
@objc func playPause(_ call: CAPPluginCall) {
|
||||||
PlayerHandler.playPause()
|
PlayerHandler.paused = !PlayerHandler.paused
|
||||||
call.resolve([ "playing": !PlayerHandler.paused() ])
|
call.resolve([ "playing": !PlayerHandler.paused ])
|
||||||
}
|
}
|
||||||
@objc func playPlayer(_ call: CAPPluginCall) {
|
@objc func playPlayer(_ call: CAPPluginCall) {
|
||||||
PlayerHandler.play()
|
PlayerHandler.paused = false
|
||||||
call.resolve()
|
call.resolve()
|
||||||
}
|
}
|
||||||
@objc func pausePlayer(_ call: CAPPluginCall) {
|
@objc func pausePlayer(_ call: CAPPluginCall) {
|
||||||
PlayerHandler.pause()
|
PlayerHandler.paused = true
|
||||||
call.resolve()
|
call.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,13 +98,69 @@ public class AbsAudioPlayer: CAPPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func sendMetadata() {
|
@objc func sendMetadata() {
|
||||||
self.notifyListeners("onPlayingUpdate", data: [ "value": !PlayerHandler.paused() ])
|
self.notifyListeners("onPlayingUpdate", data: [ "value": !PlayerHandler.paused ])
|
||||||
self.notifyListeners("onMetadata", data: PlayerHandler.getMetdata())
|
self.notifyListeners("onMetadata", data: PlayerHandler.getMetdata())
|
||||||
}
|
}
|
||||||
@objc func sendPlaybackClosedEvent() {
|
@objc func sendPlaybackClosedEvent() {
|
||||||
self.notifyListeners("onPlaybackClosed", data: [ "value": true ])
|
self.notifyListeners("onPlaybackClosed", data: [ "value": true ])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func decreaseSleepTime(_ call: CAPPluginCall) {
|
||||||
|
guard let timeString = call.getString("time") else { return call.resolve([ "success": false ]) }
|
||||||
|
guard let time = Int(timeString) else { return call.resolve([ "success": false ]) }
|
||||||
|
guard let currentSleepTime = PlayerHandler.remainingSleepTime else { return call.resolve([ "success": false ]) }
|
||||||
|
|
||||||
|
PlayerHandler.remainingSleepTime = currentSleepTime - time
|
||||||
|
call.resolve()
|
||||||
|
}
|
||||||
|
@objc func increaseSleepTime(_ call: CAPPluginCall) {
|
||||||
|
guard let timeString = call.getString("time") else { return call.resolve([ "success": false ]) }
|
||||||
|
guard let time = Int(timeString) else { return call.resolve([ "success": false ]) }
|
||||||
|
guard let currentSleepTime = PlayerHandler.remainingSleepTime else { return call.resolve([ "success": false ]) }
|
||||||
|
|
||||||
|
PlayerHandler.remainingSleepTime = currentSleepTime + time
|
||||||
|
call.resolve()
|
||||||
|
}
|
||||||
|
@objc func setSleepTimer(_ call: CAPPluginCall) {
|
||||||
|
guard let timeString = call.getString("time") else { return call.resolve([ "success": false ]) }
|
||||||
|
guard let time = Int(timeString) else { return call.resolve([ "success": false ]) }
|
||||||
|
|
||||||
|
NSLog("chapter time: \(call.getBool("isChapterTime", false))")
|
||||||
|
|
||||||
|
if call.getBool("isChapterTime", false) {
|
||||||
|
let timeToPause = time / 1000 - Int(PlayerHandler.getCurrentTime() ?? 0)
|
||||||
|
if timeToPause < 0 { return call.resolve([ "success": false ]) }
|
||||||
|
|
||||||
|
NSLog("oof \(timeToPause)")
|
||||||
|
|
||||||
|
PlayerHandler.remainingSleepTime = timeToPause
|
||||||
|
return call.resolve([ "success": true ])
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerHandler.remainingSleepTime = time / 1000
|
||||||
|
call.resolve([ "success": true ])
|
||||||
|
}
|
||||||
|
@objc func cancelSleepTimer(_ call: CAPPluginCall) {
|
||||||
|
PlayerHandler.remainingSleepTime = nil
|
||||||
|
call.resolve()
|
||||||
|
}
|
||||||
|
@objc func getSleepTimerTime(_ call: CAPPluginCall) {
|
||||||
|
call.resolve([
|
||||||
|
"value": PlayerHandler.remainingSleepTime
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func sendSleepTimerEnded() {
|
||||||
|
self.notifyListeners("onSleepTimerEnded", data: [
|
||||||
|
"value": PlayerHandler.getCurrentTime()
|
||||||
|
])
|
||||||
|
}
|
||||||
|
@objc func sendSleepTimerSet() {
|
||||||
|
self.notifyListeners("onSleepTimerSet", data: [
|
||||||
|
"value": PlayerHandler.remainingSleepTime
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
@objc func sendPrepareMetadataEvent(itemId: String, playWhenReady: Bool) {
|
@objc func sendPrepareMetadataEvent(itemId: String, playWhenReady: Bool) {
|
||||||
self.notifyListeners("onPrepareMedia", data: [
|
self.notifyListeners("onPrepareMedia", data: [
|
||||||
"audiobookId": itemId,
|
"audiobookId": itemId,
|
||||||
|
@ -115,11 +174,11 @@ public class AbsAudioPlayer: CAPPlugin {
|
||||||
/*
|
/*
|
||||||
IMPLEMENTED:
|
IMPLEMENTED:
|
||||||
|
|
||||||
cancelSleepTimer
|
* cancelSleepTimer
|
||||||
decreaseSleepTime
|
decreaseSleepTime (millis)
|
||||||
increaseSleepTime
|
increaseSleepTime (millis)
|
||||||
getSleepTimerTime
|
* getSleepTimerTime (millis)
|
||||||
setSleepTimer
|
* setSleepTimer (millis)
|
||||||
* closePlayback
|
* closePlayback
|
||||||
* setPlaybackSpeed
|
* setPlaybackSpeed
|
||||||
* seekBackward
|
* seekBackward
|
||||||
|
@ -136,7 +195,7 @@ public class AbsAudioPlayer: CAPPlugin {
|
||||||
* onPlaybackClosed
|
* onPlaybackClosed
|
||||||
* onPlayingUpdate
|
* onPlayingUpdate
|
||||||
* onMetadata
|
* onMetadata
|
||||||
onSleepTimerEnded
|
onSleepTimerEnded (millis)
|
||||||
onSleepTimerSet
|
onSleepTimerSet (millis)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,39 @@ class PlayerHandler {
|
||||||
private static var session: PlaybackSession?
|
private static var session: PlaybackSession?
|
||||||
private static var timer: Timer?
|
private static var timer: Timer?
|
||||||
|
|
||||||
private static var listeningTimePassedSinceLastSync = 0.0
|
private static var _remainingSleepTime: Int? = nil
|
||||||
|
public static var remainingSleepTime: Int? {
|
||||||
|
get {
|
||||||
|
return _remainingSleepTime
|
||||||
|
}
|
||||||
|
set(time) {
|
||||||
|
if time != nil && time! < 0 {
|
||||||
|
_remainingSleepTime = nil
|
||||||
|
} else {
|
||||||
|
_remainingSleepTime = time
|
||||||
|
}
|
||||||
|
|
||||||
|
if _remainingSleepTime == nil {
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name(PlayerEvents.sleepEnded.rawValue), object: _remainingSleepTime)
|
||||||
|
} else {
|
||||||
|
NotificationCenter.default.post(name: NSNotification.Name(PlayerEvents.sleepSet.rawValue), object: _remainingSleepTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static var listeningTimePassedSinceLastSync: Double = 0.0
|
||||||
|
|
||||||
|
public static var paused: Bool {
|
||||||
|
get {
|
||||||
|
return player?.rate == 0.0
|
||||||
|
}
|
||||||
|
set(paused) {
|
||||||
|
if paused {
|
||||||
|
self.player?.pause()
|
||||||
|
} else {
|
||||||
|
self.player?.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static func startPlayback(session: PlaybackSession, playWhenReady: Bool, playbackRate: Float) {
|
public static func startPlayback(session: PlaybackSession, playWhenReady: Bool, playbackRate: Float) {
|
||||||
if player != nil {
|
if player != nil {
|
||||||
|
@ -48,20 +80,6 @@ class PlayerHandler {
|
||||||
self.player?.setPlaybackRate(speed)
|
self.player?.setPlaybackRate(speed)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func play() {
|
|
||||||
self.player?.play()
|
|
||||||
}
|
|
||||||
public static func pause() {
|
|
||||||
self.player?.play()
|
|
||||||
}
|
|
||||||
public static func playPause() {
|
|
||||||
if paused() {
|
|
||||||
self.player?.play()
|
|
||||||
} else {
|
|
||||||
self.player?.pause()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func seekForward(amount: Double) {
|
public static func seekForward(amount: Double) {
|
||||||
guard let player = player else {
|
guard let player = player else {
|
||||||
return
|
return
|
||||||
|
@ -81,11 +99,6 @@ class PlayerHandler {
|
||||||
public static func seek(amount: Double) {
|
public static func seek(amount: Double) {
|
||||||
player?.seek(amount)
|
player?.seek(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func paused() -> Bool {
|
|
||||||
player?.rate == 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func getMetdata() -> [String: Any] {
|
public static func getMetdata() -> [String: Any] {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
syncProgress()
|
syncProgress()
|
||||||
|
@ -94,27 +107,30 @@ class PlayerHandler {
|
||||||
return [
|
return [
|
||||||
"duration": player?.getDuration() ?? 0,
|
"duration": player?.getDuration() ?? 0,
|
||||||
"currentTime": player?.getCurrentTime() ?? 0,
|
"currentTime": player?.getCurrentTime() ?? 0,
|
||||||
"playerState": !paused(),
|
"playerState": !paused,
|
||||||
"currentRate": player?.rate ?? 0,
|
"currentRate": player?.rate ?? 0,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func tick() {
|
private static func tick() {
|
||||||
if !paused() {
|
if !paused {
|
||||||
listeningTimePassedSinceLastSync += 1
|
listeningTimePassedSinceLastSync += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if listeningTimePassedSinceLastSync > 3 {
|
if listeningTimePassedSinceLastSync > 3 {
|
||||||
syncProgress()
|
syncProgress()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if remainingSleepTime != nil {
|
||||||
|
if remainingSleepTime! == 0 {
|
||||||
|
paused = true
|
||||||
|
}
|
||||||
|
remainingSleepTime! -= 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public static func syncProgress() {
|
public static func syncProgress() {
|
||||||
if session == nil {
|
if session == nil { return }
|
||||||
return
|
guard let player = player else { return }
|
||||||
}
|
|
||||||
guard let player = player else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let report = PlaybackReport(currentTime: player.getCurrentTime(), duration: player.getDuration(), timeListened: listeningTimePassedSinceLastSync)
|
let report = PlaybackReport(currentTime: player.getCurrentTime(), duration: player.getDuration(), timeListened: listeningTimePassedSinceLastSync)
|
||||||
|
|
||||||
|
|
|
@ -10,4 +10,6 @@ import Foundation
|
||||||
enum PlayerEvents: String {
|
enum PlayerEvents: String {
|
||||||
case update = "com.audiobookshelf.app.player.update"
|
case update = "com.audiobookshelf.app.player.update"
|
||||||
case closed = "com.audiobookshelf.app.player.closed"
|
case closed = "com.audiobookshelf.app.player.closed"
|
||||||
|
case sleepSet = "com.audiobookshelf.app.player.sleep.set"
|
||||||
|
case sleepEnded = "com.audiobookshelf.app.player.sleep.ended"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue