Swift和NSTask停顿问题

3

我是Mac世界的新手。我正在使用Swift,并尝试逐个运行外部进程。 只要调试过,一切都很好,我的意思是:在附有调试器的Xcode中运行。

我没有做任何更改,尝试从“Debug”文件夹中的位置在终端窗口中运行它。现在外部进程开始了,但卡住了。已经关闭了一些STDERR输出。并且外部任务需要进行磁盘IO。

let video : NSTask = NSTask()
video.launchPath = "./ffmpeg"
video.arguments = ["-i", "\(item)", "-c:v","copy", "-bsf:v", "h264_mp4toannexb", "-an", "-y", "-loglevel", "quiet", "\(path).h264"]

//also tried without the following two lines
video.standardError = NSFileHandle.fileHandleWithStandardError()
video.standardOutput = NSFileHandle.fileHandleWithStandardOutput()

video.launch()
video.waitUntilExit()

是的:我把所有内容复制到当前路径,这样就可以执行了。但是在终端运行时会停顿。

现在问题来了:为什么?我在这里做错了什么?简单的解决方案是始终在Xcode中运行它,但是你可能会想象到,对于一个命令行工具来说,这非常不方便。

1个回答

6
您需要将标准输入重定向到/dev/null。ffmpeg已经打开了标准输入并正在等待该管道上的更多数据。
video.standardInput = NSFileHandle.fileHandleWithNullDevice()

请注意,你不需要将你的作业输出到standardErrorstandardOutput。这些是默认设置。
在Xcode中,这个操作是可行的,因为调试器会自动关闭标准输入(stdin)。

谢谢你提供的解决方案,非常完美。我想知道是否有任何资源可以帮助理解为什么关闭“standardInput”会解决这个问题?谢谢! - Honghao Z
2
@HonghaoZhang 请查看http://ffmpeg.org/ffmpeg.html并阅读有关`-stdin`的文档。正如它所指出的那样,您也可以通过传递`-nostdin`作为参数而不是关闭stdin来解决此问题。他们列出的解决方案`< /dev/null`与此答案相同(只是shell的方式而不是Swift的方式)。 - Rob Napier
非常感谢!如果进程在后台运行,使用“-nostdin”会更好。 - Honghao Z

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接