webrtc nextversion時代のjavascript開発

Post on 06-Jan-2017

2.605 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

WebRTC NextVersion 時代の JavaScript開発

2016/2/17(Wed)@WebRTC Conference Japan 2016仲裕介( NTT コミュニケーションズ)

自己紹介名前:仲 裕介(なかゆうすけ /@Tukimikage )所属: NTT コミュニケーションズ エンジニア仕事: WebRTC プラットフォーム SkyWay の開発    Web 技術者向け情報メディア HTML5 Experts.jp 運営

プライベート: WebRTC Meetup Tokyo / Japan 主催者の一人http://webrtcjp.info/

今日お話すること 私達 WebRTC プラットフォーマーは、自社で提供する JavaScript ライブラリを常に完全動作させるために、ブラウザの API の実装状況や標準化動向に目を配っています。

今後注目すべき WebRTC API の変化について、今日はお話します。

会場への質問 WebRTC API の標準化動向や各ブラウザの実装状況をウォッチしていますか? 「お金出してるから( or お金出してないけど) WebRTC プラットフォーム使ってるから大丈夫!」と思ってませんか?

WebRTC プラットフォームサービス WebRTC のアプリ開発を行う上で今や無くてはならない存在

OpenToktokbox

IceLINKfrozen mountain

WebRTC プラットフォームサービス WebRTC のアプリ開発を行う上で今や無くてはならない存在

SkylinkTemasys

SkyWayNTT Communications

プラットフォーム利用のメリット WebRTC アプリ開発者がこれらプラットフォームを利用するメリットは?

クロスブラウザや iOS/Android をはじめとするクロスプラットフォームに対応している。 WebRTC に必要なサーバ API を提供してくれるため、開発者が専用サーバの運用を行わなくて良い。 複雑で更新頻度も高いネイティブ API を使いやすくラップし、ブラウザのアップデートにも勝手に追従してくれる。….etc

プラットフォーム利用のデメリット 逆に、 WebRTC アプリ開発者がこれらプラットフォームを利用するデメリットは?

WebRTC はブラウザのアップデートが早いため、昨日まで動いていた機能が今日動かない!とかザラにある。サービス復旧はプラットフォームの対応次第という事になりかねない。 クライアントの WebRTC 実装は SDK として隠蔽されているため、トラブルシューティング時のハードルが高い。 エンジニアの WebRTC 力の低下を招く。(つまり、生で WebRTCの実装ができなくなる)

….etc

WebRTC 力の低下が招くもの これ、じつはかなり恐ろしい状態・・・なぜか?

WebRTC は、ブラウザ同士の実装差分や、端末スペック、ネットワーク環境の違いなど様々な要因が動作に影響を与える。

開発環境ではバッチリ動くけど、お客様のところでは動かないなんてよくある話。おまけに最後まで原因がわからないことも多い。 ※ここで折れると「何だ WebRTC って使えないじゃん!」となる・・・・

そうならないために現場のエンジニアは、それら不測の事態に対処する必要が出てくる。生 WebRTC の実装を読み解く力(= WebRTC 力)が必要になる。

※ 解決策の1つではあるけど完全じゃない

ここまでのまとめ WebRTC のアプリ開発を行う場合、 WebRTC プラットフォームサービスを活用すると、かなり簡単に実装できる。 しかし、ビジネスユースで WebRTC のアプリ開発を行う場合は、お客様の環境で期待通りの動作をさせるためのチューニングや、万が一動かない場合のトラブルシューティングなどをきっちり対応する必要があり、技術力を要求される。 そのために、ブラウザの実装状況や最新の標準化動向なども忘れずにウォッチし WebRTC 力を維持しましょう。

ここから本題 皆さんの WebRTC 力を維持するために、今日は、今年かなりホットになるであろう話題にフォーカス

WebRTC 1.0 から WebRTC Next Version へのシフト(注: JavaScript にフォーカスします)

WebRTC NextVersion でAPI はどう変わる?

2016 年押えておくべきポイントは? WebRTC の JavaScript API は今大きく変わろうとしている

W3C の標準化の現場では、 WebRTC 1.0 の仕様 FIX に向けて様々な議論が行われている( 2016 1Q に勧告候補になるらしい) その先の WebRTC Next Version / NV (仮・この資料では次世代仕様を今後そう呼ぶ)についても既に議論が活発に行われている。

