从Pipestdout获取ffmpeg信息

问题描述

我想打电话给ffmpeg来获取视频文件的持续时间。在OSX Terminal中使用命令时,一切正常:

ffmpeg -i MyVideo.MOV 2>&1 | grep "Duration"

我明白了:

  Duration: 00:01:23.53,start: 0.000000,bitrate: 39822 kb/s

对我来说很完美。但是现在我从代码中尝试了此调用

func shell(launchPath: String,arguments: [String]) -> String
{
    let task = Process()
    task.launchPath = launchPath
    task.arguments  = arguments

    let pipe = Pipe()
    task.standardOutput = pipe
    
    do {
        try task.run()
        // task.launch() till 10.12,but Now catchable!
    } catch let error as NSError {
        print(error.localizedDescription)
        return ""
    }
    
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output: String = Nsstring(data: data,encoding: String.Encoding.utf8.rawValue)! as String

    return output
}

代码对所有其他外部命令都适用。但是这里出现错误

[NULL @ 0x107808800] Unable to find a suitable output format for '2>&1'
2>&1: Invalid argument

我这样定义ffmpeg的参数:

let arguments = ["-i",video.path,"2>&1","|","grep \"Duration\"" ]

即使我将它们全部作为一个较大的字符串放在一个参数中,它也不起作用。使用“ pipe:1”代替“ 2>&1”以及其他参数也会导致错误

任何想法,我如何使它起作用?

解决方法

2>&1意味着standardError(Output)中的所有内容都进入了standardOutput。

嗯,您真的不需要那个吗?

为什么不直接读取standardError(Output)而自己做grep?

let pipe = Pipe()
task.standardError = pipe

... //task.run()

let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output: String = String(data: data,encoding: .utf8)

顺便说一句,让我们避免使用NSString并将其重新广播到String中。

我们也自己做grep

let durationLine = output.components(separatedBy: .newlines).first(where: { $0.contains("Duration") }) 

步骤:让我们获得一个新行数组,并找到带有“ Duration”的第一行。