Стриминг видеозвонков по RTMP
Сегодня стриминг-платформы на пике популярности, так как миллионы талантливых людей регулярно делятся своими знаниями — читай, используют стриминг на всю катушку. Так как этот рынок растет, то существует и масса приложений, которые могут стримить видео в реальном времени, используя камеру смартфона или ноутбука. Возможно, вы тоже хотите внедрить в ваше приложение такую функциональность; если так, то спешим обрадовать — теперь Voximplant позволяет прокидывать видеозвонки по RTMP в любой CDN, который поддерживает этот протокол.
Эта функциональность стала возможна благодаря новому модулю Voxengine — StreamingAgent. Под катом вас ждут 5 шагов по настройке этой интеграции, добро пожаловать!
Схема
Видеозвонок из мобильного/веб-приложения или SIP приходит в наше облако, которое направляет его в стриминговый CDN. В свою очередь, CDN отправляет аудио- и видеопотоки конечным пользователям — как он обычно и делает. Обратите внимание, что RTMP поддерживает только H.264, поэтому очень важно явно указывать этот кодек при стриминге.
Вам понадобятся
- аккаунт на стриминговом сервисе, например, Twitch или Youtube;
- аккаунт Voximplant. Если у вас его нет, то регистрация живет здесь;
- приложение Voximplant, а также сценарий, правило и один пользователь. Все это мы создадим в этом туториале;
- веб-клиент для захвата видео и аудио — воспользуемся нашей демкой videochat
1. Настройки стриминга
Первым делом вам нужно будет получить значения двух параметров, который мы используем в облачном сценарии — stream name/key и server URL. Ниже показано, как получить эти значения на примере Twitch и YouTube.
Twitch
Зайдите в аккаунт, нажмите на аватарку в правом верхнем углу и выберите Video Producer.
В разделе Settings выберите Channel, а затем нажмите Copy в верху страницы — так вы получите ваш Primary Stream Key. Обратите внимание, что ключ доступен только при активированной двухфакторной аутентификации. Вставьте это значение в ваш текстовый редактор или просто оставьте эту страницу открытой, чтобы скопипастить значение позже.
Чтобы найти server url, зайдите на страницу stream.twitch.tv/ingests, выберите один из рекомендованных серверов и скопируйте его без последнего слэша, например: rtmp://live-sfo.twitch.tv/app
YouTube
Войдите в аккаунт, нажмите на аватарку в правом верхнем углу и выберите YouTube Studio (beta).
Если у вас нет канала на YouTube, то появится диалог о создании канала. Нажмите Create channel и вы увидите дашборд созданного канала с уведомлением, что стриминг будет возможен в течение 24 часов.
Находясь в YouTube Studio, через меню слева зайдите в Other features —> Live stream now. Откроется новая страница, внизу которого будет блок Encoder setup. Отсюда необходимо взять значения Server URL и Stream name/key (либо оставить страницу открытой).
2. Настройки VOXIMPLANT
Теперь надо сделать настройки со стороны Voximplant. Сначала войдите в свой аккаунт: https://manage.voximplant.com/auth. В меню слева нажмите «Приложения», затем «Новое приложение» и создайте приложение с именем streaming. Зайдите в новое приложение, переключитесь на вкладку «Сценарии», чтобы создать сценарий startStream с таким кодом (не забудьте подставить значения из предыдущего шага в строках 8 и 9):
require(Modules.StreamingAgent);
VoxEngine.setVideoCodec("H264");
VoxEngine.addEventListener(AppEvents.CallAlerting, function (e) {
const streaming = VoxImplant.createStreamingAgent({
protocol: "RTMP",
url: "rtmp://live-sfo.twitch.tv/app",
streamName: "live_********************",
keyframeInterval: 4
});
e.call.sendMediaTo(streaming);
streaming.addEventListener(StreamingAgentEvents.Connected, function (e) {
Logger.write("LOG: StreamingAgentEvents.Connected: " + e.reason);
});
streaming.addEventListener(StreamingAgentEvents.Disconnected, function (e) {
Logger.write("LOG: StreamingAgentEvents.Disconnected: " + e.reason);
});
streaming.addEventListener(StreamingAgentEvents.ConnectionFailed, function (e) {
Logger.write("LOG: StreamingAgentEvents.ConnectionFailed: " + e.reason);
});
streaming.addEventListener(StreamingAgentEvents.Error, function (e) {
Logger.write("LOG: StreamingAgentEvents.Error: " + e.reason);
});
streaming.addEventListener(StreamingAgentEvents.StreamStarted, function (e) {
Logger.write("LOG: StreamingAgentEvents.StreamStarted: " + e.reason);
});
streaming.addEventListener(StreamingAgentEvents.StreamError, function (e) {
Logger.write("LOG: StreamingAgentEvents.StreamError: " + e.reason);
});
streaming.addEventListener(StreamingAgentEvents.StreamStopped, function (e) {
Logger.write("LOG: StreamingAgentEvents.StreamStopped: " + e.reason);
});
e.call.answer();
e.call.addEventListener(CallEvents.Disconnected, function (e) {
Logger.write("LOG: terminating in 6 secs");
setTimeout(VoxEngine.terminate, 6000);
});
});
Это простой сценарий, который инициирует стрим, а также отслеживает все его возможные состояния, как то: Connected, Connection failed, StreamStarted и т.д. — подробности работы сценарии будут чуть ниже. Сейчас же вам надо перейти на вкладку «Роутинг» вашего приложения и нажать «Новое правило». Назовите его streamRule, укажите сценарий startStream и оставьте маску по умолчанию (.*).
Последнее, что надо сделать на этом этапе — создать пользователя. Перейдите на вкладку «Пользователи», нажмите «Создать пользователя», укажите имя (например, user1) и пароль, затем кликните «Создать». Эта пара логин-пароль понадобятся нам для аутентификации в веб-клиенте.
Конфигурация Voximplant закончена, но прежде чем мы перейдем к веб-клиенту, предлагаю разобраться, как работает модуль StreamingAgent в нашем сценарии.
3. Сценарий
Модуль StreamingAgent позволяет разработчикам запускать стримы по RTMP на популярные стиминговые платформы. Чтобы использовать функциональность модуля, мы должны подключить его в самом начале сценария:
require(Modules.StreamingAgent);
Далее необходимо явным образом указать кодек, который будет использоваться при стриминге. Так как многие платформы (Twitch и YouTube в том числе) используют RTMP, который, в свою очередь, поддерживает H.264, именно его мы и укажем:
VoxEngine.setVideoCodec("H264");
Если кодек не указан, то может быть вызвано событие StreamingAgentEvents.StreamError, содержащее текст об ошибке:
"Video codec mismatch. " + codecName + " granted, but should be H.264"
Затем мы добавляем обработчик для события CallAlerting, чтобы обработать видеозвонок из веб-клиента (да-да, скоро мы до него дойдем). Первым делом мы добавим в обработчик вызов метода createStreamingAgent. У метода есть следующие параметры, большинство из них — обязательные, опциональные отмечены отдельно:
- protocol — пока поддерживается только RTMP;
- url — server URL, см. шаг 1;
- streamName — stream name/key, см. шаг 1;
- applicationName (опциональный) — часть streamName, например, live2. Используйте этот параметр, если этого требует выбранная платформа;
- keyframeInterval (опциональный, секунды) — как часто будет создаваться ключевой кадр в стриме. Если не указан, то по умолчанию стоит значение 2.
Выше, в листинге сценария, вызов метода createStreamingAgent выглядит так:
VoxEngine.addEventListener(AppEvents.CallAlerting, function (e) {
const streaming = VoxImplant.createStreamingAgent({
protocol: "RTMP",
url: "rtmp://live-sfo.twitch.tv/app",
streamName: "live_********************",
keyframeInterval: 4
});
Но мы можем опустить keyframeInterval и использовать applicationName, вот так:
VoxEngine.addEventListener(AppEvents.CallAlerting, function (e) {
const streaming = VoxImplant.createStreamingAgent({
protocol: "RTMP",
url: "rtmp://a.rtmp.youtube.com/",
applicationName: "live2",
streamName: "somename"
});
После того как создан объект стриминга, сценарий продолжает обрабатывать звонок внутри обработчика. Следующий шаг — направить входящий видеопоток из веб-клиента в созданный объект стриминга:
e.call.sendMediaTo(streaming);
Затем мы используем все возможные стриминговые события для отладки: обработчики ничего не делают, кроме отправки сведений в лог Voximplant-сессии. Вы можете не использовать этот кусок кода, если хотите.
После обработки событий сценарий отвечает на входящий звонок:
e.call.answer();
Наконец, мы должны корректно обработать окончание стриминга, когда веб-клиент прекращает отправку видео. Формально, мы можем не использовать и этот обработчик тоже, но при этом сессия закончится только по спустя 60 секунд после прекращения отправки видео. В этом ожидании нет смысла, поэтому лучше завершать сессию, отталкиваясь от событий Disconnected:
e.call.addEventListener(CallEvents.Disconnected, function (e) {
Logger.write("LOG: terminating in 6 secs");
setTimeout(VoxEngine.terminate, 6000);
});
Понимая логику сценария, мы готовы приступить к последней –, но не по значению — части нашей конфигурации.
4. Веб-клиент
Клонируйте или скачайте наше демо videochat. Затем перейдите в папку репозитория и откройте файл WebApp/JS/app.js в текстовом редакторе/IDE. Измените имя приложения на 5 строке и сохраните файл:
Собственно, всё.
5. Запускаем стриминг
Вам нужно запустить папку WebApp локально или на вашем веб-сервере. Для локального запуска можете воспользоваться утилитой live-server или приложением Web Server for Chrome. При запуске веб-клиента вы должны передать ему имя вашего аккаунта Voximplant, например:
http://127.0.0.1:8080/index.html#accname=johngalt
Запустив клиент, введите пару логин-пароль из пункта 2:
Введите любый набор символов рядом со знаком @ и нажмите Call. Если все было сделано правильно, скоро начнется ваш стрим :) Успешных вам стримов и продуктивной разработки!