NV で API はどう変わる? W3C も支持を表明している Extensible Web という考え方に基づき、今後標準化の場では、ユースケースを限定しないローレベルな API が提唱されていく

Extensible Web で何が変わる? 課題

ブラウザベンダや W3C が API を提案しそれを標準化するという、今までの手法では、 Web 開発者にとって必ずしも使いやすい API にはならず、 Web 開発者が標準化の現場で置き去りになるという問題があった。また、 API の実装や標準化に時間がかかりすぎていたという面もあった。(事実 WebRTC1.0 は伸びに伸びている…) 解決策

Extensible Web では、 ブラウザベンダや W3C はユースケースをあまり限定しない、セキュアでローレベルな API を Web 開発者に提供することに注力する。Web 開発者は、自分たちが実現したいユースケースに沿って、それらの API を自由に組み合わせることが可能になる。また、その結果を標準化の場にフィードバックできる仕組みを用意する。

NV で API はどう変わる? WebRTC の世界では Extensible Web で具体的に何が起こるのか

WebRTC1.0 の世界(今までの世界) WebRTC1.0 では、 PeerConnectionオブジェクトが様々な機能を隠蔽しており、開発者はそのオブジェクトにメソッドを利用してアクセスすることで、 WebRTC の想定するユースケースを実現してきた。 →  WebRTC1.0 の想定するベーシックなユースケース                   = 1:1ビデオチャット

NV で API はどう変わる? WebRTC の世界では Extensible Web で具体的に何が起こるのか

WebRTC NV の世界(これからの世界) WebRTC を構成するよりローレベルな機能まで1つの Object として定義し、それぞれを直接叩くことが出来る JavaScript インターフェースを用意する。 具体的には、 WebRTC と並んで W3C の Community Group で議論されている、 ObjectRTC (以下、 ORTC )がそれに近い。 WebRTC 1.0 標準化勢は、 ORTC の設計思想にインスパイアされ、良い点を取り込もうとしている。しかしながら、既に仕様が成熟しつつある

WebRTC1.0 に、今更全てを取り込むわけにもいかないため、 WebRTC1.0 として実現する機能、その次の WebRTC NV として実現する機能の仕分けが今、行われている。 詳しくは1日目 Dr. Alex Gouaillard のセッションが役に立つに違いない

NV で API はどう変わる? ORTC の世界

各ブロックは全て JS から単独で操作可能な Object である。

引用元: http://ortc.org/wp-content/uploads/2015/11/ortc.html※WebRTC1.0 の世界ではこれがひとくくり

NV で API はどう変わる? WebRTC の世界では Extensible Web で具体的に何が起こるのか

Offer/Answerモデルからの開放(1) WebRTC 1.0 では、1:1での双方向コミュニケーションを前提にしていたため、 Offer/Answer というステートフルなモデルが用いられていた。 開発者は双方のステートを意識しつつ、アプリ開発を行う必要があり、実装が複雑になる一面もあった。

1. いくで! 2. はいよ!

3.返すで!4.ほいさ!

NV で API はどう変わる? WebRTC の世界で具体的に何が起こっているのか

Offer/Answerモデルからの開放(2) 現在は WebRTC の活用の場も広がり、必ずしも1:1ではない、必ずしも双方向ではないユースケースが登場している。そういったユースケースでは、

Offer/Answerモデルは逆に使いにくい。(例えば1:多で片方向の映像配信とか) WebRTC NV では、各オブジェクトに対する JavaScript からの操作は全て、ステートレスに行えるように API が設計されている。

NV で API はどう変わる? WebRTC の世界で具体的に何が起こっているのか

SDP から JSONへ WebRTC1.0 では、 Web アプリからブラウザに対して指示を出す際は、 SDP というテキストベースのプロトコルを利用するルールになっている。シグナリングで互いにメッセージを交換する場合も SDP のフォーマットで交換する。 先ほどの Offer/Answerモデルの採用は、 SDP がそのモデルを想定したプロトコルであることに起因している。 WebRTC NV では、 Web アプリとブラウザ間のデータのやり取りは JSONをベースとなり、 Web 開発者には親しみにやすい仕様になっている。ただし、既存の WebRTC1.0 と相互接続する場合は、 JSON→SDP→JSON の変換が必要となる。

