Skip to content

Commit e152f3f

Browse files
committed
Implemented subtitles (Closes 207)
1 parent c08c404 commit e152f3f

1 file changed

Lines changed: 58 additions & 4 deletions

File tree

PlayerUI/Views/PUIPlayerView.swift

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ public final class PUIPlayerView: NSView {
237237
player.addObserver(self, forKeyPath: #keyPath(AVPlayer.rate), options: [.initial, .new], context: nil)
238238
player.addObserver(self, forKeyPath: #keyPath(AVPlayer.currentItem.loadedTimeRanges), options: [.initial, .new], context: nil)
239239
player.addObserver(self, forKeyPath: #keyPath(AVPlayer.currentItem.duration), options: [.initial, .new], context: nil)
240+
player.addObserver(self, forKeyPath: #keyPath(AVPlayer.currentItem.currentMediaSelection), options: [.initial, .new], context: nil)
240241

241242
asset?.loadValuesAsynchronously(forKeys: ["tracks"], completionHandler: metadataBecameAvailable)
242243

@@ -259,6 +260,7 @@ public final class PUIPlayerView: NSView {
259260
oldValue.removeObserver(self, forKeyPath: #keyPath(AVPlayer.volume))
260261
oldValue.removeObserver(self, forKeyPath: #keyPath(AVPlayer.currentItem.loadedTimeRanges))
261262
oldValue.removeObserver(self, forKeyPath: #keyPath(AVPlayer.currentItem.duration))
263+
oldValue.removeObserver(self, forKeyPath: #keyPath(AVPlayer.currentItem.currentMediaSelection))
262264
}
263265

264266
public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
@@ -273,6 +275,8 @@ public final class PUIPlayerView: NSView {
273275
self.updatePlayingState()
274276
} else if keyPath == #keyPath(AVPlayer.currentItem.duration) {
275277
self.metadataBecameAvailable()
278+
} else if keyPath == #keyPath(AVPlayer.currentItem.currentMediaSelection) {
279+
self.updateMediaSelection()
276280
} else {
277281
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
278282
}
@@ -790,10 +794,6 @@ public final class PUIPlayerView: NSView {
790794
}
791795
}
792796

793-
@IBAction func showSubtitlesMenu(_ sender: PUIButton) {
794-
// TODO: show subtitles menu
795-
}
796-
797797
@IBAction public func togglePlaying(_ sender: Any?) {
798798
if isPlaying {
799799
pause(sender)
@@ -879,6 +879,60 @@ public final class PUIPlayerView: NSView {
879879
}
880880
}
881881

882+
// MARK: - Subtitles
883+
884+
private var subtitlesMenu: NSMenu?
885+
private var subtitlesGroup: AVMediaSelectionGroup?
886+
887+
private func updateMediaSelection() {
888+
guard let playerItem = player?.currentItem else { return }
889+
890+
guard let subtitlesGroup = playerItem.asset.mediaSelectionGroup(forMediaCharacteristic: AVMediaCharacteristicLegible) else {
891+
subtitlesButton.isHidden = true
892+
return
893+
}
894+
895+
self.subtitlesGroup = subtitlesGroup
896+
897+
let currentMediaSelection = playerItem.currentMediaSelection
898+
899+
subtitlesButton.isHidden = false
900+
901+
let menu = NSMenu()
902+
903+
subtitlesGroup.options.forEach { option in
904+
let item = NSMenuItem(title: option.displayName, action: #selector(didSelectSubtitleOption(_:)), keyEquivalent: "")
905+
item.representedObject = option
906+
item.target = self
907+
908+
menu.addItem(item)
909+
}
910+
911+
self.subtitlesMenu = menu
912+
}
913+
914+
@objc fileprivate func didSelectSubtitleOption(_ sender: NSMenuItem) {
915+
guard let subtitlesGroup = self.subtitlesGroup else { return }
916+
guard let option = sender.representedObject as? AVMediaSelectionOption else { return }
917+
918+
// reset all item's states
919+
sender.menu?.items.forEach({ $0.state = NSOffState })
920+
921+
if option.extendedLanguageTag == player?.currentItem?.selectedMediaOption(in: subtitlesGroup)?.extendedLanguageTag {
922+
player?.currentItem?.select(nil, in: subtitlesGroup)
923+
sender.state = NSOffState
924+
return
925+
}
926+
927+
player?.currentItem?.select(option, in: subtitlesGroup)
928+
929+
sender.state = NSOnState
930+
}
931+
932+
@IBAction func showSubtitlesMenu(_ sender: PUIButton) {
933+
subtitlesMenu?.popUp(positioning: nil, at: .zero, in: sender)
934+
}
935+
882936
// MARK: - Key commands
883937

884938
private var keyDownEventMonitor: Any?

0 commit comments

Comments
 (0)