无法在 macOS 应用程序的 FFMPEG 进程中通过 NSOpenPanel 访问用户选择的文件
Unable to access user selected file via NSOpenPanel in FFMPEG process in macOS app
我是通过 SwiftUI 进行 macOS 开发的新手。在通过 NSOpenPanel
选择 MP4 文件后,我正在尝试 运行 一个 FFMPEG 进程。但是,FFMPEG
回应:
file:///Users/MyUsername/Documents/Video.mp4: No such file or directory
这是我的简单代码:
import SwiftUI
struct ContentView: View {
@State var selectedURL: URL?
var body: some View {
VStack {
if selectedURL != nil {
Text("Selected: \(selectedURL!.absoluteString)")
} else {
Text("Nothing selected")
}
Button(action: {
let panel = NSOpenPanel()
panel.allowedFileTypes = ["mp4"]
panel.canChooseDirectories = false
panel.canCreateDirectories = false
panel.allowsMultipleSelection = false
let result = panel.runModal()
if result == .OK {
self.selectedURL = panel.url
let savePath = self.getDownloadDirectory().appendingPathComponent("video.webm")
self.convertVideo(inputFilePath: self.selectedURL!.absoluteString, outputFilePath: savePath.absoluteString, callback: {(s) in
// omit the callback at this moment
})
}
}) {
Text("Select File")
}
}
.frame(width: 640, height: 480)
}
func getDownloadDirectory() -> URL {
let paths = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask)
return paths[0]
}
func convertVideo(inputFilePath: String, outputFilePath: String,
callback: @escaping (Bool) -> Void) -> (Process, DispatchWorkItem)? {
guard let launchPath = Bundle.main.path(forResource: "ffmpeg", ofType: "") else {
return nil
}
let process = Process()
let task = DispatchWorkItem {
process.launchPath = launchPath
process.arguments = [
"-y",
"-i", inputFilePath,
"-vcodec", "vp8",
"-acodec", "libvorbis",
"-pix_fmt", "yuva420p",
"-metadata:s:v:0",
"alpha_mode=\"1\"",
"-auto-alt-ref", "0",
outputFilePath
]
process.standardInput = FileHandle.nullDevice
process.launch()
process.terminationHandler = { process in
callback(process.terminationStatus == 0)
}
}
DispatchQueue.global(qos: .userInitiated).async(execute: task)
return (process, task)
}
}
我错过了什么让 FFMPEG 进程访问我选择的文件?谢谢!
尝试使用 .path
而不是 .absoluteString
self.convertVideo(inputFilePath: self.selectedURL!.path,
outputFilePath: savePath.absoluteString, callback: {(s) in
我是通过 SwiftUI 进行 macOS 开发的新手。在通过 NSOpenPanel
选择 MP4 文件后,我正在尝试 运行 一个 FFMPEG 进程。但是,FFMPEG
回应:
file:///Users/MyUsername/Documents/Video.mp4: No such file or directory
这是我的简单代码:
import SwiftUI
struct ContentView: View {
@State var selectedURL: URL?
var body: some View {
VStack {
if selectedURL != nil {
Text("Selected: \(selectedURL!.absoluteString)")
} else {
Text("Nothing selected")
}
Button(action: {
let panel = NSOpenPanel()
panel.allowedFileTypes = ["mp4"]
panel.canChooseDirectories = false
panel.canCreateDirectories = false
panel.allowsMultipleSelection = false
let result = panel.runModal()
if result == .OK {
self.selectedURL = panel.url
let savePath = self.getDownloadDirectory().appendingPathComponent("video.webm")
self.convertVideo(inputFilePath: self.selectedURL!.absoluteString, outputFilePath: savePath.absoluteString, callback: {(s) in
// omit the callback at this moment
})
}
}) {
Text("Select File")
}
}
.frame(width: 640, height: 480)
}
func getDownloadDirectory() -> URL {
let paths = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask)
return paths[0]
}
func convertVideo(inputFilePath: String, outputFilePath: String,
callback: @escaping (Bool) -> Void) -> (Process, DispatchWorkItem)? {
guard let launchPath = Bundle.main.path(forResource: "ffmpeg", ofType: "") else {
return nil
}
let process = Process()
let task = DispatchWorkItem {
process.launchPath = launchPath
process.arguments = [
"-y",
"-i", inputFilePath,
"-vcodec", "vp8",
"-acodec", "libvorbis",
"-pix_fmt", "yuva420p",
"-metadata:s:v:0",
"alpha_mode=\"1\"",
"-auto-alt-ref", "0",
outputFilePath
]
process.standardInput = FileHandle.nullDevice
process.launch()
process.terminationHandler = { process in
callback(process.terminationStatus == 0)
}
}
DispatchQueue.global(qos: .userInitiated).async(execute: task)
return (process, task)
}
}
我错过了什么让 FFMPEG 进程访问我选择的文件?谢谢!
尝试使用 .path
而不是 .absoluteString
self.convertVideo(inputFilePath: self.selectedURL!.path,
outputFilePath: savePath.absoluteString, callback: {(s) in