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

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

Разработка и обслуживание любых видов сайтов:

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

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

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

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

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    982
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1241
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    994

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

Мы часто сталкиваемся с задачей: компания хочет запустить свой стриминг-сервис, похожий на 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 дня. Пишите.