mirror of
https://github.com/yattee/yattee.git
synced 2024-12-15 06:40:32 +05:30
Add setting for controls center buttons
This commit is contained in:
parent
4333bcc1e9
commit
79f801ea60
@ -158,6 +158,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
var onPresentPlayer: (() -> Void)?
|
var onPresentPlayer: (() -> Void)?
|
||||||
|
private var remoteCommandCenterConfigured = false
|
||||||
|
|
||||||
init(
|
init(
|
||||||
accounts: AccountsModel = AccountsModel(),
|
accounts: AccountsModel = AccountsModel(),
|
||||||
@ -537,6 +538,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
func handleQueueChange() {
|
func handleQueueChange() {
|
||||||
Defaults[.queue] = queue
|
Defaults[.queue] = queue
|
||||||
|
|
||||||
|
updateRemoteCommandCenter()
|
||||||
controls.objectWillChange.send()
|
controls.objectWillChange.send()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,6 +563,8 @@ final class PlayerModel: ObservableObject {
|
|||||||
func handlePlaybackModeChange() {
|
func handlePlaybackModeChange() {
|
||||||
Defaults[.playbackMode] = playbackMode
|
Defaults[.playbackMode] = playbackMode
|
||||||
|
|
||||||
|
updateRemoteCommandCenter()
|
||||||
|
|
||||||
guard playbackMode == .related else {
|
guard playbackMode == .related else {
|
||||||
autoplayItem = nil
|
autoplayItem = nil
|
||||||
return
|
return
|
||||||
@ -580,11 +584,94 @@ final class PlayerModel: ObservableObject {
|
|||||||
self.accounts.api.loadDetails(item, completionHandler: { newItem in
|
self.accounts.api.loadDetails(item, completionHandler: { newItem in
|
||||||
guard newItem.videoID == self.autoplayItem?.videoID else { return }
|
guard newItem.videoID == self.autoplayItem?.videoID else { return }
|
||||||
self.autoplayItem = newItem
|
self.autoplayItem = newItem
|
||||||
|
self.updateRemoteCommandCenter()
|
||||||
self.controls.objectWillChange.send()
|
self.controls.objectWillChange.send()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateRemoteCommandCenter() {
|
||||||
|
let skipForwardCommand = MPRemoteCommandCenter.shared().skipForwardCommand
|
||||||
|
let skipBackwardCommand = MPRemoteCommandCenter.shared().skipBackwardCommand
|
||||||
|
let previousTrackCommand = MPRemoteCommandCenter.shared().previousTrackCommand
|
||||||
|
let nextTrackCommand = MPRemoteCommandCenter.shared().nextTrackCommand
|
||||||
|
|
||||||
|
if !remoteCommandCenterConfigured {
|
||||||
|
remoteCommandCenterConfigured = true
|
||||||
|
|
||||||
|
#if !os(macOS)
|
||||||
|
try? AVAudioSession.sharedInstance().setCategory(
|
||||||
|
.playback,
|
||||||
|
mode: .moviePlayback
|
||||||
|
)
|
||||||
|
|
||||||
|
UIApplication.shared.beginReceivingRemoteControlEvents()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
let preferredIntervals = [NSNumber(10)]
|
||||||
|
|
||||||
|
skipForwardCommand.preferredIntervals = preferredIntervals
|
||||||
|
skipBackwardCommand.preferredIntervals = preferredIntervals
|
||||||
|
|
||||||
|
skipForwardCommand.addTarget { [weak self] _ in
|
||||||
|
self?.backend.seek(relative: .secondsInDefaultTimescale(10))
|
||||||
|
return .success
|
||||||
|
}
|
||||||
|
|
||||||
|
skipBackwardCommand.addTarget { [weak self] _ in
|
||||||
|
self?.backend.seek(relative: .secondsInDefaultTimescale(-10))
|
||||||
|
return .success
|
||||||
|
}
|
||||||
|
|
||||||
|
previousTrackCommand.addTarget { [weak self] _ in
|
||||||
|
self?.backend.seek(to: .zero)
|
||||||
|
return .success
|
||||||
|
}
|
||||||
|
|
||||||
|
nextTrackCommand.addTarget { [weak self] _ in
|
||||||
|
self?.advanceToNextItem()
|
||||||
|
return .success
|
||||||
|
}
|
||||||
|
|
||||||
|
MPRemoteCommandCenter.shared().playCommand.addTarget { [weak self] _ in
|
||||||
|
self?.play()
|
||||||
|
return .success
|
||||||
|
}
|
||||||
|
|
||||||
|
MPRemoteCommandCenter.shared().pauseCommand.addTarget { [weak self] _ in
|
||||||
|
self?.pause()
|
||||||
|
return .success
|
||||||
|
}
|
||||||
|
|
||||||
|
MPRemoteCommandCenter.shared().togglePlayPauseCommand.addTarget { [weak self] _ in
|
||||||
|
self?.togglePlay()
|
||||||
|
return .success
|
||||||
|
}
|
||||||
|
|
||||||
|
MPRemoteCommandCenter.shared().changePlaybackPositionCommand.addTarget { [weak self] remoteEvent in
|
||||||
|
guard let event = remoteEvent as? MPChangePlaybackPositionCommandEvent else { return .commandFailed }
|
||||||
|
|
||||||
|
self?.backend.seek(to: event.positionTime)
|
||||||
|
|
||||||
|
return .success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch Defaults[.systemControlsCommands] {
|
||||||
|
case .seek:
|
||||||
|
previousTrackCommand.isEnabled = false
|
||||||
|
nextTrackCommand.isEnabled = false
|
||||||
|
skipForwardCommand.isEnabled = true
|
||||||
|
skipBackwardCommand.isEnabled = true
|
||||||
|
|
||||||
|
case .restartAndAdvanceToNext:
|
||||||
|
skipForwardCommand.isEnabled = false
|
||||||
|
skipBackwardCommand.isEnabled = false
|
||||||
|
previousTrackCommand.isEnabled = true
|
||||||
|
nextTrackCommand.isEnabled = isAdvanceToNextItemAvailable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func resetAutoplay() {
|
func resetAutoplay() {
|
||||||
autoplayItem = nil
|
autoplayItem = nil
|
||||||
autoplayItemSource = nil
|
autoplayItemSource = nil
|
||||||
|
@ -99,6 +99,7 @@ extension Defaults.Keys {
|
|||||||
|
|
||||||
static let playerDetailsPageButtonLabelStyle = Key<PlayerDetailsPageButtonLabelStyle>("playerDetailsPageButtonLabelStyle", default: defaultForPlayerDetailsPageButtonLabelStyle)
|
static let playerDetailsPageButtonLabelStyle = Key<PlayerDetailsPageButtonLabelStyle>("playerDetailsPageButtonLabelStyle", default: defaultForPlayerDetailsPageButtonLabelStyle)
|
||||||
|
|
||||||
|
static let systemControlsCommands = Key<SystemControlsCommands>("systemControlsCommands", default: .restartAndAdvanceToNext)
|
||||||
static let mpvCacheSecs = Key<String>("mpvCacheSecs", default: "20")
|
static let mpvCacheSecs = Key<String>("mpvCacheSecs", default: "20")
|
||||||
static let mpvCachePauseWait = Key<String>("mpvCachePauseWait", default: "2")
|
static let mpvCachePauseWait = Key<String>("mpvCachePauseWait", default: "2")
|
||||||
static let mpvEnableLogging = Key<Bool>("mpvEnableLogging", default: false)
|
static let mpvEnableLogging = Key<Bool>("mpvEnableLogging", default: false)
|
||||||
@ -225,3 +226,7 @@ enum PlayerDetailsPageButtonLabelStyle: String, CaseIterable, Defaults.Serializa
|
|||||||
enum ThumbnailsQuality: String, CaseIterable, Defaults.Serializable {
|
enum ThumbnailsQuality: String, CaseIterable, Defaults.Serializable {
|
||||||
case highest, medium, low
|
case highest, medium, low
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SystemControlsCommands: String, CaseIterable, Defaults.Serializable {
|
||||||
|
case seek, restartAndAdvanceToNext
|
||||||
|
}
|
||||||
|
@ -23,6 +23,9 @@ struct PlayerSettings: View {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
@Default(.enableReturnYouTubeDislike) private var enableReturnYouTubeDislike
|
@Default(.enableReturnYouTubeDislike) private var enableReturnYouTubeDislike
|
||||||
|
@Default(.systemControlsCommands) private var systemControlsCommands
|
||||||
|
|
||||||
|
@EnvironmentObject<PlayerModel> private var player
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
private var idiom: UIUserInterfaceIdiom {
|
private var idiom: UIUserInterfaceIdiom {
|
||||||
@ -60,6 +63,7 @@ struct PlayerSettings: View {
|
|||||||
pauseOnEnteringBackgroundToogle
|
pauseOnEnteringBackgroundToogle
|
||||||
#endif
|
#endif
|
||||||
closeLastItemOnPlaybackEndToggle
|
closeLastItemOnPlaybackEndToggle
|
||||||
|
systemControlsCommandsPicker
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: SettingsHeader(text: "Interface")) {
|
Section(header: SettingsHeader(text: "Interface")) {
|
||||||
@ -113,6 +117,22 @@ struct PlayerSettings: View {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var systemControlsCommandsPicker: some View {
|
||||||
|
Picker("System controls buttons", selection: $systemControlsCommands) {
|
||||||
|
Text("10 seconds forwards/backwards").tag(SystemControlsCommands.seek)
|
||||||
|
Text("Restart/Play next").tag(SystemControlsCommands.restartAndAdvanceToNext)
|
||||||
|
}
|
||||||
|
.onChange(of: systemControlsCommands) { _ in
|
||||||
|
player.updateRemoteCommandCenter()
|
||||||
|
}
|
||||||
|
.labelsHidden()
|
||||||
|
#if os(iOS)
|
||||||
|
.pickerStyle(.automatic)
|
||||||
|
#elseif os(tvOS)
|
||||||
|
.pickerStyle(.inline)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
private var qualityPicker: some View {
|
private var qualityPicker: some View {
|
||||||
Picker("Quality", selection: $quality) {
|
Picker("Quality", selection: $quality) {
|
||||||
ForEach(ResolutionSetting.allCases, id: \.self) { resolution in
|
ForEach(ResolutionSetting.allCases, id: \.self) { resolution in
|
||||||
|
@ -168,10 +168,6 @@ struct YatteeApp: App {
|
|||||||
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
|
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
|
||||||
SDWebImageManager.defaultImageCache = PINCache(name: "stream.yattee.app")
|
SDWebImageManager.defaultImageCache = PINCache(name: "stream.yattee.app")
|
||||||
|
|
||||||
#if !os(macOS)
|
|
||||||
configureNowPlayingInfoCenter()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
if Defaults[.lockPortraitWhenBrowsing] {
|
if Defaults[.lockPortraitWhenBrowsing] {
|
||||||
Orientation.lockOrientation(.portrait, andRotateTo: .portrait)
|
Orientation.lockOrientation(.portrait, andRotateTo: .portrait)
|
||||||
@ -236,56 +232,8 @@ struct YatteeApp: App {
|
|||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||||
Windows.main.focus()
|
Windows.main.focus()
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
player.updateRemoteCommandCenter()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureNowPlayingInfoCenter() {
|
|
||||||
#if !os(macOS)
|
|
||||||
try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .moviePlayback)
|
|
||||||
|
|
||||||
UIApplication.shared.beginReceivingRemoteControlEvents()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MPRemoteCommandCenter.shared().playCommand.addTarget { _ in
|
|
||||||
player.play()
|
|
||||||
return .success
|
|
||||||
}
|
|
||||||
|
|
||||||
MPRemoteCommandCenter.shared().pauseCommand.addTarget { _ in
|
|
||||||
player.pause()
|
|
||||||
return .success
|
|
||||||
}
|
|
||||||
|
|
||||||
MPRemoteCommandCenter.shared().previousTrackCommand.isEnabled = false
|
|
||||||
MPRemoteCommandCenter.shared().nextTrackCommand.isEnabled = false
|
|
||||||
|
|
||||||
MPRemoteCommandCenter.shared().changePlaybackPositionCommand.addTarget { remoteEvent in
|
|
||||||
guard let event = remoteEvent as? MPChangePlaybackPositionCommandEvent
|
|
||||||
else {
|
|
||||||
return .commandFailed
|
|
||||||
}
|
|
||||||
|
|
||||||
player.backend.seek(to: event.positionTime)
|
|
||||||
|
|
||||||
return .success
|
|
||||||
}
|
|
||||||
|
|
||||||
let skipForwardCommand = MPRemoteCommandCenter.shared().skipForwardCommand
|
|
||||||
skipForwardCommand.isEnabled = true
|
|
||||||
skipForwardCommand.preferredIntervals = [10]
|
|
||||||
|
|
||||||
skipForwardCommand.addTarget { _ in
|
|
||||||
player.backend.seek(relative: .secondsInDefaultTimescale(10))
|
|
||||||
return .success
|
|
||||||
}
|
|
||||||
|
|
||||||
let skipBackwardCommand = MPRemoteCommandCenter.shared().skipBackwardCommand
|
|
||||||
skipBackwardCommand.isEnabled = true
|
|
||||||
skipBackwardCommand.preferredIntervals = [10]
|
|
||||||
|
|
||||||
skipBackwardCommand.addTarget { _ in
|
|
||||||
player.backend.seek(relative: .secondsInDefaultTimescale(-10))
|
|
||||||
return .success
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user