Розробка платформи для стрімінгу прямих трансляцій

Архітектура платформи для прямих трансляцій

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Розробка платформи для стрімінгу прямих трансляцій
Складний
від 2 тижнів до 3 місяців

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1418
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1242
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    997

Архітектура платформи для прямих трансляцій

Ми часто стикаємося із завданням: компанія хоче запустити свій стрімінг-сервіс, схожий на Twitch, але з власними правилами монетизації та контенту. Типова проблема — затримка зростає при піку до 10 секунд, якість падає, а інфраструктура не витримує навантаження. За 5+ років ми розробили понад 15 streaming-проєктів, від невеликих educational-платформ до великих media. Розберемо, як побудувати надійну live-систему з нуля з урахуванням вимог до затримки, сумісності з пристроями та масштабування до тисяч глядачів. В основі вибору протоколів лежать такі критерії, як затримка, підтримка CDN та сумісність із браузерами.

Схема доставки та протоколи

Стрімер → Ingest → Transcoding → CDN → Viewer

Вхідний потік від стрімера — зазвичай RTMP (OBS, StreamLabs, XSplit всі вміють RTMP із коробки). На виході до глядача — HLS або DASH для браузера, WebRTC для ultra-low-latency (< 1 сек).

RTMP забезпечує низьку затримку на етапі прийому, але не підходить для доставки через блокування фаєрволами. HLS — стандарт де-факто, працює через HTTP і легко кешується на CDN.

OBS/FFMPEG → RTMP → Nginx-RTMP/SRS/Wowza → FFmpeg transcoding ↓ HLS segments → S3/CDN WebRTC → Selective Forwarding Unit 

Чому SRS кращий за інші ingest-сервери?

SRS (Simple Realtime Server) — опенсорс, Go, чудово тримає навантаження до 10K+ підключень на одному сервері. У наших проєктах SRS показав продуктивність на 30% вищу, ніж Wowza, при ідентичній конфігурації. Налаштування через один конфіг:

# srs.conf listen 1935; max_connections 1000; daemon off; http_server { enabled on; listen 8080; dir ./objs/nginx/html; } vhost __defaultVhost__ { # Хук: повідомляємо backend про початок/кінець трансляції http_hooks { enabled on; on_publish http://api:8000/hooks/stream/start; on_unpublish http://api:8000/hooks/stream/stop; on_play http://api:8000/hooks/stream/view; } hls { enabled on; hls_path ./objs/nginx/html; hls_fragment 2; # 2 секунди — баланс затримки та стабільності hls_window 10; # 10 сегментів у вікні } transcode { enabled on; ffmpeg /usr/local/bin/ffmpeg; engine hd { enabled on; vcodec libx264; vbitrate 2000; vfps 30; vwidth 1280; vheight 720; acodec aac; abitrate 128; output rtmp://localhost:1935/[app]/[stream]_720p; } engine sd { enabled on; vcodec libx264; vbitrate 800; vfps 30; vwidth 854; vheight 480; acodec aac; abitrate 96; output rtmp://localhost:1935/[app]/[stream]_480p; } } } 

Аутентифікація стрімера

Стрімер публікує потік за stream key. Не можна приймати RTMP від невідомих джерел:

# FastAPI: хук для SRS on_publish from fastapi import FastAPI, HTTPException from pydantic import BaseModel class PublishHook(BaseModel): action: str app: str stream: str # stream key від стрімера param: str # query string @app.post("/hooks/stream/start") async def on_stream_start(hook: PublishHook): # Валідуємо stream key streamer = await db.fetchrow( "SELECT id, user_id, is_active FROM stream_keys WHERE key = $1", hook.stream ) if not streamer or not streamer['is_active']: raise HTTPException(status_code=403, detail="Invalid stream key") # Запускаємо трансляцію в БД await db.execute(""" INSERT INTO live_streams (user_id, stream_key_id, started_at, status) VALUES ($1, $2, NOW(), 'live') ON CONFLICT (stream_key_id) DO UPDATE SET started_at = NOW(), status = 'live' """, streamer['user_id'], streamer['id']) # Повідомляємо підписників через WebSocket await notify_followers(streamer['user_id'], 'stream_started') return {"code": 0} # SRS очікує code=0 для дозволу 
Як оптимізувати завантаження HLS-сегментів у S3?

Моніторимо директорію із сегментами через cron або системний таймер. Для .m3u8 файлів встановлюємо Cache-Control: max-age=2, для .ts — max-age=86400, immutable. Використовуємо aws s3 cp з правильними заголовками.

Як працює чат у реальному часі?

Чат трансляції — обов'язковий елемент. WebSocket через Redis Pub/Sub з rate limiting та зберіганням ковзного вікна повідомлень:

