Я строил ферму рендеринга и устал от установки и обновления ffmpeg отдельно на каждом компьютере узла рендеринга.Если вы хотите использовать ffmpeg в приложении OS X, вы можете использовать предварительно скомпилированные параметры, и вы можете использовать NSTask, самый простой способ, который я нашел, это:
1.Загрузите бесплатное приложение Unarchiver, если у вас его еще нет (доступно в App Store).
2.Перейдите на сайт ffmpeg> Загрузки> (значок Apple)> нажмите «Статическая сборка для OS X 64-разрядная версия Intel» и загрузите любой необходимый пакет.Это будет файл типа "ffmpeg-3.0.2-2.7z".
3.Откройте его с помощью Unarchiver, вы получите файл UNIX, просто названный "ffmpeg".
4.Перетащите этот файл в ваш проект Xcode.Когда вы скомпилируете, он будет в основном комплекте вашего приложения.
5.Настройте свой NSTask, что-то вроде этого (пример на Swift):
guard let launchPath = NSBundle.mainBundle().pathForResource("ffmpeg", ofType: "") else { return }
dispatch_async(dispatch_get_main_queue()) {
let compressTask: NSTask = NSTask()
compressTask.launchPath = launchPath
compressTask.arguments = [
"-y",
"-i", myUncompressedInputFilePath,
"-vcodec", "libx264",
"-b:v", "1500k",
"-c:a", "aac",
"-pix_fmt", "yuv420p", // Necessary to allow playback in OS X Finder and QT Player
myCompressedOutputFilePath
]
compressTask.standardInput = NSFileHandle.fileHandleWithNullDevice()
compressTask.launch()
compressTask.waitUntilExit()
// Do cleanup work here if necessary.
}
Все, супер просто и отлично работает.Асинхронная отправка необязательна, удалите ее, если хотите, чтобы она работала синхронно, но она заблокирует выполнение вашей программы.Вы можете установить любые параметры, которые вы обычно можете использовать в командной строке, включая то, какие кодеки использовать, битрейт, масштабирование и т. Д. Вывод также будет отображаться на панели отладки XCode (управляйте количеством с помощью параметра -loglevel).*
Выполнение 2-проходного кодирования также очень просто (и имеет большое значение по качеству):
guard let launchPath = NSBundle.mainBundle().pathForResource("ffmpeg", ofType: "") else { return }
dispatch_async(dispatch_get_main_queue()) {
// Make this a unique name to avoid conflicts if you have simultaneous encodings.
let passLogFilePath = "\(NSTemporaryDirectory())\(NSUUID().UUIDString)_passlog"
let compressPass1: NSTask = NSTask()
compressPass1.launchPath = launchPath
compressPass1.arguments = [
"-y",
"-i", myUncompressedInputFilePath,
"-pass", "1",
"-passlogfile", passLogFilePath,
"-vcodec", "libx264",
"-b:v", "1500k",
"-c:a", "aac",
"-f", "mov",
"/dev/null"
]
compressPass1.standardInput = NSFileHandle.fileHandleWithNullDevice()
compressPass1.launch()
compressPass1.waitUntilExit()
let compressPass2: NSTask = NSTask()
compressPass2.launchPath = launchPath
compressPass2.arguments = [
"-y",
"-i", myUncompressedInputFilePath,
"-pass", "2",
"-passlogfile", passLogFilePath,
"-vcodec", "libx264",
"-b:v", "1500k",
"-c:a", "aac",
"-pix_fmt", "yuv420p", // Necessary to allow playback in OS X Finder and QT Player
myCompressedOutputFilePath
]
compressPass2.standardInput = NSFileHandle.fileHandleWithNullDevice()
compressPass2.launch()
compressPass2.waitUntilExit()
// Clean up ffmpeg pass log files, there should be two of them.
let fm = NSFileManager.defaultManager()
if fm.fileExistsAtPath("\(passLogFilePath)-0.log") {
do {
try fm.removeItemAtPath("\(passLogFilePath)-0.log")
} catch {
print("Failed to remove '-0.log' file.")
}
}
if fm.fileExistsAtPath("\(passLogFilePath)-0.log.mbtree") {
do {
try fm.removeItemAtPath("\(passLogFilePath)-0.log.mbtree")
} catch {
print("Failed to remove '-0.log.mbtree' file.")
}
}
}