[Перевод] Введение в работу с ORTC в Microsoft Edge
В октябре прошло года мы объявили о нашем намерении поддержать ORTC в Microsoft Edge с особым фокусом на аудио/видео-коммуникации. С тех пор мы много над этим работали и сегодня рады анонсировать, что превью-версия нашей реализации доступна в свежей сборке Edge в рамках программы Windows Insider.
Поддержка ORTC в Microsoft Edge является результатом сотрудничества между командами операционных систем (OSG) и Skype. Объединив вместе 20-летний опыт построения веб-платформы и 12-летний опыт создания одного из крупнейших сервисов коммуникации в реальном времени для обычных и бизнес-пользователей, мы поставили перед собой цель сделать возможным построение в браузере опыта общения не только с пользователями Skype, но и другими коммуникационными сервисами, совместимыми c WebRTC.
Смотря в будущее, мы надеемся увидеть множество решений от сообщества, которые станут возможными благодаря использованию ORTC. В свою очередь, мы хотим подробнее рассказать, что включает наша предварительная реализация ORTC, и показать на простом примере, как построить аудио- и видео-коммуникацию в 1:1 сценарии.
Что мы предоставляем
Диаграмма ниже является часть обзорного раздела спецификации ORTC API. Она дает верхнеуровневое описание взаимосвящей между различными объектами ORTC и полезная для иллюстрации взаимодействия отдельных участков кода: от захвата медиа-потоков (треков) до объектов RtpSender, и далее путь к объектам RtpReceiver, которые могут быть направлены в video/audio теги. Мы рекомендуем использовать данную диаграмму в качестве справочного пособия при начале изучения ORTC API.
Наша начальная реализация ORTC включает следующие компоненты:
- Поддержка ORTC API. Наш основной фокус сейчас – это аудио/видео-коммуникации. Мы реализовали поддержку следующих объектов: IceGatherer, IceTransport, DtlsTransport, RtpSender, RtpReceiver, а также интерфейсы RTCStats, которые напрямую не отображаются на диаграмме.
- Поддержка пультиплексирования RTP/RTCP (необходима в работе с DtlsTransport). Также поддерживается мультиплексирование аудио/видео.
- Поддержка STUN/TURN/ICE. Мы доддерживаем STUN (RFC 5389), TURN (RFC 5766) и ICE (RFC 5245). В рамках ICE поддерживает регулярная номинация, в то время, как агрессивный выбор поддерживается частично (для получателя). DTLS-SRTP (RFC 5764) поддерживается на базе DTLS 1.0 (RFC 4347).
- Поддержка кодеков. Из аудиокодеков мы реализовали поддержку G.711, G.722, Opus и SILK. Мы также поддерживаем Comfort Noise (CN) и DTMF в соответствии с аудио требованиями RTCWEB. Для видео мы пока поддерживаем только кодек H.264UC используемый сервисами Skype (включая такие возможности, как одновременное и масштабируемое кодирование видео и опережающая коррекция ошибок). В будущем мы планируем реализовать совместимую поддержку видео на базе H.264.
Хотя наша предварительная реализация все еще может содержать в себе баги, мы думаем, что ее уже можно использовать в типовых сценариях, и будем рады услышать отзывы от разработчиков, которые попробуют реализацию на практике.
Если вы знакомы с реализациями WebRTC 1.0 и заинтересованы узнать побольше об эволюции поддержки объектов в рамках WebRTC 1.0 и ORTC, рекумендуем познакомиться со следующей презентацией от Google, Microsoft и Hookflash с конференции IIT RTC 2014: “ORTC API Update.”
Как создать приложение для 1:1-взаимодействия
Теперь давайте обсудим, как от обзорной диаграммы ORTC перейти к реализации в коде простого сценария 1:1 аудио/видео-коммуникации. Для данного специфичного сценария вам понадобятся две машины с Windows 10, работающих в качестве двух клиентов (точек) взаимодействия, и веб-сервер, работающий как сигнализирующий канал для обмена информацией между этими точками, чтобы между ними можно было установить связь.
Шаги ниже относятся к операциями, осуществляемым одним из клиентов. Обе точки должны пройти через схожие шаги, чтобы установить 1:1-взаимодействие. Чтобы лучше прочувствовать примеры кода ниже, рекомендуем в качестве образца реализации использовать наш пример на Microsoft Edge Test Drive.
Шаг #1. Создание объекта MediaStream (например, через Media Capture API) с одним аудио-треком и одним видео-треком.
navigator.MediaDevices.getUserMedia ({
"audio": true,
"video": {
width: 640,
height: 360,
facingMode: "user"
}
}).then(
gotStream
).catch(
gotMediaError
);
function gotStream(stream) {
var mediaStreamLocal = stream;
…
}
Подробнее о работе с Media Capture API можно прочитать в нашей статье с анонсом поддержки захвата медиа-сигналов в Microsoft Edge.
Шаг #2. Создать ICE-сборщик, и разрешить локальным кандидатам на установку взаимодействия по ICE-протоколу сообщать о себе удаленным точкам.
var iceOptions = new RTCIceGatherOptions;
iceOptions.gatherPolicy = "all";
iceOptions.iceservers = ... ;
var iceGathr = new RTCIceGatherer(iceOptions);
iceGathr.onlocalcandidate = function(evt) {
mySignaller.signalMessage({
"candidate": evt.candidate
});
};
Чтобы помочь защитить приватность пользователей, мы добавили опцию, позволяющую пользователю контролировать, можно ли IP-адрес локального хоста передавать объектам IceGatherer. Соответствующий интерфейс настройки можно найти в настройках браузера Microsoft Edge.
В нашем примере на Test Drive мы развернули TURN-сервер. У него ограниченная пропускная способность, поэтому мы ограничили его только нашей демонстрационной страницей.
Шаг #3. Создать ICE-транспорт для аудио и видео и подготовиться к обработке удаленных ICE-кандидатов в ICE-транспорте
var iceTr = new RTCIceTransport();
mySignaller.onRemoteCandidate = function(remote) {
iceTr.addRemoteCandidate(remote.candidate);
}
Другой вариант – это собрать всех удаленных ICE-кандидатов в массив remoteCandidates и вызвать функцию iceTr.setRemoteCandidates(remoteCandidates, чтобы сразу добавить всех удаленных кандидатов.
Шаг #4. Создать DTLS-транспорт
var dtlsTr = new RTCDtlsTransport(iceTr);
Шаг #5. Создать объект отправителя и получателя
var audioTrack = mediaStreamLocal.getAudioTracks()[0];
var videoTrack = mediaStreamLocal.getVideoTracks()[0];
var audioSender = new RtpSender(audioTrack, dtlsTr);
var videoSender = new RtpSender(videoTrack, dtlsTr);
var audioReceiver = new RtpReceiver(dtlsTr, "audio");
var videoReceiver = new RtpReceiver(dtlsTr, "video");
Шаг #6. Запросить возможности отправителя и получателя
var recvAudioCaps = RTCRtpReceiver.getCapabilities("audio");
var recvVideoCaps = RTCRtpReceiver.getCapabilities("video");
var sendAudioCaps = RTCRtpSender.getCapabilities("audio");
var sendVideoCaps = RTCRtpSender.getCapabilities("video");
Шаг #7. Обменяться ICE/DTLS-параметрами и возможностями на получение/отправку.
mySignaller.signalMessage({
"ice": iceGathr.getLocalParameters(),
"dtls": dtlsTr.getLocalParameters(),
"recvAudioCaps": recvAudioCaps,
"recvVideoCaps": recvVideoCaps,
"sendAudioCaps": sendAudioCaps,
"sendVideoCaps": sendVideoCaps
};
Шаг #8. Получить параметры удаленной точки, начать работу транспортов ICE и DTLS, установить параметры отправки и получения аудио/видео.
mySignaller.onRemoteParams = function(params) {
// The responder answers with its preferences, parameters and capabilities
// Derive the send and receive parameters.
var audioSendParams = myCapsToSendParams(sendAudioCaps, params.recvAudioCaps);
var videoSendParams = myCapsToSendParams(sendVideoCaps, params.recvVideoCaps);
var audioRecvParams = myCapsToRecvParams(recvAudioCaps, params.sendAudioCaps);
var videoRecvParams = myCapsToRecvParams(recvVideoCaps, params.sendVideoCaps);
iceTr.start(iceGathr, params.ice, RTCIceRole.controlling);
dtlsTr.start(params.dtls);
audioSender.send(audioSendParams);
videoSender.send(videoSendParams);
audioReceiver.receive(audioRecvParams);
videoReceiver.receive(videoRecvParams);
};
Ниже приведен набросок для вспомогательной функции:
RTCRtpParameters function myCapsToSendParams (RTCRtpCapabilities sendCaps, RTCRtpCapabilities remoteRecvCaps) {
// Function returning the sender RTCRtpParameters, based on intersection of the local sender and remote receiver capabilities.
// Steps to be followed:
// 1. Determine the RTP features that the receiver and sender have in common.
// 2. Determine the codecs that the sender and receiver have in common.
// 3. Within each common codec, determine the common formats and rtcpFeedback mechanisms.
// 4. Determine the payloadType to be used, based on the receiver preferredPayloadType.
// 5. Set RTCRtcpParameters such as mux to their default values.
}
RTCRtpParameters function myCapsToRecvParams(RTCRtpCapabilities recvCaps, RTCRtpCapabilities remoteSendCaps) {
return myCapsToSendParams(remoteSendCaps, recvCaps);
}
Шаг #9. Отобразить и начать проигрывание удаленных медиа-потоков через video-тег
var videoRenderer = document.getElementById("myRtcVideoTag");
var mediaStreamRemote = new MediaStream();
mediaStreamRemote.addTrack(audioReceiver.track);
mediaStreamRemote.addTrack(videoReceiver.track);
videoRenderer.srcObject = mediaStreamRemote;
videoRenderer.play();
В целом, это основные шаги при написании года. Как мы сказали, наш пример работы с ORTC включает дополнительно показ видео-превью, обработку сообщений об ошибках и др.
Как только вы разберетесь с настройкой 1:1-звонков, вам будет достаточно очевидно, как сделать групповой сеанс, используя топологию сетки, в которой каждая точка имеет 1:1-связь с остальной группой. Так как параллельное дублирование в нашей реализации не работает, вам нужно будет использовать 1:1-сигналы, так что независимые объекты IceGatherer и DtlsTransport будут использоваться для каждого соединения.
Дополнительные детали по реализации ORTC в Microsoft Edge
Мы обновляем нашу реализацию, чтобы соответствовать свежим обновлениям спецификации ORCT. В целом спецификация достаточно стабильна с момента выпуска «призыва к реализации» со стороны ORTC CG, поэтому мы не ожидаем значительных изменений на уровне JavaScript API. В связи с этим нам кажется, что наша реализация готова для того, чтобы начать тестирование кросс-браузерной совместимости на уровне протоколов.
Некоторые ограничения нашей реализации, которые мы должны обозначить:
- Мы не поддерживаем RTCIceTransportController. Наша реализация обрабатывает команды заморозки/разморозки в ICE на уровне каждого транспорта, поэтому возможность отдачи указаний всем IceTransports не является обязательной. Думаем, это должно быть совместимо с существующими реализациями.
- RtpListener еще не поддерживается. Это означает что SSRC необходимо указывать заранее в рамках RtpReceiver.
- Дублирование (создание форка) не поддерживается ни в IceTransport, ни в IceGatherer, ни в DtlsTransport. Решение по реализации дублирования в DtlsTransport все еще обсуждается в ORTC CG.
- Немультиплексорные RTP/RTCP не поддерживаются в DtlsTransport. При использовании DtlsTransport ваше приложение должно поддерживать мультиплексирование RTP/RTCP.
- В RTCRtpEncodingParameters в настоящий момент мы игнорируем большинство настроек качества. Однако мы требуем установки атрибутов ‘active’ и ‘ssrc’.
- Событие icecandidatepairchanged еще не поддерживается. Вы можете прлучить информацию о кандидате на установку связи через метод getNominatedCandidatePair.
- На сегодня мы не поддерживаем функциональности DataChannel, определяемой спецификацией ORTC.
Что дальше
Хотя наша реализация носит предварительный характер, мы будем рады услышать ваши отзывы. Они помогут нам реализовать полноценную поддержку ORTC в Microsoft Edge в ближайшие месяцы. Наша цель – сделать реализацию стандарта, совместимую с современным вебом и остальными решениями индустрии коммуникаций реального времени в будущем.
На пути к этой цели в ближайшем будущем команда Skype начнет использовать ORTC API в Microsoft Edge, чтобы создать полноценный опыт аудио/видео-коммуникации и взаимодействия в веб-клиентах Skype и Skype for Business. Команда также инвестирует в совместимость со стандартным WebRTC-протоколом, чтобы быть увереными, что Skype работает на ключевых десктопных, мобильных и браузерных платформах. Для разработчиков, которые хотят интегрировать Skype и Skype for Business в свои приложения, Skype Web SDK также будет обновлен с учетом возможности использования ORTC и WebRTC API. Дополнительная информация на эту тему доступна в заметке "Enabling Seamless Communication Experiences for the Web with Skype, Skype for Business, and Microsoft Edge".
Более того, несколько членов ORTC CG плотно работали с нами над ранней адаптацией технологии. Мы планируем продолжить совместную работу над эволюцией технологии WebRTC в сторону “WebRTC Next Version (NV).” Мы ожидаем, что первопроходцы в работе с ORTC скоро начнут делаться своим опытом.
Дополнительные примеры: Связка ORTC + WebRTC, Звонок между ORTC и Twilio.
– Shijun Sun, Principal Program Manager, Microsoft Edge
– Hao Yan, Principal Program Manager, Skype
– Bernard Aboba, Architect, Skype