Інтеграція FFmpeg для обробки мультимедіа в мобільному застосунку
FFmpeg на мобільному пристрої — це коли потрібно транскодувати відео, витягти аудіо, зліпити кілька доріжок, конвертувати формат або нарізати медіафайл прямо на телефоні без відправки на сервер. Нативні API (AVFoundation, MediaCodec) не охоплюють усі ці сценарії — FFmpeg охоплює.
Підключення FFmpeg до проекту
iOS. ffmpeg-kit — мобільна збірка FFmpeg з обгорткою Swift/Objective-C:
// Podfile
pod 'ffmpeg-kit-ios-full', '~> 6.0'
// Використання
FFmpegKit.executeAsync("-i input.mp4 -vn -acodec copy output.aac") { session in
guard let returnCode = session?.getReturnCode() else { return }
if ReturnCode.isSuccess(returnCode) {
print("Готово: \(session?.getOutput() ?? "")")
} else {
print("Помилка: \(session?.getLogsAsString() ?? "")")
}
}
Android. Той же ffmpeg-kit-android (Maven):
implementation("com.arthenica:ffmpeg-kit-android:6.0.LTS")
FFmpegKit.executeAsync(
"-i input.mp4 -vf scale=1280:720 -c:v libx264 -preset ultrafast -crf 23 output.mp4"
) { session ->
if (ReturnCode.isSuccess(session.returnCode)) {
// обробляємо результат на main thread
}
}
ffmpeg-kit поставляється в кількох варіантах збірки: min (мінімальний набір кодеків), min-gpl, https, full, full-gpl. Для більшості завдань достатньо https (H.264, AAC, MP3, HTTPS-потоки). full-gpl включає x264, x265, libvpx — потрібен якщо хочемо кодувати H.264 через libx264 замість системного кодека.
Flutter. ffmpeg_kit_flutter (pub.dev) — та ж бібліотека з обгорткою Dart.
Типові завдання та команди
Транскодування відео
# H.264, 720p, CRF 23 (баланс якість/розмір)
-i input.mov -c:v libx264 -preset ultrafast -crf 23 -c:a aac -b:a 128k -vf scale=1280:720 output.mp4
-preset ultrafast — швидкість кодування важливіше розміру файлу. На телефоні CPU повільний, ultrafast або superfast — розумний вибір для UGC-контенту. veryfast дає помітно менший розмір, але кодує в 2–3 рази довше.
Обрізка без перекодування
# Stream copy — швидко, без втрати якості, але точність до ключового кадру
-i input.mp4 -ss 00:00:10 -to 00:00:30 -c copy output.mp4
# Точна обрізка — повільніше, але frame-accurate
-i input.mp4 -ss 00:00:10 -to 00:00:30 output.mp4
-c copy не перекодує — працює за секунди. Без -c copy FFmpeg декодує та перекодує кожен кадр. Для UI застосунку: показуємо кнопку «Швидка обрізка» (з copy) і «Точна обрізка» (з перекодуванням).
Об'єднання файлів
# Concat через список файлів (один формат)
-f concat -safe 0 -i filelist.txt -c copy output.mp4
filelist.txt містить шляхи: file '/path/to/clip1.mp4'\nfile '/path/to/clip2.mp4'. Створюємо файл програмно в тимчасовій директорії перед викликом.
Витягування аудіо, заміна звукової доріжки
# Витягти аудіо
-i input.mp4 -vn -acodec copy output.aac
# Замінити аудіо у відео
-i video.mp4 -i audio.aac -c:v copy -map 0:v:0 -map 1:a:0 output.mp4
Накладення водяного знаку
-i input.mp4 -i watermark.png -filter_complex "overlay=W-w-10:H-h-10" output.mp4
W-w-10:H-h-10 — правий нижній кут з відступом 10 px.
Моніторинг прогресу
FFmpeg пише прогрес у stderr. ffmpeg-kit надає StatisticsCallback:
FFmpegKit.executeAsync(command,
withCompleteCallback: { session in /* завершено */ },
withLogCallback: nil,
withStatisticsCallback: { stats in
guard let duration = totalDurationMs else { return }
let progress = Double(stats?.getTime() ?? 0) / duration
DispatchQueue.main.async { self.progressBar.progress = Float(progress) }
}
)
stats.getTime() — поточна позиція обробки в мілісекундах. Отримати totalDurationMs можна через FFprobeKit.getMediaInformationAsync.
Продуктивність та обмеження
На iPhone 14 Pro транскодування 1-хвилинного 1080p відео через libx264 ultrafast займає ~45–60 секунд. Це багато для UX. Альтернативи:
-
Системний кодировщик через
VideoToolbox:-c:v h264_videotoolbox— використовує апаратне прискорення Apple, в 5–10 разів швидше, менше контролю над бітрейтом -
На Android:
-c:v h264_mediacodec— апаратний H.264 через MediaCodec
Апаратний кодировщик доступний не на всіх пристроях та версіях. Додаємо fallback на libx264:
val command = if (isHardwareEncoderAvailable()) {
"-i input.mp4 -c:v h264_mediacodec output.mp4"
} else {
"-i input.mp4 -c:v libx264 -preset ultrafast output.mp4"
}
Розмір бінарника: ffmpeg-kit-full додає ~30–50 МБ до розміру застосунку. ffmpeg-kit-min — ~8–12 МБ. Виділяємо мінімальну збірку під конкретні завдання.
Строки
Базова інтеграція з однією-двома операціями (обрізка + конвертація) — 2 дні. Повнофункціональний медіапроцесор з прогресом, чергою завдань та fallback на системні API — 4–5 днів.







