Merge pull request #109 from rasmuslos/master

Added sleep timer
This commit is contained in:
advplyr 2022-03-10 19:24:42 -06:00 committed by GitHub
commit 704318071e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 136 additions and 25 deletions

View file

@ -22,6 +22,7 @@ class AudioPlayer: NSObject {
// enums and @objc are not compatible
@objc dynamic var status: Int
@objc dynamic var rate: Float
private var tmpRate: Float = 1.0
private var playerContext = 0
private var playerItemContext = 0
@ -71,7 +72,8 @@ class AudioPlayer: NSObject {
public func play() {
self.audioPlayer.play()
self.status = 1
self.rate = 1.0
self.rate = self.tmpRate
self.audioPlayer.rate = self.tmpRate
updateNowPlaying()
}
@ -97,10 +99,15 @@ class AudioPlayer: NSObject {
self.updateNowPlaying()
}
}
public func setPlaybackRate(_ rate: Float) {
if(self.audioPlayer.rate != rate) {
public func setPlaybackRate(_ rate: Float, observed: Bool = false) {
if self.audioPlayer.rate != rate {
self.audioPlayer.rate = rate
}
if rate > 0.0 && !(observed && rate == 1) {
self.tmpRate = rate
}
self.rate = rate
self.updateNowPlaying()
@ -183,7 +190,7 @@ class AudioPlayer: NSObject {
}
func invokeMetadataUpdate() {
if !shouldFetchCover() && audiobook.artworkUrl != nil {
if !shouldFetchCover() || audiobook.artworkUrl == nil {
setMetadata(nil)
return
}
@ -234,7 +241,6 @@ class AudioPlayer: NSObject {
guard let playerStatus = AVPlayerItem.Status(rawValue: (change?[.newKey] as? Int ?? -1)) else { return }
if playerStatus == .readyToPlay {
NSLog("pain \(self.audiobook.startTime)")
updateNowPlaying()
self.status = 0
@ -246,7 +252,7 @@ class AudioPlayer: NSObject {
}
} else if context == &playerContext {
if keyPath == #keyPath(AVPlayer.rate) {
setPlaybackRate(change?[.newKey] as? Float ?? 1.0)
setPlaybackRate(change?[.newKey] as? Float ?? 1.0, observed: true)
} else if keyPath == #keyPath(AVPlayer.currentItem) {
NSLog("WARNING: Item ended")
}

View file

@ -1,16 +1,20 @@
#import <Foundation/Foundation.h>
#import <Capacitor/Capacitor.h>
CAP_PLUGIN(MyNativeAudio, "MyNativeAudio",
CAP_PLUGIN_METHOD(initPlayer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(playPlayer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(pausePlayer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(seekForward, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(seekBackward, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(seekPlayer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(terminateStream, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getStreamSyncData, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getCurrentTime, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(setPlaybackSpeed, CAPPluginReturnPromise);
)
CAP_PLUGIN_METHOD(initPlayer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(playPlayer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(pausePlayer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(seekForward, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(seekBackward, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(seekPlayer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(terminateStream, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getStreamSyncData, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getCurrentTime, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(setPlaybackSpeed, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(setSleepTimer, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(increaseSleepTime, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(decreaseSleepTime, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(cancelSleepTimer, CAPPluginReturnPromise);
)

View file

@ -3,6 +3,10 @@ import Capacitor
import MediaPlayer
import AVKit
func parseSleepTime(millis: String?) -> Double {
(Double(millis ?? "0") ?? 0) / 1000
}
@objc(MyNativeAudio)
public class MyNativeAudio: CAPPlugin {
var currentCall: CAPPluginCall?
@ -10,10 +14,8 @@ public class MyNativeAudio: CAPPlugin {
var playerContext = 0
override public func load() {
NSLog("Load MyNativeAudio")
// NotificationCenter.default.addObserver(self, selector: #selector(stop), name: Notification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
}
var currentSleepTimer: Timer? = nil
var remainingSleepDuration: Double = 0
@objc func initPlayer(_ call: CAPPluginCall) {
NSLog("Init Player")
@ -32,13 +34,18 @@ public class MyNativeAudio: CAPPlugin {
token: call.getString("token") ?? ""
)
let playWhenReady = call.getBool("playWhenReady", false)
if self.currentPlayer != nil && self.currentPlayer?.audiobook.streamId == audiobook.streamId {
if playWhenReady {
self.currentPlayer?.play()
}
call.resolve(["success": true])
return
}
self.currentPlayer = AudioPlayer(audiobook: audiobook, playWhenReady: call.getBool("playWhenReady", false))
self.currentPlayer = AudioPlayer(audiobook: audiobook, playWhenReady: playWhenReady)
self.currentPlayer!.addObserver(self, forKeyPath: #keyPath(AudioPlayer.status), options: .new, context: &playerContext)
call.resolve(["success": true])
@ -142,12 +149,13 @@ public class MyNativeAudio: CAPPlugin {
}
@objc func getStreamSyncData(_ call: CAPPluginCall) {
if self.currentPlayer == nil {
call.resolve([ "isPlaying": false as Any, "lastPauseTime": 0, "id": nil ])
call.resolve([ "isPlaying": false, "lastPauseTime": 0, "id": nil ])
return
}
call.resolve([ "isPlaying": self.currentPlayer!.rate > 0.0, "lastPauseTime": 0, "id": self.currentPlayer?.audiobook.streamId as Any ])
}
@objc func setPlaybackSpeed(_ call: CAPPluginCall) {
if self.currentPlayer == nil {
call.resolve()
@ -160,11 +168,104 @@ public class MyNativeAudio: CAPPlugin {
call.resolve()
}
@objc func setSleepTimer(_ call: CAPPluginCall) {
if self.currentPlayer == nil {
call.resolve()
return
}
let time = parseSleepTime(millis: call.getString("time"))
setSleepTimer(seconds: time)
call.resolve([ "success": true ])
}
@objc func increaseSleepTime(_ call: CAPPluginCall) {
if self.currentPlayer == nil {
call.resolve()
return
}
var time = self.remainingSleepDuration + parseSleepTime(millis: call.getString("time"))
if time > self.currentPlayer!.getDuration() {
time = self.currentPlayer!.getDuration()
}
setSleepTimer(seconds: time)
call.resolve([ "success": true ])
}
@objc func decreaseSleepTime(_ call: CAPPluginCall) {
if self.currentSleepTimer == nil {
call.resolve()
return
}
var time = parseSleepTime(millis: call.getString("time"))
if time < 0 {
time = 0
}
setSleepTimer(seconds: time)
call.resolve([
"success": true,
])
}
@objc func cancelSleepTimer(_ call: CAPPluginCall) {
setSleepTimer(seconds: 0)
call.resolve([
"success": true,
])
}
func setSleepTimer(seconds: Double) {
if currentPlayer == nil {
return
}
remainingSleepDuration = seconds
currentSleepTimer?.invalidate()
self.notifyListeners("onSleepTimerSet", data: [
"value": self.remainingSleepDuration,
])
if seconds == 0 {
return
}
DispatchQueue.main.async {
self.currentSleepTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
self.updateSleepTime()
}
}
}
func updateSleepTime() {
if currentPlayer == nil {
return
}
if self.remainingSleepDuration <= 0 {
if currentSleepTimer != nil {
currentSleepTimer!.invalidate()
}
self.notifyListeners("onSleepTimerEnded", data: [
"value": currentPlayer!.getCurrentTime(),
])
currentPlayer!.pause()
return
}
remainingSleepDuration -= 1
self.notifyListeners("onSleepTimerSet", data: [
"value": self.remainingSleepDuration,
])
}
func sendMetadata() {
if self.currentPlayer == nil {
return
}
self.notifyListeners("onMetadata", data: [
"duration": self.currentPlayer!.getDuration() * 1000,
"currentTime": self.currentPlayer!.getCurrentTime() * 1000,