WebRTC NV を利用した開発はどうなる?

WebRTC NV を利用した開発 WebRTC NV を利用した開発例

WebRTC NV はまだ仕様書もなく実装されているブラウザも存在しないが、一番近い実装としては、 ORTC とそれを実装した Microsoft Edge が相当する。今回は Edge に実装された ORTC のコードを解説する処理シーケンスを解説する。

Edge の ORTC 実装の制約 全ての API が仕様通りに実装されているわけではない STUN サーバの指定ができない

TURN サーバが必ず必要

H.264 や VP8 に対応していない Chrome-Edge/Firefox-Edge は音声のみ疎通可 Edge 同士であれば H.264UC で映像も疎通可

ICE は half trickle ICE を実装

Edge の ORTC シーケンスMediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

Edge の ORTC シーケンスMediaCaptur

eMediaCaptur

e

IceGatherer IceGatherer

ローカルの ICE 候補を収集するvar iceOptions = new RTCIceGatherOptions;iceOptions.gatherPolicy = "all";iceOptions.iceservers = ”turn.xxx.com";var iceGathr = new RTCIceGatherer(iceOptions);iceGathr.onlocalcandidate = function(evt) {

mySignaller.signalMessage({

"candidate": evt.candidate });

};

localStreamA

localStreamB

ローカルの ICE Candidate を収集するvar iceOptions = new RTCIceGatherOptions;iceOptions.gatherPolicy = "all";iceOptions.iceservers = ”turn.xxx.com";var iceGathr = new RTCIceGatherer(iceOptions);iceGather.onlocalcandidate = function(evt) {

mySignaller.signalMessage({ "candidate": evt.candidate });

};

Edge の ORTC シーケンスMediaCaptur

eMediaCaptur

e

IceGatherer IceGatherer

localStreamB

localStreamA

CandidateA

CandidateB

Edge の ORTC シーケンスMediaCaptur

eMediaCaptur

e

IceGatherer IceGatherer

localStreamB

localStreamA

CandidateA

CandidateB

シグナリングで Candidate を交換

Edge の ORTC シーケンスMediaCaptur

eMediaCaptur

e

IceGatherer IceGatherer

localStreamB

localStreamA

CandidateA

CandidateB

IceTransport IceTransport

ローカルの Candidate とリモートのCandidate の組み合わせから、通信可能な経路を探索する。var iceTr = new RTCIceTransport();mySignaller.onRemoteCandidate = function(remote) { iceTr.addRemoteCandidate(remote.candidate);}

CandidateB

CandidateA

IceTransport オブジェクトを生成する( ICE による通信経路確立のための準備)var iceTr = new RTCIceTransport();mySignaller.onRemoteCandidate = function(remote) { iceTr.addRemoteCandidate(remote.candidate);}

Edge の ORTC シーケンスMediaCaptur

eMediaCaptur

e

IceGatherer IceGatherer

localStreamB

localStreamA

CandidateA

CandidateB

IceTransport IceTransport

CandidateB

CandidateA

ICE TransporticeTrObjec

ticeTrObjec

t

Edge の ORTC シーケンスMediaCaptur

eMediaCaptur

e

IceGatherer IceGatherer

localStreamB

localStreamA

CandidateA

CandidateB

IceTransport IceTransport

CandidateB

CandidateA

DtlsTransport DtlsTransport

iceTrObject

iceTrObject

DTLS による暗号通信用の経路を作成する。var dtlsTr = new RTCDtlsTransport(iceTr);

dtlsTransport オブジェクトを生成する(鍵交換に利用する、 DTLS による暗号通信経路生成の準備)var dtlsTr = new RTCDtlsTransport(iceTr);

Edge の ORTC シーケンスMediaCaptur

eMediaCaptur

e

IceGatherer IceGatherer

localStreamB

localStreamA

CandidateA

CandidateB

IceTransport IceTransport

CandidateB

CandidateA

DtlsTransport DtlsTransport

iceTrObject

iceTrObject

dtlsTrObject

dtlsTrObject

Edge の ORTC シーケンスMediaCaptur

eMediaCaptur

e

IceGatherer RTCIceGatherer

localStreamB

localStreamA

CandidateA

