-
-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathMediaPlayerWindowController.swift
More file actions
108 lines (83 loc) · 3.08 KB
/
MediaPlayerWindowController.swift
File metadata and controls
108 lines (83 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import Cocoa
import AVKit
import SMBClient
private let storyboardID = "MediaPlayerWindowController"
class MediaPlayerWindowController: NSWindowController, NSWindowDelegate {
static let supportedExtensions = {
let fileTypes: [AVFileType] = AVURLAsset.audiovisualTypes()
let extensions = fileTypes
.compactMap { UTType($0.rawValue)?.preferredFilenameExtension }
return extensions
}()
private let treeAccessor: TreeAccessor
private let path: String
private lazy var asset = SMBAVAsset(accessor: treeAccessor, path: path)
private var observation: NSKeyValueObservation?
private var windowController: NSWindowController?
static func instantiate(path: String, accessor: TreeAccessor) -> Self {
let storyboard = NSStoryboard(name: storyboardID, bundle: nil)
return storyboard.instantiateController(identifier: storyboardID) { (coder) in
Self(coder: coder, path: path, accessor: accessor)
}
}
required init?(coder: NSCoder, path: String, accessor: TreeAccessor) {
self.path = path
self.treeAccessor = accessor
super.init(coder: coder)
}
required init?(coder: NSCoder) {
return nil
}
deinit {
observation?.invalidate()
}
override func windowDidLoad() {
super.windowDidLoad()
guard let window else { return }
window.appearance = NSAppearance(named: .darkAqua)
window.title = URL(fileURLWithPath: path).lastPathComponent
window.delegate = self
guard let videoPlayerViewController = contentViewController as? MediaPlayerViewController else { return }
Task { @MainActor in
do {
let fileReader = try await treeAccessor.fileReader(path: path)
_ = try await fileReader.read(offset: 0, length: 1)
try await fileReader.close()
let playerItem = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: playerItem)
videoPlayerViewController.playerView.player = player
asset.loadTracks(withMediaType: .video) { (tracks, error) in
guard let track = tracks?.first else { return }
Task {
let naturalSize = try await track.load(.naturalSize)
await MainActor.run {
guard let currentScreen = NSScreen.screens.first(where: { $0 == window.screen }) else {
return
}
let rect = AVMakeRect(
aspectRatio: CGSize(width: naturalSize.width, height: naturalSize.height),
insideRect: currentScreen.visibleFrame
)
let contentSize = NSSize(width: min(rect.width, naturalSize.width), height: min(rect.height, naturalSize.height))
window.setContentSize(contentSize)
window.center()
player.play()
}
}
}
} catch {
_ = await MainActor.run {
NSAlert(error: error).runModal()
}
}
}
windowController = self
}
func windowWillClose(_ notification: Notification) {
asset.close()
windowController = nil
}
}
class MediaPlayerViewController: NSViewController {
@IBOutlet var playerView: AVPlayerView!
}