summaryrefslogtreecommitdiffstats
path: root/osdep/macos/remote_command_center.swift
diff options
context:
space:
mode:
authorder richter <der.richter@gmx.de>2019-11-30 16:08:32 +0100
committerder richter <der.richter@gmx.de>2019-12-15 20:07:31 +0100
commita32db637b5c66c0304147caadf02d7b28083bcee (patch)
treea078fd47fd36cc853a1422ea05a949fbc9afde60 /osdep/macos/remote_command_center.swift
parent8a6ee7fe947bb01a49beb38152cedb1e1b206ed2 (diff)
downloadmpv-a32db637b5c66c0304147caadf02d7b28083bcee.tar.bz2
mpv-a32db637b5c66c0304147caadf02d7b28083bcee.tar.xz
mac: replace old event tap for media key support with MediaPlayer
the old event tap has several problems, like no proper priority support or having to set accessibility permissions for mpv or the terminal. it is now replaced by the new MediaPlayer which has proper priority support and isn't as greedy as previously. this only includes Media Key support and not any of the other features included in the MediaPlayer framework, like proper Now Playing data (only set dummy data for now). this is only available on macOS 10.12.2 and higher. also removes some unnecessary redefines. Fixes #6389
Diffstat (limited to 'osdep/macos/remote_command_center.swift')
-rw-r--r--osdep/macos/remote_command_center.swift159
1 files changed, 159 insertions, 0 deletions
diff --git a/osdep/macos/remote_command_center.swift b/osdep/macos/remote_command_center.swift
new file mode 100644
index 0000000000..585a2e5698
--- /dev/null
+++ b/osdep/macos/remote_command_center.swift
@@ -0,0 +1,159 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import MediaPlayer
+
+@available(macOS 10.12.2, *)
+class RemoteCommandCenter: NSObject {
+
+ enum KeyType {
+ case normal
+ case repeatable
+ }
+
+ var config: [MPRemoteCommand:[String:Any]] = [
+ MPRemoteCommandCenter.shared().pauseCommand: [
+ "mpKey": MP_KEY_PAUSE,
+ "keyType": KeyType.normal
+ ],
+ MPRemoteCommandCenter.shared().playCommand: [
+ "mpKey": MP_KEY_PLAY,
+ "keyType": KeyType.normal
+ ],
+ MPRemoteCommandCenter.shared().stopCommand: [
+ "mpKey": MP_KEY_STOP,
+ "keyType": KeyType.normal
+ ],
+ MPRemoteCommandCenter.shared().nextTrackCommand: [
+ "mpKey": MP_KEY_NEXT,
+ "keyType": KeyType.normal
+ ],
+ MPRemoteCommandCenter.shared().previousTrackCommand: [
+ "mpKey": MP_KEY_PREV,
+ "keyType": KeyType.normal
+ ],
+ MPRemoteCommandCenter.shared().togglePlayPauseCommand: [
+ "mpKey": MP_KEY_PLAYPAUSE,
+ "keyType": KeyType.normal
+ ],
+ MPRemoteCommandCenter.shared().seekForwardCommand: [
+ "mpKey": MP_KEY_FORWARD,
+ "keyType": KeyType.repeatable,
+ "state": MP_KEY_STATE_UP
+ ],
+ MPRemoteCommandCenter.shared().seekBackwardCommand: [
+ "mpKey": MP_KEY_REWIND,
+ "keyType": KeyType.repeatable,
+ "state": MP_KEY_STATE_UP
+ ],
+ ]
+
+ var nowPlayingInfo: [String: Any] = [
+ MPNowPlayingInfoPropertyMediaType: NSNumber(value: MPNowPlayingInfoMediaType.video.rawValue),
+ MPNowPlayingInfoPropertyDefaultPlaybackRate: NSNumber(value: 1),
+ MPNowPlayingInfoPropertyPlaybackProgress: NSNumber(value: 0.0),
+ MPMediaItemPropertyPlaybackDuration: NSNumber(value: 0),
+ MPMediaItemPropertyTitle: "mpv",
+ MPMediaItemPropertyAlbumTitle: "mpv",
+ MPMediaItemPropertyArtist: "mpv",
+ ]
+
+ let disabledCommands: [MPRemoteCommand] = [
+ MPRemoteCommandCenter.shared().changePlaybackRateCommand,
+ MPRemoteCommandCenter.shared().changeRepeatModeCommand,
+ MPRemoteCommandCenter.shared().changeShuffleModeCommand,
+ MPRemoteCommandCenter.shared().skipForwardCommand,
+ MPRemoteCommandCenter.shared().skipBackwardCommand,
+ MPRemoteCommandCenter.shared().changePlaybackPositionCommand,
+ MPRemoteCommandCenter.shared().enableLanguageOptionCommand,
+ MPRemoteCommandCenter.shared().disableLanguageOptionCommand,
+ MPRemoteCommandCenter.shared().ratingCommand,
+ MPRemoteCommandCenter.shared().likeCommand,
+ MPRemoteCommandCenter.shared().dislikeCommand,
+ MPRemoteCommandCenter.shared().bookmarkCommand,
+ ]
+
+ let application: Application;
+
+ @objc init(app: Application) {
+ application = app
+
+ super.init()
+
+ for cmd in disabledCommands {
+ cmd.isEnabled = false
+ }
+ }
+
+ @objc func makeCurrent() {
+ MPNowPlayingInfoCenter.default().playbackState = .paused
+ MPNowPlayingInfoCenter.default().playbackState = .playing
+ }
+
+ @objc func start() {
+ for (cmd, _) in config {
+ cmd.isEnabled = true
+ cmd.addTarget { [unowned self] event in
+ return self.cmdHandler(event)
+ }
+ }
+
+ if let icon = application.getMPVIcon(), #available(macOS 10.13.2, *) {
+ let albumArt = MPMediaItemArtwork(boundsSize:icon.size) { _ in
+ return icon
+ }
+ nowPlayingInfo[MPMediaItemPropertyArtwork] = albumArt
+ }
+
+ MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
+ MPNowPlayingInfoCenter.default().playbackState = .playing
+ }
+
+ @objc func stop() {
+ for (cmd, _) in config {
+ cmd.isEnabled = false
+ cmd.removeTarget(nil)
+ }
+
+ MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
+ MPNowPlayingInfoCenter.default().playbackState = .unknown
+ }
+
+ func cmdHandler(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
+ guard let cmdConfig = config[event.command],
+ let mpKey = cmdConfig["mpKey"] as? Int32,
+ let keyType = cmdConfig["keyType"] as? KeyType else
+ {
+ return .commandFailed
+ }
+
+ var state = cmdConfig["state"] as? UInt32 ?? 0
+
+ if let currentState = cmdConfig["state"] as? UInt32, keyType == .repeatable {
+ state = MP_KEY_STATE_DOWN
+ config[event.command]?["state"] = MP_KEY_STATE_DOWN
+ if currentState == MP_KEY_STATE_DOWN {
+ state = MP_KEY_STATE_UP
+ config[event.command]?["state"] = MP_KEY_STATE_UP
+ }
+ }
+
+ application.handleMPKey(mpKey, withMask: Int32(state));
+
+ return .success
+ }
+} \ No newline at end of file