CandidateB

IceTransport RTCIceTransport

CandidateB

CandidateA

DtlsTransport RTCDtlsTransport

RtpSenderRtpReceiver

RtpSenderRtpReceiver

iceTrObject

iceTrObject

dtlsTrObject

dtlsTrObject

localStream から Audio/Video Track を取り出して、それをメディアの送信用オブジェクトを作成する。var videoTrack = mediaStreamLocal.getVideoTracks()[0];var videoSender = new RtpSender(videoTrack, dtlsTr);

DtlsTransport オブジェクトと Audio/Video かを指定して、受信用オブジェクトを作成する。var videoReceiver = new RtpReceiver(dtlsTr, “video”);

localStream から Audio/Video Track を取り出して、それを元にメディアの送信用オブジェクトを作成する。( Track 単位でコントロールできるようになる)var videoTrack = mediaStreamLocal.getVideoTracks()[0];var videoSender = new RtpSender(videoTrack, dtlsTr);

DtlsTransport オブジェクトと Audio/Video を指定して、受信用オブジェクトを作成する。var videoReceiver = new RtpReceiver(dtlsTr, “video”);

補足: Media Stream Object

Media Stream Object

MediaStreamTrackA(VideoTrack)

MediaStreamTrackB(AudioTrack)

Edge の ORTC シーケンスIceTransport IceTransport

DtlsTransport DtlsTransport

RtpSenderRtpReceiver

RtpSenderRtpReceiver

SenderObject

ReceiverObject

iceTrObject

iceTrObject

dtlsTrObject

dtlsTrObject

SenderObject

ReceiverObject

Edge の ORTC シーケンスIceTransport IceTransport

DtlsTransport DtlsTransport

RtpSenderRtpReceiver

RtpSenderRtpReceiver

Sender と Receiver の能力を取得する。例えば、利用できるコーデックの種類等SenderObject

ReceiverObject

iceTrObject

iceTrObject

dtlsTrObject

dtlsTrObject

SenderObject

ReceiverObject

CapabilitieSender A

Capabilitie Receiver A

CapabilitieSender B

Capabilitie Receiver B

Sender と Receiver の能力を取得する。例えば、利用できるコーデックの種類等

Edge の ORTC シーケンスIceTransport IceTransport

DtlsTransport DtlsTransport

RtpSenderRtpReceiver

RtpSenderRtpReceiver

SenderObject

ReceiverObject

CapabilitieSender A

iceTrObject

iceTrObject

dtlsTrObject

dtlsTrObject

SenderObject

ReceiverObjectCapabilitie

Receiver A

シグナリングでICE/DTLS ParameterCapabilitie をそれぞれ交換

CapabilitieSender B

Capabilitie Receiver B

iCE Param A

dtls Param A

iCE Param B

dtls Param B

Edge の ORTC シーケンスIceTransport IceTransport

DtlsTransport DtlsTransport

RtpSenderRtpReceiver

RtpSenderRtpReceiver

SenderObject

ReceiverObject

CapabilitieSender A

iceTrObject

iceTrObject

dtlsTrObject

dtlsTrObject

SenderObject

ReceiverObjectCapabilitie

Receiver A

CapabilitieSender B

Capabilitie Receiver B

iCE Param A

dtls Param A

iCE Param B

dtls Param B

CapabilitieSender B

Capabilitie Receiver B

iCE Param B

dtls Param B

CapabilitieSender A

Capabilitie Receiver A

iCE Param A

dtls Param A

Edge の ORTC シーケンスiceTrObjec

ticeTrObjec

ticeTransport.start() .start()

※UDP ホールパンチングで UDP による通信経路を確立

Edge の ORTC シーケンスiceTrObjec

ticeTrObjec

t.start() .start()

dtlsTrObject

dtlsTrObject

iceTransport

dtlsTransport

※DTLS は SRTP の鍵交換に利用する( DTLS-SRTP )

Edge の ORTC シーケンスiceTrObjec

ticeTrObjec

t.start() .start()

dtlsTrObject

dtlsTrObject

iceTransport

SenderObject

.send()SenderObjec

t

.send()

dtlsTransport

Media Stream A ( VideoTrack/AudioTrack )Media Stream B( VideoTrack/AudioTrack )

Edge の ORTC シーケンスiceTrObjec

