mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 13:33:42 +00:00
Merge pull request #765 from stonerl/partial-fix-for-503
Update now playing info when using system controls – Partial fix for 503
This commit is contained in:
commit
2026201a5f
@ -102,7 +102,7 @@ final class AVPlayerBackend: PlayerBackend {
|
|||||||
|
|
||||||
private var frequentTimeObserver: Any?
|
private var frequentTimeObserver: Any?
|
||||||
private var infrequentTimeObserver: Any?
|
private var infrequentTimeObserver: Any?
|
||||||
private var playerTimeControlStatusObserver: Any?
|
private var playerTimeControlStatusObserver: NSKeyValueObservation?
|
||||||
|
|
||||||
private var statusObservation: NSKeyValueObservation?
|
private var statusObservation: NSKeyValueObservation?
|
||||||
|
|
||||||
@ -119,6 +119,26 @@ final class AVPlayerBackend: PlayerBackend {
|
|||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
controller.player = avPlayer
|
controller.player = avPlayer
|
||||||
#endif
|
#endif
|
||||||
|
logger.info("AVPlayerBackend initialized.")
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
// Invalidate any observers to avoid memory leaks
|
||||||
|
statusObservation?.invalidate()
|
||||||
|
playerTimeControlStatusObserver?.invalidate()
|
||||||
|
|
||||||
|
// Remove any time observers added to AVPlayer
|
||||||
|
if let frequentObserver = frequentTimeObserver {
|
||||||
|
avPlayer.removeTimeObserver(frequentObserver)
|
||||||
|
}
|
||||||
|
if let infrequentObserver = infrequentTimeObserver {
|
||||||
|
avPlayer.removeTimeObserver(infrequentObserver)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove notification observers
|
||||||
|
removeItemDidPlayToEndTimeObserver()
|
||||||
|
|
||||||
|
logger.info("AVPlayerBackend deinitialized.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func canPlay(_ stream: Stream) -> Bool {
|
func canPlay(_ stream: Stream) -> Bool {
|
||||||
@ -779,7 +799,7 @@ final class AVPlayerBackend: PlayerBackend {
|
|||||||
opened = true
|
opened = true
|
||||||
controller.startPictureInPicture()
|
controller.startPictureInPicture()
|
||||||
} else {
|
} else {
|
||||||
print("PiP not possible, waited \(delay) seconds")
|
self.logger.info("PiP not possible, waited \(delay) seconds")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -881,26 +881,29 @@ final class PlayerModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateRemoteCommandCenter() {
|
func updateRemoteCommandCenter() {
|
||||||
let skipForwardCommand = MPRemoteCommandCenter.shared().skipForwardCommand
|
let commandCenter = MPRemoteCommandCenter.shared()
|
||||||
let skipBackwardCommand = MPRemoteCommandCenter.shared().skipBackwardCommand
|
let skipForwardCommand = commandCenter.skipForwardCommand
|
||||||
let previousTrackCommand = MPRemoteCommandCenter.shared().previousTrackCommand
|
let skipBackwardCommand = commandCenter.skipBackwardCommand
|
||||||
let nextTrackCommand = MPRemoteCommandCenter.shared().nextTrackCommand
|
let previousTrackCommand = commandCenter.previousTrackCommand
|
||||||
|
let nextTrackCommand = commandCenter.nextTrackCommand
|
||||||
|
|
||||||
if !remoteCommandCenterConfigured {
|
if !remoteCommandCenterConfigured {
|
||||||
remoteCommandCenterConfigured = true
|
remoteCommandCenterConfigured = true
|
||||||
|
|
||||||
#if !os(macOS)
|
|
||||||
try? AVAudioSession.sharedInstance().setCategory(
|
|
||||||
.playback,
|
|
||||||
mode: .moviePlayback
|
|
||||||
)
|
|
||||||
|
|
||||||
UIApplication.shared.beginReceivingRemoteControlEvents()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
let interval = TimeInterval(systemControlsSeekDuration) ?? 10
|
let interval = TimeInterval(systemControlsSeekDuration) ?? 10
|
||||||
let preferredIntervals = [NSNumber(value: interval)]
|
let preferredIntervals = [NSNumber(value: interval)]
|
||||||
|
|
||||||
|
// Remove existing targets to avoid duplicates
|
||||||
|
skipForwardCommand.removeTarget(nil)
|
||||||
|
skipBackwardCommand.removeTarget(nil)
|
||||||
|
previousTrackCommand.removeTarget(nil)
|
||||||
|
nextTrackCommand.removeTarget(nil)
|
||||||
|
commandCenter.playCommand.removeTarget(nil)
|
||||||
|
commandCenter.pauseCommand.removeTarget(nil)
|
||||||
|
commandCenter.togglePlayPauseCommand.removeTarget(nil)
|
||||||
|
commandCenter.changePlaybackPositionCommand.removeTarget(nil)
|
||||||
|
|
||||||
|
// Re-add targets for handling commands
|
||||||
skipForwardCommand.preferredIntervals = preferredIntervals
|
skipForwardCommand.preferredIntervals = preferredIntervals
|
||||||
skipBackwardCommand.preferredIntervals = preferredIntervals
|
skipBackwardCommand.preferredIntervals = preferredIntervals
|
||||||
|
|
||||||
@ -924,22 +927,22 @@ final class PlayerModel: ObservableObject {
|
|||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
MPRemoteCommandCenter.shared().playCommand.addTarget { [weak self] _ in
|
commandCenter.playCommand.addTarget { [weak self] _ in
|
||||||
self?.play()
|
self?.play()
|
||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
MPRemoteCommandCenter.shared().pauseCommand.addTarget { [weak self] _ in
|
commandCenter.pauseCommand.addTarget { [weak self] _ in
|
||||||
self?.pause()
|
self?.pause()
|
||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
MPRemoteCommandCenter.shared().togglePlayPauseCommand.addTarget { [weak self] _ in
|
commandCenter.togglePlayPauseCommand.addTarget { [weak self] _ in
|
||||||
self?.togglePlay()
|
self?.togglePlay()
|
||||||
return .success
|
return .success
|
||||||
}
|
}
|
||||||
|
|
||||||
MPRemoteCommandCenter.shared().changePlaybackPositionCommand.addTarget { [weak self] remoteEvent in
|
commandCenter.changePlaybackPositionCommand.addTarget { [weak self] remoteEvent in
|
||||||
guard let event = remoteEvent as? MPChangePlaybackPositionCommandEvent else { return .commandFailed }
|
guard let event = remoteEvent as? MPChangePlaybackPositionCommandEvent else { return .commandFailed }
|
||||||
|
|
||||||
self?.backend.seek(to: event.positionTime, seekType: .userInteracted)
|
self?.backend.seek(to: event.positionTime, seekType: .userInteracted)
|
||||||
@ -1038,18 +1041,22 @@ final class PlayerModel: ObservableObject {
|
|||||||
guard activeBackend == .mpv else { return }
|
guard activeBackend == .mpv else { return }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
if activeBackend == .appleAVPlayer, avPlayerUsesSystemControls {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
guard let video = currentItem?.video else {
|
guard let video = currentItem?.video else {
|
||||||
MPNowPlayingInfoCenter.default().nowPlayingInfo = .none
|
MPNowPlayingInfoCenter.default().nowPlayingInfo = .none
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentTime = (backend.currentTime?.seconds.isFinite ?? false) ? backend.currentTime!.seconds : 0
|
let currentTime = (backend.currentTime?.seconds.isFinite ?? false) ? backend.currentTime!.seconds : 0
|
||||||
|
|
||||||
|
// Determine the media type based on musicMode
|
||||||
|
let mediaType: NSNumber
|
||||||
|
if musicMode {
|
||||||
|
mediaType = MPMediaType.anyAudio.rawValue as NSNumber
|
||||||
|
} else {
|
||||||
|
mediaType = MPMediaType.anyVideo.rawValue as NSNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the Now Playing info dictionary
|
||||||
var nowPlayingInfo: [String: AnyObject] = [
|
var nowPlayingInfo: [String: AnyObject] = [
|
||||||
MPMediaItemPropertyTitle: video.displayTitle as AnyObject,
|
MPMediaItemPropertyTitle: video.displayTitle as AnyObject,
|
||||||
MPMediaItemPropertyArtist: video.displayAuthor as AnyObject,
|
MPMediaItemPropertyArtist: video.displayAuthor as AnyObject,
|
||||||
@ -1057,7 +1064,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
MPNowPlayingInfoPropertyElapsedPlaybackTime: currentTime as AnyObject,
|
MPNowPlayingInfoPropertyElapsedPlaybackTime: currentTime as AnyObject,
|
||||||
MPNowPlayingInfoPropertyPlaybackQueueCount: queue.count as AnyObject,
|
MPNowPlayingInfoPropertyPlaybackQueueCount: queue.count as AnyObject,
|
||||||
MPNowPlayingInfoPropertyPlaybackQueueIndex: 1 as AnyObject,
|
MPNowPlayingInfoPropertyPlaybackQueueIndex: 1 as AnyObject,
|
||||||
MPMediaItemPropertyMediaType: MPMediaType.anyVideo.rawValue as AnyObject
|
MPMediaItemPropertyMediaType: mediaType
|
||||||
]
|
]
|
||||||
|
|
||||||
if !currentArtwork.isNil {
|
if !currentArtwork.isNil {
|
||||||
@ -1261,7 +1268,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func destroyKeyPressMonitor() {
|
private func destroyKeyPressMonitor() {
|
||||||
if let keyPressMonitor = keyPressMonitor {
|
if let keyPressMonitor {
|
||||||
NSEvent.removeMonitor(keyPressMonitor)
|
NSEvent.removeMonitor(keyPressMonitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
import AVFoundation
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import Logging
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
final class AppDelegate: UIResponder, UIApplicationDelegate {
|
final class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
var orientationLock = UIInterfaceOrientationMask.all
|
var orientationLock = UIInterfaceOrientationMask.all
|
||||||
|
|
||||||
|
private var logger = Logger(label: "stream.yattee.app.delegalate")
|
||||||
private(set) static var instance: AppDelegate!
|
private(set) static var instance: AppDelegate!
|
||||||
|
|
||||||
func application(_: UIApplication, supportedInterfaceOrientationsFor _: UIWindow?) -> UIInterfaceOrientationMask {
|
func application(_: UIApplication, supportedInterfaceOrientationsFor _: UIWindow?) -> UIInterfaceOrientationMask {
|
||||||
@ -12,11 +15,22 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
|
|
||||||
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { // swiftlint:disable:this discouraged_optional_collection
|
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { // swiftlint:disable:this discouraged_optional_collection
|
||||||
Self.instance = self
|
Self.instance = self
|
||||||
#if os(iOS)
|
|
||||||
UIViewController.swizzleHomeIndicatorProperty()
|
|
||||||
|
|
||||||
|
#if !os(macOS)
|
||||||
|
UIViewController.swizzleHomeIndicatorProperty()
|
||||||
OrientationTracker.shared.startDeviceOrientationTracking()
|
OrientationTracker.shared.startDeviceOrientationTracking()
|
||||||
|
|
||||||
|
// Configure the audio session for playback
|
||||||
|
do {
|
||||||
|
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .moviePlayback)
|
||||||
|
} catch {
|
||||||
|
logger.error("Failed to set audio session category: \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin receiving remote control events
|
||||||
|
UIApplication.shared.beginReceivingRemoteControlEvents()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user