Ми спеціалізуємося на розробці публікації відео в мобільних додатках. Успішний мобільний додаток відео потребує ретельної обробки медіа. Типова проблема: користувач знімає 4K/60fps відео — 400 МБ за 60 секунд. Якщо гнати такий файл на сервер без обробки, завантаження затягнеться на хвилини, а плеєр у стрічці буде лагати. Економія на трафіку при транскодуванні може досягати $500 щомісяця при 1000 постів. Рішення — транскодування, обрізка та upload з відновленням. Нижче — як це зробити на iOS і Android з урахуванням кращих практик. Наш досвід: більше 5 років у мобільній розробці, більше 20 проектів з відеоконтентом. Якщо вам потрібна така функція, зв'яжіться з нами для консультації.
Вибір та обрізка відео для публікації
PHPickerViewController з filter: .videos на iOS. Для соціальних постів зазвичай обмежуємо довжину — 60–90 секунд. Перевіряємо тривалість через PHAsset.duration ще в пікері, до завантаження даних. Саме тому завантаження відео в додаток має бути надійним.
Обрізка — AVPlayerViewController з вбудованим trim editor (iOS 14+, AVPlayerViewController.allowedPictureInPictureMediaTypes), або кастомний тример через AVPlayer + AVPlayerLayer з drag-handles для CMTimeRange. Кастомний тример дає повний контроль над UI, але вимагає ~2–3 днів розробки окремо. На iOS обрізка відео iOS реалізована через AVPlayerViewController з trim editor. На Android — VideoTrimmingView через MediaPlayer + MediaMetadataRetriever для генерації тайм-лайну. Або використовуємо isoviewer / mp4parser для обрізки без повного декодування. Обрізка відео Android через VideoTrimmingView або mp4parser.
Технічні деталі вибору медіа
На iOS використовуємо `PHPhotoLibrary.requestAuthorization(for: .readWrite)` для доступу до галереї. На Android — `ActivityResultContracts.GetContent()` з MIME-типом `video/*`. На обох платформах перевіряємо розмір та тривалість до завантаження.Обов'язкове транскодування
Відео з камери сучасного смартфона в 4K/60fps — 400 МБ на хвилину. Для посту в 60 секунд це 400 МБ. Транскодуємо до завантаження. Налаштування квантування та GOP структури дозволяє балансувати якість та розмір файлу. Використання кодека H.264 з профілем High забезпечує сумісність. Процес транскодування включає декодування, ресемплінг, квантування та ентропійне кодування.
Цільові параметри для постів: 1080p, H.264, 4–6 Мбіт/с, AAC 128 кбіт/с. Це дає ~35–45 МБ для 60-секундного кліпу — розумний компроміс між якістю та розміром. Транскодування на пристрої займає 20–30 секунд, що в 2–3 рази швидше, ніж завантаження вихідного відео на сервер і зворотна обробка.
На iOS — AVAssetExportSession з AVAssetExportPreset1920x1080:
let export = AVAssetExportSession(asset: asset, presetName: AVAssetExportPreset1920x1080)! export.outputURL = tempOutputURL export.outputFileType = .mp4 export.exportAsynchronously { // completion } Прогрес транскодування через export.progress опитуємо по таймеру — у AVAssetExportSession немає делегата для прогресу, тільки polling. На iPhone SE 2nd gen транскодування 60-секундного відео — 20–30 секунд. Потрібен явний прогрес-індикатор, інакше користувач вирішить, що додаток завис.
Процес транскодування:
- Отримати вихідний
AVAsset. - Задати вихідні параметри (пресет, кодек, контейнер).
- Запустити асинхронний експорт.
- Відстежувати прогрес через polling.
- По завершенні обробити помилки або використати готовий файл.
На Android — FFmpegKit для гнучкого транскодування або MediaTranscoder (Natario1) — більш сучасна бібліотека на MediaCodec без FFmpeg. MediaTranscoder важить ~500 КБ проти ~15 МБ у FFmpegKit — різниця в 30 разів, важлива для розміру APK.
Як реалізувати завантаження з відновленням?
Відео для посту — великий файл, upload має підтримувати відновлення. Використовуємо S3 Multipart Upload: файл ділимо на частини по 5–10 МБ, кожну завантажуємо паралельно (2–3 паралельні запити прискорюють upload без перевантаження мережі).
- Розділення файлу на частини фіксованого розміру.
- Паралельне завантаження частин з контролем помилок.
- Збірка файлу на сервері.
На iOS — URLSession з BackgroundConfiguration для продовження upload при згортанні. Completion handler через application(_:handleEventsForBackgroundURLSession:) в AppDelegate.
На Android — WorkManager з UploadWorker і setConstraints(Constraints.Builder().setRequiredNetworkType(CONNECTED).build()). WorkManager гарантує виконання навіть після перезапуску пристрою — якщо користувач вийшов з додатка в середині завантаження, при наступному запуску upload продовжиться.
Як оптимізувати відео прев'ю та плеєр для стрічки?
Відео прев'ю (знімок) генеруємо до початку upload — з оригінального відео через AVAssetImageGenerator (iOS) або MediaMetadataRetriever (Android), кадр на 1-й секунді. Завантажуємо прев'ю окремо, швидко — користувач бачить пост у стрічці з прев'ю, поки відео ще обробляється.
Плеєр у стрічці — автозапуск при появі у viewport. Не використовувати AVPlayer для кожної комірки стрічки — один shared AVPlayer, який переназначається при скролі (AVQueuePlayer для попереднього завантаження наступного). На Android — ExoPlayer з ExoPlayer.Builder().setLoadControl(DefaultLoadControl()) і PlayerView в RecyclerView. Попередньо завантажуємо наступне відео при скролі через MediaSource в ConcatenatingMediaSource.
Mute за замовчуванням — стандарт для автозапуску в стрічці. Звук вмикається тапом.
Порівняння підходів на iOS і Android
| Компонент | iOS | Android |
|---|---|---|
| Вибір відео | PHPickerViewController | ActivityResultContracts.GetContent() |
| Транскодування | AVAssetExportSession | MediaTranscoder (500 КБ) vs FFmpegKit (15 МБ) |
| Upload з відновленням | URLSession BackgroundConfiguration | WorkManager |
| Плеєр у стрічці | AVQueuePlayer | ExoPlayer |
| Генерація прев'ю | AVAssetImageGenerator | MediaMetadataRetriever |
Строки та що входить в роботу
| Етап | Строк | Примітка |
|---|---|---|
| Вибір + обрізка + транскодування + upload + прев'ю + плеєр | 3–5 днів | При готовому бекенді та API |
| Додатково: кастомний тример, background upload, оптимістичний UI | +2–3 дні |
Відмітимо: що входить: аналіз вимог, проектування архітектури, реалізація з код-рев'ю, документація по збірці та деплою, інструкція для користувачів, підтримка протягом місяця після релізу. Вартість розробки такого функціоналу зазвичай становить від $6,000 до $12,000 залежно від платформ та складності. Замовте розробку і переконайтеся в якості нашого підходу.
Якщо вам потрібно реалізувати відеопости в додатку, напишіть нам — ми допоможемо. Отримайте консультацію з інтеграції відеопостів у ваш додаток.