ticeTrObjec

t.start() .start()

dtlsTrObject

dtlsTrObject

iceTransport

SenderObject

.send()SenderObjec

t

.send()

ReceiverObject

ReceiverObject

.receive()

.receive()

dtlsTransport

Media Stream A ( VideoTrack/AudioTrack )Media Stream B( VideoTrack/AudioTrack )

Edge の ORTC シーケンス

Render Render

Receiverオブジェクトから Track を取得し、 MediaStreamオブジェクトに addTrack する。var mediaStreamRemote = new MediaStream();mediaStreamRemote.addTrack(audioReceiver.track); mediaStreamRemote.addTrack(videoReceiver.track);

※Track 単位でメディアを扱うが、 Video 要素にアタッチする際は、 MediaStreamオブジェクト単位での操作する必要あり。

ReceiverObject

ReceiverObject

WebRTC NV を利用した開発 ORTC の実装は WebRTC 1.0 よりは複雑で直感的にはわかりにくい(かもしれない)

WebRTC1.0 ではブラウザが隠蔽してた、よりローレベルな機能まで開発者が触ることが出来るため、開発自体はより複雑なものになり、より幅広い知識が必要になる。 その反面、トラブルシューティングの時などは、より細かなレベルで原因分析が可能になるというメリットも有している。 また、 WebRTC1.0 よりもユースケースという観点で、実装できる機能の幅は広がっている。

WebRTC 1.0 との相互接続性 WebRTC1.0 と ORTC は相互接続が出来る

ORTC が WebRTC1.0 よりローレベルな API であることを理解してもらう まずは、 WebRTC 1.0 の復習から・・・

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

ICE の Config を指定して、 PeerConnection Object を生成する。this.stunServerURL = “stun:stun.XXX.com:3478”;var config = { iceServers: [{ urls: this.stunServerURL }] };var .peerConnection = new webkitRTCPeerConnection(config);

必要なイベントをセットする。peerConnection.onaddstream = function(){};peerConnection.onicecandidate = function(){};

ICE の Config を指定して、 PeerConnection Object を生成する。this.stunServerURL = “stun:stun.XXX.com:3478”;var config = { iceServers: [{ urls: this.stunServerURL }] };var .peerConnection = new webkitRTCPeerConnection(config);

必要なイベントをセットする。peerConnection.onaddstream = function(){};peerConnection.onicecandidate = function(){};

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC Object

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC Object.addStream() .addStream()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC Object互いの MediaStreamオブジェクトが取得できたら、Video 要素に流し込む互いの localStream が PCオブジェクトにセットされた

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC Object.createOffer()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC Object.setLocalDescription()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A

シグナリングで SDP を相手に伝える

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A

.setRemoteDescription()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

.createAnswer()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A.setLocalDescription()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP B

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP Bシグナリングで SDP を相手に伝える

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP B

.setRemoteDescription()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

.onIceCandidate()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate Aシグナリングで Candidate を相手に伝える

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A

.addIceCandidate ()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

.onIceCandidate()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

Candidate B

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

Candidate Bシグナリングで Candidate を相手に伝える

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

Candidate B

.addIceCandidate ()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

Candidate BCandidate B

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

Candidate BCandidate B

UDP ホールパンチングで接続を試行する

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

Candidate BCandidate B

.onaddstream() .onaddstream()

WebRTC 1.0 のシーケンス復習MediaCaptur

eMediaCaptur

elocalStreamA

localStreamB

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

Candidate BCandidate B

localStreamA

localStreamB

互いの MediaStreamオブジェクトを取得して、 Video 要素に流し込む互いの MediaStreamオブジェクトが取得できたら、Video 要素に流し込む

WebRTC 1.0 との相互接続性 WebRTC1.0 と ORTC は相互接続が出来る

ORTC が WebRTC1.0 よりローレベルな API であることを理解してもらう 次は、 adapter.js に組み込まれている ORTC shim の実装を元に相互運用性を解説する。

