在macOS SwiftUI应用程序中使用AVPlayer播放本地视频文件。

问题描述 投票:1回答:1

我试图在macOS 10.15.4上使用XCode 11.5创建一个简单的SwiftUI应用程序,使用AVKitAVFoundation来播放存储在本地文件系统上的视频。我希望能够根据用户的操作(例如从一系列的菜单选项中选择)确定的文件路径来选择电影。

我从这里找到了一个代码片段。https:/qiita.comcroquette0212itemseb97e970d1dcfa2932fd。

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)
    }
}

在使用 "panel "对象选择文件时,这样做的效果非常好,但我无法解决将自己的 "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(string:)或Bundle.main.url(forResource:, withExtension:)或其他选项定义我的 "url "值,但没有成功。应用程序编译和运行时没有出错,但它没有显示视频,只有一个占位图,表示没有找到文件。

我不明白从panel.url返回的 "url "值和我手动分配的值有什么区别。我使用.absoluteString检查了panel.url的内容,这与我手动分配的值完全一致。

我肯定遗漏了一些非常明显的东西,但我看不出是什么。拜托,谁能提供一些帮助?

xcode macos swiftui avplayer avkit
1个回答
1
投票

这个问题的简单解决方案:确保视频文件被捆绑在目标应用程序中。

我以为我是这样做的,但显然不是,一个检查的方法(XCode 11)是。

  • 在 "项目导航 "窗口中点击视频文件,然后:

  • 在 "文件检查器 "窗口中勾选目标应用程序旁边的 "目标成员 "框。

就这样吧。这个答案的功劳属于 https:/github.comSergioEstevao。 他有一个针对SwiftUI应用的AVPlayer解决方案。https:/github.comSergioEstevaoSVEVideoUI。 这正是我想要的。

© www.soinside.com 2019 - 2024. All rights reserved.