mirror of
https://github.com/danbee/persephone
synced 2025-03-04 08:39:11 +00:00
Use MPNowPlayingInfoCenter to player info
This means that the notications bar media player will show track & artist title, as well as artwork for the album. It also means that Play/Pause/Next/Previous work without needing accessibility access
This commit is contained in:
parent
3b330f1c78
commit
a0f1942ba8
@ -12,6 +12,8 @@ struct App {
|
||||
static let store = Store<AppState>(reducer: appReducer, state: nil)
|
||||
static let trackTimer = TrackTimer()
|
||||
static let userNotificationsController = UserNotificationsController()
|
||||
static let mediaInfoController = MediaInfoController()
|
||||
static let playerStateInfoController = PlayerStateInfoController()
|
||||
static let mpdServerDelegate = MPDServerDelegate()
|
||||
static let mpdServerController = MPDServerController(delegate: mpdServerDelegate)
|
||||
static var mpdClient: MPDClient!
|
||||
|
||||
@ -40,7 +40,9 @@ class AppDelegate: NSObject,
|
||||
}
|
||||
|
||||
_ = App.userNotificationsController
|
||||
|
||||
_ = App.mediaInfoController
|
||||
_ = App.playerStateInfoController
|
||||
|
||||
_ = App.mpdServerController
|
||||
}
|
||||
|
||||
|
||||
76
Mac/Components/Shared/MediaInfoController.swift
Normal file
76
Mac/Components/Shared/MediaInfoController.swift
Normal file
@ -0,0 +1,76 @@
|
||||
//
|
||||
// MediaInfoController.swift
|
||||
// Persephone
|
||||
//
|
||||
// Created by Alan Harper on 18/11/20.
|
||||
// Copyright © 2020 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ReSwift
|
||||
import MediaPlayer
|
||||
import Kingfisher
|
||||
|
||||
class MediaInfoController {
|
||||
init() {
|
||||
App.store.subscribe(self) {
|
||||
$0.select { $0.playerState.currentSong }
|
||||
}
|
||||
}
|
||||
|
||||
func notifyTrack(_ song: Song) {
|
||||
let provider = MPDAlbumArtImageDataProvider(
|
||||
songUri: song.mpdSong.uriString,
|
||||
cacheKey: song.album.hash
|
||||
)
|
||||
|
||||
let infoCenter = MPNowPlayingInfoCenter.default()
|
||||
|
||||
var nowPlayingInfo = [
|
||||
MPMediaItemPropertyTitle: song.title,
|
||||
MPMediaItemPropertyArtist: song.artist,
|
||||
MPMediaItemPropertyAlbumArtist: song.album.artist,
|
||||
MPMediaItemPropertyAlbumTitle: song.album.title,
|
||||
MPMediaItemPropertyPlaybackDuration: NSNumber(value: song.duration.timeInSeconds),
|
||||
MPNowPlayingInfoPropertyMediaType: NSNumber(value: MPNowPlayingInfoMediaType.audio.rawValue),
|
||||
MPNowPlayingInfoPropertyIsLiveStream: NSNumber(value: false),
|
||||
] as [String : Any]
|
||||
|
||||
if let elapsedTime = App.store.state.playerState.elapsedTimeMs {
|
||||
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: elapsedTime / 1000)
|
||||
}
|
||||
|
||||
if #available(OSX 10.13.2, *) {
|
||||
_ = KingfisherManager.shared.retrieveImage(
|
||||
with: .provider(provider),
|
||||
options: [
|
||||
.processor(DownsamplingImageProcessor(size: .notificationCoverSize)),
|
||||
.scaleFactor(2),
|
||||
]
|
||||
) { result in
|
||||
switch result {
|
||||
case .success(let value):
|
||||
let artwork = MPMediaItemArtwork.init(boundsSize: CGSize(width: 100.0, height: 100.0)) { (size: CGSize) in value.image }
|
||||
nowPlayingInfo[MPMediaItemPropertyArtwork] = artwork
|
||||
infoCenter.nowPlayingInfo = nowPlayingInfo
|
||||
case .failure:
|
||||
infoCenter.nowPlayingInfo = nowPlayingInfo
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
infoCenter.nowPlayingInfo = nowPlayingInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension MediaInfoController: StoreSubscriber {
|
||||
typealias StoreSubscriberStateType = Song?
|
||||
|
||||
|
||||
func newState(state: StoreSubscriberStateType) {
|
||||
guard let song = state else {return}
|
||||
|
||||
notifyTrack(song)
|
||||
}
|
||||
}
|
||||
72
Mac/Components/Shared/PlayerStateInfoController.swift
Normal file
72
Mac/Components/Shared/PlayerStateInfoController.swift
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// MediaInfoController.swift
|
||||
// Persephone
|
||||
//
|
||||
// Created by Alan Harper on 18/11/20.
|
||||
// Copyright © 2020 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ReSwift
|
||||
import MediaPlayer
|
||||
import Kingfisher
|
||||
|
||||
class PlayerStateInfoController {
|
||||
init() {
|
||||
App.store.subscribe(self) {
|
||||
$0.select { $0.playerState.state }
|
||||
}
|
||||
let commandCenter = MPRemoteCommandCenter.shared()
|
||||
commandCenter.playCommand.addTarget { _ in
|
||||
App.mpdClient.playPause()
|
||||
return .success
|
||||
}
|
||||
commandCenter.togglePlayPauseCommand.addTarget { _ in
|
||||
App.mpdClient.playPause()
|
||||
return .success
|
||||
}
|
||||
commandCenter.pauseCommand.addTarget { _ in
|
||||
App.mpdClient.playPause()
|
||||
return .success
|
||||
}
|
||||
|
||||
commandCenter.nextTrackCommand.addTarget { _ in
|
||||
App.mpdClient.nextTrack()
|
||||
return .success
|
||||
}
|
||||
|
||||
commandCenter.previousTrackCommand.addTarget { _ in
|
||||
App.mpdClient.prevTrack()
|
||||
return .success
|
||||
}
|
||||
}
|
||||
|
||||
func notifyState(_ state: MPDClient.MPDStatus.State?) {
|
||||
let infoCenter = MPNowPlayingInfoCenter.default()
|
||||
|
||||
switch(state) {
|
||||
case .unknown:
|
||||
infoCenter.playbackState = .unknown
|
||||
break;
|
||||
case .paused:
|
||||
infoCenter.playbackState = .paused
|
||||
break;
|
||||
case .stopped:
|
||||
infoCenter.playbackState = .stopped
|
||||
break;
|
||||
case .playing:
|
||||
infoCenter.playbackState = .playing
|
||||
break;
|
||||
case .none:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PlayerStateInfoController: StoreSubscriber {
|
||||
typealias StoreSubscriberStateType = MPDClient.MPDStatus.State?
|
||||
|
||||
func newState(state: StoreSubscriberStateType) {
|
||||
notifyState(state)
|
||||
}
|
||||
}
|
||||
@ -307,6 +307,8 @@
|
||||
E4FF7190227601B400D4C412 /* PreferencesReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FF718F227601B400D4C412 /* PreferencesReducer.swift */; };
|
||||
E4FF71922276029000D4C412 /* PreferencesActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FF71912276029000D4C412 /* PreferencesActions.swift */; };
|
||||
E4FF71942276043A00D4C412 /* MPDServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4FF71932276043A00D4C412 /* MPDServer.swift */; };
|
||||
E72BF0CE2567F45E00419CB0 /* PlayerStateInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E72BF0CD2567F45E00419CB0 /* PlayerStateInfoController.swift */; };
|
||||
E7AF1B642565124D00057784 /* MediaInfoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AF1B632565124D00057784 /* MediaInfoController.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -650,6 +652,8 @@
|
||||
E4FF718F227601B400D4C412 /* PreferencesReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesReducer.swift; sourceTree = "<group>"; };
|
||||
E4FF71912276029000D4C412 /* PreferencesActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesActions.swift; sourceTree = "<group>"; };
|
||||
E4FF71932276043A00D4C412 /* MPDServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDServer.swift; sourceTree = "<group>"; };
|
||||
E72BF0CD2567F45E00419CB0 /* PlayerStateInfoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerStateInfoController.swift; sourceTree = "<group>"; };
|
||||
E7AF1B632565124D00057784 /* MediaInfoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaInfoController.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -958,6 +962,8 @@
|
||||
E489E3A222B9D31800CA8CBD /* DraggedSongView.swift */,
|
||||
E489E3A322B9D31800CA8CBD /* DraggedSongView.xib */,
|
||||
E4B11BB52275374B0075461B /* UserNotificationsController.swift */,
|
||||
E7AF1B632565124D00057784 /* MediaInfoController.swift */,
|
||||
E72BF0CD2567F45E00419CB0 /* PlayerStateInfoController.swift */,
|
||||
);
|
||||
path = Shared;
|
||||
sourceTree = "<group>";
|
||||
@ -1643,6 +1649,7 @@
|
||||
E48059D82426D73600362CF3 /* database.c in Sources */,
|
||||
E43AC1F522C6A4F4001E483C /* DraggedAlbum.swift in Sources */,
|
||||
E40FE71B221B904300A4223F /* NSEvent.swift in Sources */,
|
||||
E72BF0CE2567F45E00419CB0 /* PlayerStateInfoController.swift in Sources */,
|
||||
E4B11BB62275374B0075461B /* UserNotificationsController.swift in Sources */,
|
||||
E43AC1F622C6AD0B001E483C /* AlbumViewController+NSCollectionViewDelegate.swift in Sources */,
|
||||
E4B11B68226A4FA00075461B /* QueueState.swift in Sources */,
|
||||
@ -1674,6 +1681,7 @@
|
||||
E4805A0A2426D73600362CF3 /* sync.c in Sources */,
|
||||
E4DA820623D6236200C1EE58 /* NSSize.swift in Sources */,
|
||||
E408D3B6220DD8970006D9BE /* Notification.swift in Sources */,
|
||||
E7AF1B642565124D00057784 /* MediaInfoController.swift in Sources */,
|
||||
E48059E42426D73600362CF3 /* run.c in Sources */,
|
||||
E4805A1A2426D73600362CF3 /* cmessage.c in Sources */,
|
||||
E48059C42426D73600362CF3 /* replay_gain.c in Sources */,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user