LoginSignup
6
1

More than 5 years have passed since last update.

外部サービス利用時、WebRTC APIを使用したい

Last updated at Posted at 2017-12-12

外部サービスを利用する

これは、WebRTCサービスに限らず、ほとんどのサービスに言えることのなのですが、
サービスは、ほぼもれなくSDKが用意されています。
SDKを使用したほうが開発は楽になりますが、その分学習コストを必要とします。
また、SDKのモデル体系がプロジェクトのモデル体系に一致しなかった場合、そのサービスを選択肢から除外することもあります。

SkyWayのモデル体系

SkyWayはPeerJSをベースとしたSDKとなっています。
PeerJSは1つのストリームにつき1つのPeerConnectionというモデル体系となっております。
もちろん、このモデル体系のほうが、ストリームに障害が発生したときやシグナリングなど管理が個別にできるため、管理しやすくなるなどメリットが大きいですが、それでも何らかの理由であえて1つのPeerConnectionで全ストリームを扱うことになった場合は、SDKのモデル体系によりSkyWayを選択肢から除外する可能性も出てきます。

OpenTokのSDKのモデル体系

OpenTokではPublisher/Subscriberというモデル体系となっており、SkyWay(PeerJS)より学習コストが高いものとなっております。
RTCPeerConnectionなどのWebRTC APIオブジェクトを完全とまではいかないもののほぼ隠ぺいしていますので、ハックするには手間がかかります。

サーバーの接続管理だけを行うSDK

前述の問題点にあわせて、WebRTC APIを熟知しているとまではいかないまでも、ある程度学習している場合は、WebRTC APIで実装したいでしょう。
そういった場合に、サーバーの接続管理(STUN,TURN,シグナリング)だけを行うSDKがほしいと思いませんか?
(私だけ?)

SkyWayのサーバー接続だけを行うサンプルコード

(※gUM()の代わりに動画を使用)

import { SkyWayConnector } from './SkyWayConnector.js';

let pcs = {};
let myId = null;

const con = new SkyWayConnector({
    key: 'APIキー'
});

con.on('open', conId => {
    dispMyId.textContent = myId = conId;
    btnConnect.disabled = false;
    console.log(`SkyWayConnector open. id='${myId}'`);
});

con.on('offer', msg => {
    console.log('offer msg', msg);
    const remoteId = msg.src;
    let pc = pcs[remoteId];
    if (!pc) {
        pc = setupPC(remoteId, true);
    }
    pc.setRemoteDescription(msg.offer).then(_ => {
        return pc.createAnswer();
    }).then(answer => {
        return pc.setLocalDescription(answer);
    }).then(_ => {
        con.sendAnswer(remoteId, pc.localDescription);
    });
});

con.on('answer', msg => {
    console.log('answer msg', msg);
    const remoteId = msg.src;
    let pc = pcs[remoteId];
    pc.setRemoteDescription(msg.answer);    
});

con.on('candidate', msg => {
    console.log('candidate msg', msg);
    const remoteId = msg.src;
    let pc = pcs[remoteId];
    pc.addIceCandidate(msg.candidate);
});

con.on('leave', msg => {
    console.log('leave msg', msg);
});

con.on('expiresin', msg => {
    console.log('expiresin msg', msg);
});

btnConnect.onclick = function (evt) {
    if (!txtRemoteId.value.trim()) return;
    const remoteId = txtRemoteId.value;
    setupPC(txtRemoteId.value);
};

function setupPC(remoteId, callee) {
    const pc = pcs[remoteId] = new RTCPeerConnection(con.PCConfig);
    pcs[remoteId].remoteId = remoteId;

    pc.onicecandidate = function (evt) {
        if (evt.candidate)
            con.sendCandidate(this.remoteId, evt.candidate);
    };

    pc.onnegotiationneeded = function () {
        pc.createOffer().then(offer => {
            return this.setLocalDescription(offer);
        }).then(_ => {
            con.sendOffer(this.remoteId, this.localDescription);
        }).catch(err => {
            logError(err);
        });
    };

    pc.ontrack = function (evt) {
        if (!remoteView.srcObject)
            remoteView.srcObject = evt.streams[0];
    };

    selfView.onloadedmetadata = function(evt) {
        const stream = selfView.captureStream();
        stream.getVideoTracks().forEach(track => {
            pc.addTrack(track);
        });
    };
    selfView.src = callee ? 'sintel.mp4' : 'bipbop.mp4';

    return pc;
}

function logError(error) {
   console.error(error);
}

このように、サーバーへの接続部分のみをライブラリ化し、あとはWebRTC APIで実装するというものです。
GitHub

以上

NTTさん、このようなSDKも用意していただけませんか?

6
1
0

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
6
1