Реалізація обрізки та редагування відео в мобільному додатку
Ми стикаємося із завданням впровадження відеоредактора майже в кожному другому мобільному проєкті. Клієнти хочуть, щоб користувач міг обрізати зайві секунди, склеїти декілька кліпів або накласти текст — і все це без зависань на 30 секунд. Здається, що API для роботи з відео є на кожній платформі, але підводних каменів вистачає: frame-accurate trimming, плавний таймлайн, швидкий експорт без блокування UI. Розберемо, як ми вирішуємо ці проблеми на iOS та Android.
Чому обрізка відео — нетривіальне завдання?
Обрізка за часом (trimming). На iOS ми використовуємо AVAssetExportSession з timeRange:
exportSession.timeRange = CMTimeRange( start: CMTime(seconds: startTime, preferredTimescale: 600), duration: CMTime(seconds: duration, preferredTimescale: 600) ) preferredTimescale: 600 — стандарт для відео, кратний 24/25/30/60 fps. Використання timescale: 1 дає помилки округлення на фреймах. На Android — MediaMuxer + MediaExtractor для frame-accurate trimming без перекодування (тільки якщо збігаються ключові кадри). Якщо ні — Transformer з media3 з явним перекодуванням. Такий підхід гарантує точність до кадру, що критично для професійного монтажу.
Як об'єднати кліпи без втрати якості?
Об'єднання кліпів. iOS: AVMutableComposition — додаємо AVMutableCompositionTrack для відео та аудіо, вставляємо через insertTimeRange(_:of:at:). Важливо: аудіодоріжки об'єднуються окремо від відеодоріжок, інакше розсинхронізація. Android: media3 Transformer з Composition API (1.2.x+). Послідовність кліпів — EditedMediaItemSequence. Ми налаштовуємо аудіомікс так, щоб переходи були безшовними — жодних клацань або затримок.
Текстові накладення. iOS: AVVideoComposition + AVVideoCompositionCoreAnimationTool. Створюємо CATextLayer, додаємо анімацію появи через CABasicAnimation, передаємо в animationTool. На Android — OverlayEffect в media3 Transformer або малюємо через Canvas на кожному кадрі (повільно, тільки для короткого контенту). Для довгих відео ми віддаємо перевагу нативним накладенням через SurfaceView — це дає до 3x приріст продуктивності порівняно з Canvas.
Таймлайн-перегляд
Найпомітніша користувачеві деталь — смужка з кадрами відео під плеєром. Генеруємо через AVAssetImageGenerator на iOS:
generator.generateCGImagesAsynchronously(forTimes: times) { _, image, _, _, _ in // оновлюємо UI на головному потоці } requestedTimeToleranceBefore/After = .zero дає точні кадри, але повільніше. Для таймлайну достатньо CMTime(seconds: 0.1, preferredTimescale: 600) — кадри найближчі до позначки. На Android — MediaMetadataRetriever.getFrameAtTime() в IO Dispatcher. Ми кешуємо згенеровані кадри в LRU-кеші, щоб при скролі не було підгальмовувань.
Експорт
Завжди асинхронно, з прогресом. iOS: exportSession.progress через Timer кожні 0.1 с. Android: Transformer.addListener з onProgress(progress: Float). Формат виводу: H.264 в MP4 — максимальна сумісність. H.265 (HEVC) — менший розмір, але не всі сервери приймають без перекодування.
| Пресет iOS | Роздільна здатність | Бітрейт (прибл.) |
|---|---|---|
AVAssetExportPreset640x480 |
640×480 | ~1.5 Мбіт/с |
AVAssetExportPreset1280x720 |
1280×720 | ~5 Мбіт/с |
AVAssetExportPreset1920x1080 |
1920×1080 | ~10 Мбіт/с |
| Кастомний AVVideoSettings | будь-яке | контрольований |
Порівняння продуктивності: нативна реалізація на iOS через AVAssetExportSession у 2–3 рази швидша за аналогічне рішення на FFmpeg (через апаратне декодування). На Android MediaCodec з H.264 дає до 50% приросту швидкості відносно програмного кодування.
Flutter: video_editor
video_editor (pub.dev) надає UI-компоненти (таймлайн, кроппер) поверх ffmpeg_kit_flutter для реальних операцій. Плюс — крос-платформний Flutter-код для UI. Мінус — FFmpeg обробляє відео на CPU, що повільніше за нативні AVFoundation/MediaCodec рішення — різниця може сягати 3–5 разів на довгих відео. Для MVP та нескладного контенту підходить, для production-редактора з частим використанням — краща нативна реалізація. У нас є досвід міграції з Flutter-редактора на нативний, це скоротило час експорту з 45 до 12 секунд для 2-хвилинного ролика.
Що входить у роботу
- Аналіз вимог до функціональності (обрізка, склейка, накладення, ефекти)
- Проєктування архітектури: вибір фреймворків, налаштування пайплайну обробки
- Реалізація core-модулів: trimming, composition, export з unit-тестами
- Інтеграція таймлайну з переглядом та обробкою жестів
- Оптимізація продуктивності: кешування кадрів, асинхронна обробка, апаратне прискорення
- Тестування на різних пристроях (iPhone SE — iPhone 15 Pro, Xiaomi Redmi — Samsung Galaxy S24)
- Збірка та деплой в App Store / Google Play з налаштуванням code signing та provisioning profiles
- Документація з інтеграції (API схеми, приклади коду, інструкція з налаштування магазину)
Ми гарантуємо, що реалізований функціонал пройде модерацію App Store (Section 4.2 — мінімалізм, 5.1 — конфіденційність) та Google Play (політика використання медіа).
Терміни та оцінка
Базова обрізка за часом + експорт — 2–3 робочі дні. Повноцінний редактор з таймлайном, об'єднанням кліпів та текстовими накладеннями — 5–8 робочих днів. Терміни уточнюються після брифінгу: на складність впливає кількість ефектів, підтримка HDR, робота з субтитрами. Напишіть — оцінимо ваш проєкт безкоштовно. За 5+ років ми реалізували понад 20 медіа-проєктів для iOS та Android, включаючи потокові відео-редактори та додатки для UGC.







