Use FFMPEG in XCode(for MacOS)
1. Download FFMPEG binary
Visit https://ffmpeg.org -> Download -> Apple logo -> Download "Static builds for OS X Intel 64-bit". This will contain single ffmpeg binary.
2. Add "ffmpeg" from above as bundle resource
3. Use Bundle to execute ffmpeg command
You can also intercept console output from the process or interrupt the process when problem occurred.
References
- http://stackoverflow.com/a/37422688/2279149
Visit https://ffmpeg.org -> Download -> Apple logo -> Download "Static builds for OS X Intel 64-bit". This will contain single ffmpeg binary.
2. Add "ffmpeg" from above as bundle resource
3. Use Bundle to execute ffmpeg command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func filterVideo(inputFilePath: String, outputFilePath: String, | |
filterPath: 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, | |
"-filter_script:v", filterPath, | |
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) | |
} |
You can also intercept console output from the process or interrupt the process when problem occurred.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typealias ProcessMeta = (Process, DispatchWorkItem) | |
typealias ProgressCallback = (String) -> Void | |
typealias ProcessResult = ([String], [String], Int32) | |
private func createBundleProcess(bundleName: String, bundleType: String? = nil, | |
arguments: [String]?, progressCallback: ProgressCallback? = nil, | |
callback: @escaping (ProcessResult) -> Void) -> ProcessMeta? { | |
guard let launchPath = Bundle.main.path(forResource: bundleName, ofType: bundleType) else { | |
return nil | |
} | |
let process = Process() | |
var output : [String] = [] | |
var error : [String] = [] | |
let outpipe = Pipe() | |
process.standardOutput = outpipe | |
let errpipe = Pipe() | |
process.standardError = errpipe | |
let task = DispatchWorkItem { | |
process.launchPath = launchPath | |
process.arguments = arguments | |
process.standardInput = FileHandle.nullDevice | |
let errorHandler: (Data) -> Void = { data in | |
if let str = String(data: data, encoding: .utf8) { | |
print(str) | |
if str.contains("Error while decoding stream") { | |
process.interrupt() | |
} | |
} | |
} | |
var outdata = Data() | |
outpipe.fileHandleForReading.readabilityHandler = { handle in | |
let data = handle.availableData | |
outdata.append(data) | |
if let msg = String(data: data, encoding: .utf8) { | |
progressCallback?(msg) | |
} | |
errorHandler(data) | |
} | |
var errdata = Data() | |
errpipe.fileHandleForReading.readabilityHandler = { handle in | |
let data = handle.availableData | |
errdata.append(data) | |
if let msg = String(data: data, encoding: .utf8) { | |
progressCallback?(msg) | |
} | |
errorHandler(data) | |
} | |
process.terminationHandler = { process in | |
if var string = String(data: outdata, encoding: .utf8) { | |
string = string.trimmingCharacters(in: .newlines) | |
output = string.components(separatedBy: "\n") | |
} | |
if var string = String(data: errdata, encoding: .utf8) { | |
string = string.trimmingCharacters(in: .newlines) | |
error = string.components(separatedBy: "\n") | |
} | |
callback((output, error, process.terminationStatus)) | |
} | |
process.launch() | |
process.waitUntilExit() | |
} | |
return (process, task) | |
} |
References
- http://stackoverflow.com/a/37422688/2279149
댓글
댓글 쓰기