Я пытаюсь создать простое приложение SwiftUI, используя XCode 11.5 в macOS 10.15.4, используя AVKit / AVFoundation для воспроизведения видео, хранящихся в локальной файловой системе. Я хотел бы иметь возможность выбрать mov ie на основе пути к файлу, определяемого действиями пользователя (например, выбор из ряда опций меню).
Я работаю с фрагментом кода, найденным здесь: https://qiita.com/croquette0212/items/eb97e970d1dcfa2932fd
import SwiftUI
import AVKit
import AVFoundation
class VideoItem: ObservableObject {
@Published var player: AVPlayer = AVPlayer()
@Published var playerItem: AVPlayerItem?
func open(_ url: URL) {
let asset = AVAsset(url: url)
let playerItem = AVPlayerItem(asset: asset)
self.playerItem = playerItem
player.replaceCurrentItem(with: playerItem)
}
}
struct PlayerView: NSViewRepresentable {
@Binding var player: AVPlayer
func updateNSView(_ NSView: NSView, context: NSViewRepresentableContext<PlayerView>) {
guard let view = NSView as? AVPlayerView else {
debugPrint("unexpected view")
return
}
view.player = player
}
func makeNSView(context: Context) -> NSView {
return AVPlayerView(frame: .zero)
}
}
struct ContentView: View {
@ObservedObject var videoItem: VideoItem = VideoItem()
var body: some View {
VStack {
if videoItem.playerItem != nil {
PlayerView(player: $videoItem.player)
}
Button(action: {
let panel = NSOpenPanel()
panel.allowedFileTypes = [kUTTypeMovie as String]
DispatchQueue.main.async {
if panel.runModal() == .OK {
guard let url = panel.url else {
return
}
self.videoItem.open(url)
}
}
}) {
Text("Open")
}
}.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
Это отлично работает для выбора файла с помощью объекта «панель», но я не могу понять простое изменение передачи моего собственного значения « url »на videoItem.open ().
Я попытался заменить блок:
let panel = NSOpenPanel()
panel.allowedFileTypes = [kUTTypeMovie as String]
DispatchQueue.main.async {
if panel.runModal() == .OK {
guard let url = panel.url else {
return
}
self.videoItem.open(url)
}
}
, определив свое значение« url »с помощью URL (string :) или Bundle.main. url (forResource :, withExtension:) или другие параметры безуспешно. Приложение компилируется и запускается без ошибок, но оно не отображает видео, а только изображение-заполнитель, указывающее, что файл не был найден.
Я не понимаю, в чем разница между значением "url" возвращается из panel.url и значений, которые я присваиваю вручную. Я проверил содержимое panel.url с помощью .absoluteString, и это в точности соответствует значениям, которые я присваиваю вручную.
Мне, конечно, не хватает чего-то очень очевидного, но я не вижу, что это такое. Кто-нибудь может помочь?