// Node.js: WebSocket-сервер для чату import { WebSocketServer } from 'ws'; import { createClient } from 'redis'; const wss = new WebSocketServer({ port: 3001 }); const redis = createClient({ url: process.env.REDIS_URL }); const redisSub = redis.duplicate(); await redis.connect(); await redisSub.connect(); interface ChatMessage { type: 'message' | 'emote' | 'sub' | 'ban'; streamId: string; userId: string; username: string; text: string; badges: string[]; timestamp: number; } // Підписуємося на канал трансляції wss.on('connection', (ws, req) => { const streamId = new URL(req.url!, 'ws://x').searchParams.get('stream'); if (!streamId) return ws.close(); const channel = `chat:${streamId}`; // Слухаємо Redis Pub/Sub для цього стріму redisSub.subscribe(channel, (message) => { if (ws.readyState === ws.OPEN) { ws.send(message); } }); ws.on('message', async (data) => { const msg: ChatMessage = JSON.parse(data.toString()); // Антиспам: rate limit на користувача const key = `chat_limit:${msg.userId}:${streamId}`; const count = await redis.incr(key); if (count === 1) await redis.expire(key, 5); if (count > 20) { // 20 повідомлень за 5 секунд — забагато ws.send(JSON.stringify({ type: 'slowmode', waitMs: 5000 })); return; } // Зберігаємо в Redis Stream (ковзне вікно 1000 повідомлень) await redis.xAdd(`stream_chat:${streamId}`, '*', msg as any, { TRIM: { strategy: 'MAXLEN', threshold: 1000 } }); // Публікуємо всім підключеним await redis.publish(channel, JSON.stringify(msg)); }); ws.on('close', () => { redisSub.unsubscribe(channel); }); }); 

Запис трансляцій у VOD

Після закінчення стріму склеюємо TS-сегменти та перекодовуємо з faststart для псевдострімінгу. Офіційна документація FFmpeg рекомендує використовувати прапорець -movflags +faststart для переміщення атома moov на початок файлу, що прискорює початок відтворення.

# Celery task: конвертація в VOD @app.task def process_vod(stream_id: int): stream = LiveStream.objects.get(id=stream_id) segments = sorted( glob(f"/var/srs/hls/{stream.stream_key}/*.ts"), key=lambda f: int(Path(f).stem.split('_')[-1]) ) concat_list = "/tmp/vod_concat.txt" with open(concat_list, 'w') as f: for s in segments: f.write(f"file '{s}'\n") raw_mp4 = f"/tmp/vod_{stream_id}_raw.mp4" subprocess.run([ 'ffmpeg', '-f', 'concat', '-safe', '0', '-i', concat_list, '-c', 'copy', raw_mp4 ], check=True) vod_mp4 = f"/var/vod/{stream_id}.mp4" subprocess.run([ 'ffmpeg', '-i', raw_mp4, '-c:v', 'libx264', '-preset', 'fast', '-crf', '23', '-c:a', 'aac', '-b:a', '128k', '-movflags', '+faststart', vod_mp4 ], check=True) stream.vod_path = vod_mp4 stream.status = 'ended' stream.save() 

Як налаштувати транскодинг у кілька якостей: покрокова інструкція

  1. Встановіть SRS та FFmpeg на сервер.
  2. У конфігу SRS увімкніть секцію transcode та вкажіть шляхи до FFmpeg.
  3. Визначте профілі транскодингу (наприклад, HD: 720p, 30fps, 2 Mbps; SD: 480p, 30fps, 800 Kbps).
  4. Вкажіть у вихідних URL [stream]_720p та [stream]_480p, щоб SRS автоматично додавав суфікс.
  5. Перевірте, що HLS-сегменти створюються для кожного профілю в окремих піддиректоріях.
  6. Протестуйте з OBS, надсилаючи потік на RTMP ingest. Переконайтеся, що плеєр може перемикатися між quality levels.

Порівняння протоколів доставки

Протокол Затримка Сумісність Кешування CDN Використання
RTMP < 1 сек Flash/старі плеєри Ні Ingest
HLS 2-30 сек HTML5, iOS, Android Так Доставка
DASH 2-10 сек HTML5, SmartTV Так Доставка
WebRTC < 500 мс Браузери, P2P Ні Інтерактив

Порівняння популярних CDN для HLS-доставки

CDN Кешування HLS Origin Shield GeoDNS Ціна за TB (орієнтовно)
Cloudflare Так Так Так $0.036
AWS CloudFront Так Так Так $0.085
Fastly Так Так Так $0.10
Akamai Так Так Так >$0.15

Що входить у розробку платформи під ключ

  • Архітектурне проектування: вибір протоколів, CDN, capacity planning.
  • Ingest-сервер: налаштування SRS/Nginx-RTMP, транскодинг у кілька якостей.
  • Бекенд: API для керування стрімами, аутентифікація, монетизація.
  • Фронтенд: кастомізований плеєр, дашборд стрімера, чат.
  • Інфраструктура: Docker-контейнеризація, автоскейлінг, моніторинг.
  • Документація: повна технічна документація, інструкції для адміністраторів.
  • Навчання: сесія для команди, підтримка 2 тижні після запуску.
  • Гарантія: виправляємо баги протягом місяця безкоштовно.

Масштабування: багатосерверний ingest

Один ingest-сервер — SPOF. Для продакшну потрібен кластер з балансуванням:

DNS → Load Balancer (GeoDNS) → Ingest cluster ↓ Transcoding workers (GPU) ↓ HLS → S3 → CDN 

Стрімери направляються на найближчий ingest за GeoDNS. Кожен ingest пише в загальне об'єктне сховище або реплікує сегменти синхронно. Зв'яжіться з нами для обговорення архітектури вашого проєкту — ми підберемо оптимальну конфігурацію.

Строки

MVP із RTMP-прийомом, HLS-доставкою, WebSocket-чатом та записом у VOD — 10–12 тижнів. Додавання транскодингу кількох якостей, gift-subscriptions, модерації чату, мобільного плеєра — ще 8–10 тижнів. Масштабування до 10k+ concurrent viewers, балансування ingest, CDN з origin shield — окремий етап.

Хочете запустити свій стрімінг-сервіс? Отримайте консультацію — оцінимо ваш проєкт за 2 дні. Пишіть.