mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-06 20:08:48 +02:00
feat: now playing chapter track
This commit is contained in:
@@ -160,3 +160,11 @@ class PlaybackSession: Object, Codable, Deletable {
|
||||
try container.encode(localMediaProgressId, forKey: .localMediaProgressId)
|
||||
}
|
||||
}
|
||||
|
||||
extension PlaybackSession {
|
||||
func getCurrentChapter() -> Chapter? {
|
||||
return chapters.first { chapter in
|
||||
chapter.start <= self.currentTime && chapter.end > self.currentTime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ class PlayerSettings: Object {
|
||||
// The webapp has a persisted setting for playback speed, but it's not always available to the native code
|
||||
// Lets track it natively as well, so we never have a situation where the UI and native player are out of sync
|
||||
@Persisted var playbackRate: Float = 1.0
|
||||
@Persisted var chapterTrack: Bool = true
|
||||
|
||||
|
||||
// Singleton pattern for Realm objects
|
||||
static func main() -> PlayerSettings {
|
||||
|
||||
@@ -39,3 +39,13 @@ class Chapter: EmbeddedObject, Codable {
|
||||
try container.encode(title, forKey: .title)
|
||||
}
|
||||
}
|
||||
|
||||
extension Chapter {
|
||||
func getRelativeChapterCurrentTime(sessionCurrentTime: Double) -> Double {
|
||||
return sessionCurrentTime - self.start
|
||||
}
|
||||
|
||||
func getRelativeChapterEndTime() -> Double {
|
||||
return self.end - self.start
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,6 +224,8 @@ class AudioPlayer: NSObject {
|
||||
// Update the UI
|
||||
NotificationCenter.default.post(name: NSNotification.Name(PlayerEvents.sleepSet.rawValue), object: nil)
|
||||
}
|
||||
// Update the now playing and chapter info
|
||||
self.updateNowPlaying()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -443,6 +445,10 @@ class AudioPlayer: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
public func setChapterTrack() {
|
||||
self.updateNowPlaying()
|
||||
}
|
||||
|
||||
public func getCurrentTime() -> Double? {
|
||||
guard let playbackSession = self.getPlaybackSession() else { return nil }
|
||||
let currentTrackTime = self.audioPlayer.currentTime().seconds
|
||||
@@ -657,7 +663,16 @@ class AudioPlayer: NSObject {
|
||||
}
|
||||
private func updateNowPlaying() {
|
||||
NotificationCenter.default.post(name: NSNotification.Name(PlayerEvents.update.rawValue), object: nil)
|
||||
if let duration = self.getDuration(), let currentTime = self.getCurrentTime() {
|
||||
if let session = self.getPlaybackSession(), let currentChapter = session.getCurrentChapter(), PlayerSettings.main().chapterTrack {
|
||||
NowPlayingInfo.shared.update(
|
||||
duration: currentChapter.getRelativeChapterEndTime(),
|
||||
currentTime: currentChapter.getRelativeChapterCurrentTime(sessionCurrentTime: session.currentTime),
|
||||
rate: rate,
|
||||
chapterName: currentChapter.title,
|
||||
chapterNumber: (session.chapters.firstIndex(of: currentChapter) ?? 0) + 1,
|
||||
chapterCount: session.chapters.count
|
||||
)
|
||||
} else if let duration = self.getDuration(), let currentTime = self.getCurrentTime() {
|
||||
NowPlayingInfo.shared.update(duration: duration, currentTime: currentTime, rate: rate)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,10 @@ class PlayerHandler {
|
||||
self.player?.setPlaybackRate(speed)
|
||||
}
|
||||
|
||||
public static func setChapterTrack() {
|
||||
self.player?.setChapterTrack()
|
||||
}
|
||||
|
||||
public static func getSleepTimeRemaining() -> Double? {
|
||||
return self.player?.getSleepTimeRemaining()
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ class NowPlayingInfo {
|
||||
self.setMetadata(artwork: artwork, metadata: metadata)
|
||||
}
|
||||
}
|
||||
public func update(duration: Double, currentTime: Double, rate: Float) {
|
||||
public func update(duration: Double, currentTime: Double, rate: Float, chapterName: String? = nil, chapterNumber: Int? = nil, chapterCount: Int? = nil) {
|
||||
// Update on the main to prevent access collisions
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
if let self = self {
|
||||
@@ -62,6 +62,18 @@ class NowPlayingInfo {
|
||||
self.nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = rate
|
||||
self.nowPlayingInfo[MPNowPlayingInfoPropertyDefaultPlaybackRate] = 1.0
|
||||
|
||||
|
||||
if let chapterName = chapterName, let chapterNumber = chapterNumber, let chapterCount = chapterCount {
|
||||
self.nowPlayingInfo[MPMediaItemPropertyTitle] = chapterName
|
||||
self.nowPlayingInfo[MPNowPlayingInfoPropertyChapterNumber] = chapterNumber
|
||||
self.nowPlayingInfo[MPNowPlayingInfoPropertyChapterCount] = chapterCount
|
||||
} else {
|
||||
// Set the title back to the book title
|
||||
self.nowPlayingInfo[MPMediaItemPropertyTitle] = self.nowPlayingInfo[MPMediaItemPropertyAlbumTitle]
|
||||
self.nowPlayingInfo[MPNowPlayingInfoPropertyChapterNumber] = nil
|
||||
self.nowPlayingInfo[MPNowPlayingInfoPropertyChapterCount] = nil
|
||||
}
|
||||
|
||||
MPNowPlayingInfoCenter.default().nowPlayingInfo = self.nowPlayingInfo
|
||||
}
|
||||
}
|
||||
@@ -89,7 +101,7 @@ class NowPlayingInfo {
|
||||
|
||||
nowPlayingInfo[MPMediaItemPropertyTitle] = metadata!.title
|
||||
nowPlayingInfo[MPMediaItemPropertyArtist] = metadata!.author ?? "unknown"
|
||||
nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = metadata!.series
|
||||
nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = metadata!.title
|
||||
}
|
||||
|
||||
private func shouldFetchCover(id: String) -> Bool {
|
||||
|
||||
Reference in New Issue
Block a user