LoginSignup
2
2

More than 5 years have passed since last update.

[webRTC for android vol4] 複数台接続

Last updated at Posted at 2017-08-12

Android で複数台接続いきます。

成果物

↑ iOSとブラウザが相手。

環境

  • android studio 2.3.3
  • Nexus 5x android6.0.1

流れ

設計

IMG_4767.JPG

インタフェース

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に回す。

終わり。

まとめ

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2