※ adapter.js とは? - webrtc.org が公開している WebRTC 公式 Shim - Temasys 社の adapter.js とは別物なので注意   https://github.com/webrtc/adapter

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PeerConnectionオブジェクトを擬似的に作成する (1)window.RTCPeerConnection = function(config) { var self = this;

this.onicecandidate = null; this.onaddstream = null; this.onremovestream = null; this.onsignalingstatechange = null; this.oniceconnectionstatechange = null; this.onnegotiationneeded = null; this.ondatachannel = null;

this.localStreams = []; this.remoteStreams = []; this.getLocalStreams = function() { return self.localStreams; }; this.getRemoteStreams = function() { return self.remoteStreams; };

this.localDescription = new RTCSessionDescription({ type: '', sdp: '' }); this.remoteDescription = new RTCSessionDescription({ type: '', sdp: '' }); this.signalingState = 'stable'; this.iceConnectionState = 'new';

this.iceOptions = { gatherPolicy: 'all', iceServers: [] };

};

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PeerConnectionオブジェクトを擬似的に作成する(2)※ ここはわりと Edge の実装に合わせてゴニョゴニョしてるif (config && config.iceTransportPolicy) { switch (config.iceTransportPolicy) { case 'all': case 'relay': this.iceOptions.gatherPolicy = config.iceTransportPolicy; break; case 'none': // FIXME: remove once implementation and spec have added this. throw new TypeError('iceTransportPolicy "none" not supported'); }}if (config && config.iceServers) { // Edge does not like // 1) stun: // 2) turn: that does not have all of turn:host:port?transport=udp this.iceOptions.iceServers = config.iceServers.filter(function(server) { if (server && server.urls) { server.urls = server.urls.filter(function(url) { return url.indexOf('transport=udp') !== -1; })[0]; return true; } return false; });}

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC Object

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC Object.addStream() .addStream()

window.RTCPeerConnection.prototype.addStream = function(stream) { this.localStreams.push(stream.clone());};

特別な処理は必要ないwindow.RTCPeerConnection.prototype.addStream = function(stream) { this.localStreams.push(stream.clone());};

※Edge の仕様上 Stream は clone して渡す必要がある

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC Object.createOffer()

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC Object.createOffer()

処理が盛り沢山1. WebRTC 1.0 準拠の SDP を JS で生成2. ローカル ICE Candidate を収集var iceGatherer = new RTCIceGatherer(self.iceOptions);iceGatherer.onlocalcandidate = function(evt) { : :

3. Ice and Dtls Transport を生成var iceTransport = new RTCIceTransport(iceGatherer);var dtlsTransport = new RTCDtlsTransport(iceTransport);

4. RTPSender/Receiver を生成var rtpSender = new RTCRtpSender(track, transports.dtlsTransport);var rtpReceiver = new RTCRtpReceiver(transports.dtlsTransport, kind);

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC Object.setLocalDescription()

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC Object.setLocalDescription()

Offer側では先ほど生成したSDP を保管this.localDescription = description;

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A

シグナリングで SDP を相手に伝える

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A

.setRemoteDescription()

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A

.setRemoteDescription()

Offer の SDP を解析し必要なオブジェクトを生成1. ローカル ICE Candidate を収集var iceGatherer = new RTCIceGatherer(self.iceOptions);iceGatherer.onlocalcandidate = function(evt) { : :

2. Ice and Dtls Transportオブジェクトを生成var iceTransport = new RTCIceTransport(iceGatherer);var dtlsTransport = new RTCDtlsTransport(iceTransport);

3. RTPSender/Receiverオブジェクトを生成var rtpSender = new RTCRtpSender(track, transports.dtlsTransport);var rtpReceiver = new RTCRtpReceiver(transports.dtlsTransport, kind);

4. 相手の SDP を保管this.remoteDescription = description;

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

.createAnswer()

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

.createAnswer()

処理が盛り沢山1. WebRTC 1.0 準拠の SDP を JS で生成※細かい処理は省略

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

.setLocalDescription()

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

.setLocalDescription()

Answer の SDP を解析し必要な処理を行う1. Ice and Dtls Transport の処理を開始するiceTransport.start(iceGatherer, remoteIceParameters, ‘controlled’);dtlsTransport.start(remoteDtlsParameters);

2. 自分の SDP を保管this.localDescription = description;

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP B

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP Bシグナリングで SDP を相手に伝える

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP B

.setRemoteDescription()

Answer の SDP を解析し必要な処理を行う1. Ice and Dtls Transport の処理を開始するiceTransport.start(iceGatherer, remoteIceParameters, ‘controlling’);dtlsTransport.start(remoteDtlsParameters);

2. 相手の SDP を保管this.remoteDescription = description;

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

.onIceCandidate()

createOffer() の処理の中でセットした iceGatherer.onlocalcandidate イベントでローカルのCandidate を取得し、 WebRTC 1.0 のイベントに置き換えて発火させる。

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate Aシグナリングで Candidate を相手に伝える

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A

.addIceCandidate ()

受信した Candidate を iceTransport.addRemoteCandidate() でセットする。

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

Candidate BCandidate B

UDP ホールパンチングで通信経路を確立

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

Candidate BCandidate B

.onaddstream() .onaddstream()

createOffer() の処理の中で生成した、 rtpReceiver からRemote の MediaStreamTrack を取り出し、 MediaStreamオブジェクトに addTrack() し、 WebRTC 1.0 のイベントでプログラム側にコールバックする

WebRTC 1.0 on ORTC

MediaCapture

MediaCapturelocalStream

AlocalStream

B

PeerConnection

PeerConnection

PC Object PC ObjectSDP A SDP A

SDP BSDP B

Candidate A Candidate A

Candidate BCandidate B

.onaddstream() .onaddstream()

setRemoteDescription() の処理の中で生成した、 rtpReceiver から Remote の MediaStreamTrack を取り出し、 MediaStreamオブジェクトに addTrack() し、 WebRTC 1.0 のイベントでプログラム側にコールバックする

WebRTC 1.0 との相互接続性 ORTC の API を組み合わせることで WebRTC 1.0 の API を再現することが可能

既存 WebRTC 1.0 ライブラリを ORTC 環境で利用したい場合に実装が必要になる。 普通は shim を実装している adapter.js を利用するのが一番効率的だが、すんなり動かない事例場合もあるので、中身の理解は必要。

SkyWay で利用する Peer.js は数行の改修を加えて対応 改修内容は以下の diff を参照 https://

github.com/nttcom/peerjs/commit/7dedac9c4c8d2681e710f662d15bca7834251f5d#diff-0e4bfadc2f518e77444db1f92a1d2451

相互接続以外の使い方としては、アイディア次第では SFU や MCU ( Chrome のMediaRecorder API などと組み合わせも可能)など色々なものが JavaScript で自作可能

デモ: ORTC

Edge – Edge ( Video ) Chrome – Edge ( Audio )

まとめ

まとめ 今回のセッションでお伝えしたいこと

WebRTC 開発は各種フレームワークを利用することが一般的だが、特に業務で開発を行う場合は、様々なシーンで、開発者の WebRTC 力が要求されるため、内部の仕組みの理解も怠ってはいけない。 限定的なユースケースを想定している WebRTC 1.0 は、 Extensible Web の流れに従って、セキュアでよりローレベルな API を提供する WebRTC NV (現在では ORTC や WebRTC 1.0 に一部取り込まれている)にシフトしつつある。 WebRTC 1.0 と WebRTC NV は決して別の API ではない。 WebRTC はただのビデオチャットを実現する技術ではなくなってきている。 WebRTC NV の APIを組み合わせれば、 WebRTC 1.0 の API の再定義や、更に SFU などのメディアサーバだってブラウザ上で実現できるポテンシャルを秘めている。

WebRTC の進化からこれからも目が離せない!ご清聴ありがとうございました!

参考文献

WebRTC 標準化について http://

www.slideshare.net/iwashi86/2015-4-webrtc Extensible Web について

https://extensiblewebmanifesto.org/ja/ http://jxck.hatenablog.com/entry/extensible-l

owlevel-api ORTC について

http://ortc.org/wp-content/uploads/2015/11/ortc.html

http://iwashi.co/2015/08/13/ortc-and-webrtc/ http://jxck.hatenablog.com/entry/ortc-to-web

rtcnv http://www.slideshare.net/yusukenaka52/we

brtcortc-50153479 Edge における ORTC の実装例

https://blogs.windows.com/msedgedev/2015/09/18/ortc-api-is-now-available-in-microsoft-edge/

https://msdn.microsoft.com/ja-jp/library/mt588497(v=vs.85).aspx

Adapter.js の ORTC shim について https://github.com/webrtc/adapter/pull/136

top related