Адаптивний HLS-стрімінг: як це працює і чому вигідно
HLS стрімінг (HTTP Live Streaming) — протокол Apple HLS, що став де-факто стандартом у вебі. Пряма віддача MP4 через HTTP ламається на довгих відео, слабких з'єднаннях і мобільних пристроях. Користувач чекає завантаження, буферизація на кожному перепаді швидкості вбиває Retention, а CDN-трафік зростає даремно. Ми реалізуємо HLS — відео нарізається на сегменти по 2–6 секунд, плеєр автоматично вибирає якість під поточну пропускну здатність. Результат: миттєвий старт, жодних фризів, економія трафіку до 40 %. HLS краще MP4 у 3-5 разів за навантаженням на сервер.
Наш досвід — 7+ років у відео-стрімінгу, 35+ реалізованих проєктів з HLS. Компанія на ринку з 2018 року. Ми гарантуємо стабільну роботу на будь-яких пристроях: від старих Android до останніх iPhone та Smart TV.
Чому HLS кращий за пряму віддачу MP4? У 3-5 разів менше навантаження на сервер
MP4 з прогресивним завантаженням (byte-range requests) працює тільки для коротких роликів. При перемиканні на іншу якість потрібно або завантажувати другий файл паралельно, або терпіти буферизацію. HLS вирішує це архітектурно: плейлист (.m3u8) містить посилання на сегменти різних бітрейтів, плеєр перемикається між ними на межі сегментів — жодного розриву відтворення.
Apple Developer Documentation зазначає: HTTP Live Streaming розбиває відео на невеликі HTTP-завантаження.
Порівняємо HLS та MP4:
| Характеристика | HLS | MP4 з прогресивним завантаженням |
|---|---|---|
| Старт на повільному з'єднанні | Миттєвий (через 2-6 сек) | Вимагає буферизації 10+ сек |
| Перемикання якості | Без розриву, на межі сегментів | Неможливо без перезавантаження |
| Кешування CDN | Ефективно (незалежні сегменти) | Погано (великі файли, partial content) |
| Підтримка браузерами | Нативна в Safari, HLS.js для інших | Нативна, але без адаптивності |
| Навантаження на origin | Низьке (маленькі файли легко кешуються) | Високе (запити range) |
Як вибрати оптимальні профілі якості?
Профілі підбираються за двома критеріями: цільова аудиторія та тип контенту. Ми використовуємо таку таблицю як базу:
| Профіль | Роздільна здатність | Бітрейт | CRF | Preset | Цільове з'єднання |
|---|---|---|---|---|---|
| 360p | 640x360 | 600 Kbps | 28 | fast | 3G / Edge |
| 720p | 1280x720 | 2500 Kbps | 23 | fast | LTE / 4G |
| 1080p | 1920x1080 | 5000 Kbps | 22 | medium | Wi-Fi / 5G |
Для екшн-сцен або спортивних трансляцій бітрейти підвищують на 30–50 %, для статичних презентацій — знижують. Ми оцінюємо проєкт і підбираємо профілі індивідуально.
Генерація HLS через FFmpeg (кілька якостей одним проходом) для VOD-стрімінгу
Одним викликом FFmpeg генеруємо всі профілі — це ефективніше по CPU, ніж запускати окремі процеси. Використовуємо H.264 High Profile з B-frames (2-3), CABAC entropy coding, та GOP size 2-4 секунди для кращої ключової точки. Налаштовуємо keyframe alignment між профілями для безшовного перемикання якості (Seamless Switching). Для ABR використовуємо алгоритм HLS.js з бендвісним оцінюванням (Bandwidth Estimate) на основі експоненційного ковзного середнього (EWMA).
ffmpeg -i input.mp4 \
-map 0:v:0 -map 0:a:0 \
-map 0:v:0 -map 0:a:0 \
-map 0:v:0 -map 0:a:0 \
\
-c:v:0 libx264 -crf 28 -preset fast \
-vf:v:0 "scale=640:360:force_original_aspect_ratio=decrease,pad=640:360:(ow-iw)/2:(oh-ih)/2:black" \
-b:v:0 600k -maxrate:v:0 800k \
-c:a:0 aac -b:a:0 96k \
\
-c:v:1 libx264 -crf 23 -preset fast \
-vf:v:1 "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2:black" \
-b:v:1 2500k -maxrate:v:1 3000k \
-c:a:1 aac -b:a:1 128k \
\
-c:v:2 libx264 -crf 22 -preset medium \
-vf:v:2 "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black" \
-b:v:2 5000k -maxrate:v:2 6000k \
-c:a:2 aac -b:a:2 192k \
\
-hls_time 4 -hls_list_size 0 -hls_flags independent_segments \
-hls_segment_filename "360p/seg%03d.ts" \
-var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" \
-master_pl_name master.m3u8 \
%v/index.m3u8
%v підставляє індекс потоку. -hls_flags independent_segments робить кожен сегмент незалежним ключовим кадром — плеєр може перемикати якість миттєво.
Що означають ключові параметри FFmpeg?
- `-map`: вибирає потоки для кожного варіанту. - `-c:v` і `-c:a`: кодеки відео (libx264 = H.264) та аудіо (aac). - `-crf`: якість відео (чим нижче, тим вища якість і більший бітрейт). - `-preset`: швидкість стиснення (fast/medium — баланс швидкості та розміру). - `-hls_time`: тривалість сегмента в секундах. - `-master_pl_name`: ім'я головного плейлиста.Що входить у роботу
Ми постачаємо:
- PHP-сервіс HLS з гнучкою конфігурацією профілів (клас
HlsServiceз підтримкою будь-якої кількості профілів); - Job-обробник для асинхронної генерації в черзі (Laravel Horizon, Redis);
- Nginx-конфігурацію з коректними MIME-типами, CORS та кешуванням;
- Плеєр на HLS.js з fallback для Safari/iOS;
- Документацію з розгортання та інтеграції;
- Підтримку протягом 30 днів після здачі.
Плеєр на фронтенді
HLS.js — основна бібліотека для браузерів без нативної підтримки (Chrome, Firefox, Edge). Код підключення:
<video id="video" controls preload="none"></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>
const video = document.getElementById('video');
const src = '/hls/1/master.m3u8';
if (Hls.isSupported()) {
const hls = new Hls({
maxBufferLength: 30,
startLevel: -1, // авто-вибір якості
abrEwmaDefaultEstimate: 1_000_000, // початкова смуга 1 Mbps
});
hls.loadSource(src);
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = src;
}
</script>
Зберігання сегментів (сегментація відео)
Для годинного відео в трьох якостях ~2000 файлів .ts. Локальний диск працює, але при масштабуванні переходимо на S3-сумісне сховище (MinIO, AWS S3). FFmpeg вміє писати напряму в S3 через s3:// URI за наявності libavformat з підтримкою S3. Альтернатива — генерувати локально, потім синхронізувати aws s3 sync.
Процес роботи та терміни
- Аналітика — вивчаємо вихідне відео, аудиторію, вимоги до буквелінту.
- Проектування — вибираємо профілі, кодек, параметри ABR (адаптивний бітрейт).
- Реалізація — налаштовуємо FFmpeg, пишемо PHP-сервіс, job, Nginx, плеєр.
- Тестування — перевіряємо на мобільних, десктопі, Smart TV; вимірюємо LCP та час до першого кадру.
- Деплой — викочуємо на продакшен з моніторингом помилок плеєра.
Орієнтовні терміни: 2–3 робочих дні на базову інтеграцію. Оцінимо ваш проєкт за 1 день — отримайте консультацію. Вартість робіт від 30 000 грн залежно від складності. Наприклад, для проєкту з 50 000 щоденних переглядів економія на CDN може сягати 15 000 грн на місяць.
Типові помилки та як їх уникнути
- Несумісність кодеків: використовуємо H.264 High Profile — підтримується всіма пристроями.
- Неправильні шляхи в плейлисті: перевіряємо відносні шляхи при генерації сегментів.
- Відсутність CORS: додаємо заголовок
Access-Control-Allow-Origin: *для плеєра на іншому домені. - Велика кількість файлів: налаштовуємо очищення старих сегментів (для live) або використовуємо S3 з TTL.
З HLS під ключ ваш контент працюватиме швидко та стабільно на будь-яких пристроях — замовте впровадження.







