Xcode 使用AVPlayer在macOS SwiftUI应用程序中播放本地视频文件
我正在尝试使用macOS 10.15.4上的XCode 11.5创建一个简单的SwiftUI应用程序,使用AVKit/AVFoundation播放本地文件系统上存储的视频。我希望能够根据用户操作确定的文件路径选择电影(例如,从一系列菜单选项中选择) 我正在使用以下代码片段: ,使用url(字符串:)或Bundle.main.url(forResource:,带扩展名:)或其他选项定义我的“url”值,但没有成功。应用程序编译并运行时不会出错,但不会显示视频,只会显示一个占位符图像,指示未找到该文件 我不明白panel.url返回的“url”值与我手动分配的值之间有什么区别。我已经使用.absoluteString检查了panel.url的内容,这与我手动分配的值完全匹配Xcode 使用AVPlayer在macOS SwiftUI应用程序中播放本地视频文件,xcode,macos,swiftui,avplayer,avkit,Xcode,Macos,Swiftui,Avplayer,Avkit,我正在尝试使用macOS 10.15.4上的XCode 11.5创建一个简单的SwiftUI应用程序,使用AVKit/AVFoundation播放本地文件系统上存储的视频。我希望能够根据用户操作确定的文件路径选择电影(例如,从一系列菜单选项中选择) 我正在使用以下代码片段: ,使用url(字符串:)或Bundle.main.url(forResource:,带扩展名:)或其他选项定义我的“url”值,但没有成功。应用程序编译并运行时不会出错,但不会显示视频,只会显示一个占位符图像,指示未找到该文
我肯定错过了一些非常明显的东西,但我看不出是什么。请问,有人能提供一些帮助吗?这个问题的简单解决方案:确保视频文件与目标应用程序捆绑在一起 我以为我在这么做,但显然不是,检查(XCode 11)的方法是:
- 单击“项目导航器”窗口中的“视频文件”,然后
- 勾选文件中目标应用程序旁边的目标成员资格框
检查窗
就这样。这个答案应该归功于谁拥有适用于SwiftUI应用程序的AVPlayer解决方案:这正是我想要的。继续,接受你自己的答案。这发生在我们所有人身上。一个正在运行的应用程序中有很多活动部件!很高兴你明白了。
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)
}
}
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)
}
}