Skip to content

Commit

Permalink
Fix media selection issues when altering current selection programmat…
Browse files Browse the repository at this point in the history
…ically (#600)
  • Loading branch information
defagos authored Oct 13, 2023
1 parent 144eaee commit ec4ec42
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
20 changes: 20 additions & 0 deletions Sources/Player/Internal/QueuePlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ class QueuePlayer: AVQueuePlayer {

private var pendingSeeks = Deque<Seek>()

// Starting with iOS 17 accessing media selection criteria might be slow. Use a cache for the lifetime of the
// player.
var mediaSelectionCriteria: [AVMediaCharacteristic: AVPlayerMediaSelectionCriteria?] = [:]

private var targetSeek: Seek? {
pendingSeeks.last
}
Expand Down Expand Up @@ -130,6 +134,22 @@ class QueuePlayer: AVQueuePlayer {
private func notifySeekEnd() {
Self.notificationCenter.post(name: .didSeek, object: self)
}

override func mediaSelectionCriteria(forMediaCharacteristic mediaCharacteristic: AVMediaCharacteristic) -> AVPlayerMediaSelectionCriteria? {
if let cachedCriteria = mediaSelectionCriteria[mediaCharacteristic] {
return cachedCriteria
}
else {
let criteria = super.mediaSelectionCriteria(forMediaCharacteristic: mediaCharacteristic)
mediaSelectionCriteria[mediaCharacteristic] = criteria
return criteria
}
}

override func setMediaSelectionCriteria(_ criteria: AVPlayerMediaSelectionCriteria?, forMediaCharacteristic mediaCharacteristic: AVMediaCharacteristic) {
mediaSelectionCriteria[mediaCharacteristic] = criteria
super.setMediaSelectionCriteria(criteria, forMediaCharacteristic: mediaCharacteristic)
}
}

extension AVQueuePlayer {
Expand Down
12 changes: 12 additions & 0 deletions Sources/Player/Player+MediaSelection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ public extension Player {
queuePlayer.setMediaSelectionCriteria(updatedSelectionCriteria, forMediaCharacteristic: characteristic)
}

/// A binding to read and write the current media selection for a characteristic.
///
/// - Parameter characteristic: The characteristic.
/// - Returns: The binding.
func mediaOption(for characteristic: AVMediaCharacteristic) -> Binding<MediaSelectionOption> {
.init {
self.selectedMediaOption(for: characteristic)
} set: { newValue in
self.select(mediaOption: newValue, for: characteristic)
}
}

/// The current media option for a characteristic.
///
/// - Parameter characteristic: The characteristic.
Expand Down
9 changes: 1 addition & 8 deletions Sources/Player/UserInterface/SettingsMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,14 @@ private struct PlaybackSpeedMenuContent: View {
private struct MediaSelectionMenuContent: View {
let characteristic: AVMediaCharacteristic
@ObservedObject var player: Player
@State private var selection: MediaSelectionOption = .automatic

var body: some View {
Picker("", selection: $selection) {
Picker("", selection: player.mediaOption(for: characteristic)) {
ForEach(mediaOptions, id: \.self) { option in
Text(option.displayName).tag(option)
}
}
.pickerStyle(.inline)
.onAppear {
selection = player.selectedMediaOption(for: characteristic)
}
.onChange(of: selection) { value in
player.select(mediaOption: value, for: characteristic)
}
}

private var mediaOptions: [MediaSelectionOption] {
Expand Down

0 comments on commit ec4ec42

Please sign in to comment.