Android で複数台接続いきます。
- 1:1はこちら → webRTC for android vol3 trickle ICE
- web版はこちら → webRTC for web vol2 複数人での接続
- iOS版はこちら → webRTC for ios vol4 複数台接続
成果物
↑ iOSとブラウザが相手。
環境
- android studio 2.3.3
- Nexus 5x android6.0.1
流れ
設計
インタフェース
Wamp
WampInterface.java
enum Topic {
Callme("com.nakadoribook.webrtc.[roomId].callme"),
Close("com.nakadoribook.webrtc.[roomId].close"),
Answer("com.nakadoribook.webrtc.[roomId].[userId].answer"),
Offer("com.nakadoribook.webrtc.[roomId].[userId].offer"),
Candidate("com.nakadoribook.webrtc.[roomId].[userId].candidate");
private final String text;
private Topic(final String text) {
this.text = text;
}
public String getString() {
return this.text;
}
}
interface WampCallbacks {
void onOpen();
void onReceiveAnswer(String targetId, String sdp);
void onReceiveOffer(String taretId, String sdp);
void onIceCandidate(String targetId, String sdp, String sdpMid, int sdpMLineIndex);
void onReceiveCallme(String targetId);
void onCloseConnection(String targetId);
}
public interface WampInterface {
void connect();
void publishCallme();
void publishOffer(String targetId, String sdp);
void publishAnswer(String targetId, String sdp);
void publishCandidate(String targetId, String candidate);
}
WebRTC
WebRTCInterface.java
interface WebRTCCallbacks{
void onCreateOffer(String sdp);
void onCreateAnswer(String sdp);
void didReceiveRemoteStream(MediaStream mediaStream);
void onIceCandidate(String sdp, String sdpMid, int sdpMLineIndex);
}
public interface WebRTCInterface {
void createOffer();
void receiveOffer(String sdp);
void receiveAnswer(String sdp);
void receiveCandidate(String sdp, String sdpMid, int sdpMLineIndex);
void close();
}
Connection
ConnectionInterface.java
interface ConnectionCallbacks{
void onAddedStream(MediaStream mediaStream);
}
public interface ConnectionInterface {
String targetId();
void publishOffer();
void receiveOffer(String sdp);
void receiveAnswer(String sdp);
void receiveCandidate(String candidate, String sdpMid, int sdpMLineIndex);
void close();
}
実装
App(MainActivity.java)
WampTopic監視
Wamp.callback → App の部分。
自分のuserId のトピックを監視する。
- openしたタイミングで roomIDのみんなにCallme を送る
- その他はtargetIdから対象のConnection探してそのまま情報を流す
receiveOffer と、 receiveCallme のところで、Connectionを作る。
MainActivity.java
private void setupWamp(){
// wamp
String roomId = "abcdef"; // とりあえず固定
wamp = new Wamp(this, roomId, userId, new WampCallbacks() {
@Override
public void onOpen() {
wamp.publishCallme();
}
@Override
public void onReceiveAnswer(String targetId, String sdp) {
Connection connection = findConnection(targetId);
if(connection == null){
Log.d("onReceiveAnswer", "not found connection");
return;
}
connection.receiveAnswer(sdp);
}
@Override
public void onReceiveOffer(String targetId, String sdp) {
Connection connection = createConnection(targetId);
connection.receiveOffer(sdp);
}
@Override
public void onIceCandidate(String targetId, String candidate, String sdpMid, int sdpMLineIndex) {
Connection connection = createConnection(targetId);
connection.receiveCandidate(candidate, sdpMid, sdpMLineIndex);
}
@Override
public void onReceiveCallme(String targetId) {
Connection connection = createConnection(targetId);
connection.publishOffer();
}
@Override
public void onCloseConnection(String targetId) {
}
});
}
相手のストリームを表示
Connection.callback → app の部分。
相手のストリームをもらったらViewを作って表示する
MainActivity.java
Connection connection = new Connection(userId, targetId, wamp, new ConnectionCallbacks() {
@Override
public void onAddedStream(MediaStream mediaStream) {
final VideoTrack remoteVideoTrack = mediaStream.videoTracks.getFirst();
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
SurfaceViewRenderer remoteRenderer = new SurfaceViewRenderer(MainActivity.this);
// 〜 略 〜
GridLayout remoteViewContainer = (GridLayout) MainActivity.this.findViewById(R.id.remote_view_container);
remoteViewContainer.addView(remoteRenderer);
}
});
}
});
Connection
webrtcのシグナリング
WebRTC.callback → Connection (→ Wamp) の部分。
Offer/Answer/Candidate がWebRTCから出てくるので、それをWampでpublishして相手に渡す.
Connection.java
this.webRTC = new WebRTC(new WebRTCCallbacks(){
@Override
public void onCreateOffer(String sdp) {
try{
JSONObject json = new JSONObject();
json.put("sdp", sdp);
json.put("type", "offer");
wamp.publishOffer(targetId, json.toString());
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void onCreateAnswer(String sdp) {
try{
JSONObject json = new JSONObject();
json.put("sdp", sdp);
json.put("type", "answer");
wamp.publishAnswer(targetId, json.toString());
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void onIceCandidate(String sdp, String sdpMid, int sdpMLineIndex) {
final JSONObject json = new JSONObject();
try{
json.put("type", "candidate");
json.put("candidate", sdp);
json.put("sdpMid", sdpMid);
json.put("sdpMLineIndex", sdpMLineIndex);
wamp.publishCandidate(targetId, json.toString());
}catch (Exception e){
e.printStackTrace();
}
}
});
そんなこんなやってるとそのうち
Connection.java
@Override
public void didReceiveRemoteStream(MediaStream mediaStream) {
callbacks.onAddedStream(mediaStream);
}
相手のストリームが拾えるので拾ったらConnectionに回す。
終わり。
次
まとめ