サンプル

共通 HTML

送受信、送信のみ、受信のみで利用します。

送受信で接続する

sendrecv() を使用して接続します。

マルチストリームで接続した Connection オブジェクト は接続したチャネル ID に MediaStream が追加、削除されるとコールバックが呼ばれます。 コールバックを利用して追加、削除された MediaStream を処理します。

import Sora from "sora-js-sdk";

const connectToSora = async () => {
  // オーディオとビデオのストリームを取得
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true,
  });

  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    multistream: true,
  };
  const sendrecv = sora.sendrecv(channelId, metadata, options);

  // ontrack イベント (リモートメディアストリームが追加されたときに発生)
  sendrecv.on("track", (event) => {
    // 追加されたストリームを取得
    const stream = event.streams[0];

    // リモートビデオエレメントを取得
    const remoteVideos = document.querySelector("#remote-videos");

    // リモートビデオエレメントのIDを生成
    const remoteVideoId = `remote-video-${stream.id}`;
    // 既存のビデオエレメントが無ければ新たに作成
    if (!remoteVideos!.querySelector(`#${remoteVideoId}`)) {
      const remoteVideo = document.createElement("video");
      remoteVideo.id = remoteVideoId;
      remoteVideo.autoplay = true;
      remoteVideo.srcObject = stream;
      remoteVideos!.appendChild(remoteVideo);
    }
  });

  // removetrack イベント (リモートメディアストリームが削除されたときに発生)
  sendrecv.on("removetrack", (event) => {
    // target は removetrack が発火した MediaStream
    const target = event.target as MediaStream;
    const remoteVideo = document.querySelector(`#remote-video-${target.id}`);
    const remoteVideos = document.querySelector("#remote-videos");
    if (remoteVideo) {
      remoteVideos!.removeChild(remoteVideo);
    }
  });

  await sendrecv.connect(stream);

  console.log("Connected to Sora");
};

connectToSora();

実際に動作するサンプルは sora-js-sdk/examples/sendrecv.html

送信のみで接続する

sendonly() を使用して接続します。

import Sora from "sora-js-sdk";

const connectToSora = async () => {
  // オーディオとビデオのストリームを取得
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true,
  });

  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    multistream: true,
  };
  const sendrecv = sora.sendonly(channelId, metadata, options);
  await sendrecv.connect(stream);

  console.log("Connected to Sora");
};

connectToSora();

実際に動作するサンプルは sora-js-sdk/examples/sendonly.html

受信のみで接続する

recvonly() を使用して接続します。

import Sora from "sora-js-sdk";

const connectToSora = async () => {
  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora-js-sdk";
  const metadata = undefined;
  const options = {
    multistream: true,
  };
  const recvonly = sora.recvonly(channelId, metadata, options);

  // ontrack イベント (リモートメディアストリームが追加されたときに発生)
  recvonly.on("track", (event) => {
    // 追加されたストリームを取得
    const remoteStream = event.streams[0];

    // リモートビデオエレメントを取得
    const remoteVideos = document.querySelector("#remote-videos");

    // リモートビデオエレメントのIDを生成
    const remoteVideoId = `remote-video-${remoteStream.id}`;

    // 既存のビデオエレメントが無ければ新たに作成
    if (!remoteVideos!.querySelector(`#${remoteVideoId}`)) {
      const remoteVideo = document.createElement("video");
      remoteVideo.id = remoteVideoId;
      remoteVideo.autoplay = true;
      remoteVideo.srcObject = remoteStream;
      remoteVideos!.appendChild(remoteVideo);
    }
  });

  // removetrack イベント (リモートメディアストリームが削除されたときに発生)
  recvonly.on("removetrack", (event) => {
    // target は removetrack が発火した MediaStream
    const target = event.target as MediaStream;
    const remoteVideo = document.querySelector(`#remote-video-${target.id}`);
    const remoteVideos = document.querySelector("#remote-videos");
    if (remoteVideo) {
      remoteVideos!.removeChild(remoteVideo);
    }
  });

  recvonly.connect();

  console.log("Connected to Sora");
};

connectToSora();

実際に動作するサンプルは sora-js-sdk/examples/recvonly.html

サイマルキャストを有効にしてで接続する

サイマルキャスト (Simulcast) は配信時に 1 つの RTCPeerConnection から複数種類のエンコードした映像を配信する機能です。 詳しくは Sora ドキュメント サイマルキャスト を参照してください。

オプションsimulcast: true を指定します

import Sora, { type VideoCodecType } from "sora-js-sdk";

const connectToSora = async () => {
  // オーディオとビデオのストリームを取得
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true,
  });

  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    simulcast: true,
    multistream: true,
    videoCodecType: "VP8" as VideoCodecType,
  };
  const sendonly = sora.sendonly(channelId, metadata, options);
  await sendonly.connect(stream);

  console.log("Connected to Sora");
};

connectToSora();

スポットライトで接続する

スポットライト (Spotlight) は一定の音量を超えて音声を発している参加者の場合は音声や高画質映像を、それ以外の参加者は音声のない低画質映像を配信する機能です。 詳しくは Sora ドキュメント スポットライト を参照してください。

オプションspotlight: true multistream: true を指定します

import Sora, { type VideoCodecType } from "sora-js-sdk";

const connectToSora = async () => {
  // オーディオとビデオのストリームを取得
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true,
  });

  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    simulcast: true,
    // スポットライト機能を有効にする
    spotlight: true,
    multistream: true,
    videoCodecType: "VP8" as VideoCodecType,
  };

  const sendonly = sora.sendonly(channelId, metadata, options);
  await sendonly.connect(stream);

  console.log("Connected to Sora");
};

connectToSora();

音声や映像コーデックを指定する

音声や映像のコーデックタイプは オプション で指定します

import Sora, { type AudioCodecType, VideoCodecType } from "sora-js-sdk";

const connectToSora = async () => {
  // オーディオとビデオのストリームを取得
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true,
  });

  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    multistream: true,
    // 音声コーデックに Opus を指定
    audioCodecType: "OPUS" as AudioCodecType,
    // 映像コーデックに VP9 を指定
    videoCodecType: "VP9" as VideoCodecType,
  };

  const sendrecv = sora.sendrecv(channelId, metadata, options);
  await sendrecv.connect(stream);

  console.log("Connected to Sora");
};

connectToSora();

音声や映像のビットレートを指定する

音声のビットレート指定は推奨しません

音声や映像のビットレートは オプション で指定します

import Sora from "sora-js-sdk";

const connectToSora = async () => {
  // オーディオとビデオのストリームを取得
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true,
  });

  const debug = true;
  // Sora への接続を作成
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    multistream: true,
    audio: true,
    // オーディオのビットレートを 64 kbps に設定
    audioBitRate: 64,
    video: true,
    // ビデオのビットレートを 192 kbps に設定
    videoBitRate: 192,
  };

  const sendrecv = sora.sendrecv(channelId, metadata, options);
  await sendrecv.connect(stream);

  console.log("Connected to Sora");
};

connectToSora();
  • 音声ビットレートに指定できる範囲は 6-510 です

  • 映像ビットレートに指定できる範囲は 1-30000 です

映像コーデックパラメーターを指定する

オプション で指定します

import Sora, { type VideoCodecType } from "sora-js-sdk";

const connectToSora = async () => {
  // オーディオとビデオのストリームを取得
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true,
  });

  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    video: true,
    videoCodecType: "VP9" as VideoCodecType,
    // VP9 の 映像パラメーターで profile-id を 2 に指定
    // これを利用するには sora.conf にて signaling_vp9_params = true を設定する必要がある
    videoVp9Params: {
      profileId: 2,
    },
    multistream: true,
  };

  const sendonly = sora.sendonly(channelId, metadata, options);
  await sendonly.connect(stream);

  console.log("Connected to Sora");
};

connectToSora();

AV1 や H.264 でも指定可能です。

映像と音声の可否を指定する

オプション で指定します

音声なし

import Sora from "sora-js-sdk";

const connectToSora = async () => {
  // ユーザーメディア(ビデオのみ)を取得
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: false,
    video: true,
  });

  const debug = true;
  // Sora への接続を作成
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    audio: false, // オーディオは不要
    multistream: true,
  };

  const sendrecv = sora.sendrecv(channelId, metadata, options);
  await sendrecv.connect(stream);

  console.log("Connected to Sora");
};

connectToSora();

映像なし

import Sora from "sora-js-sdk";

const connectToSora = async () => {
  // ユーザーメディア(オーディオのみ)を取得
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: false,
  });

  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    video: false, // ビデオは不要
    multistream: true,
  };

  const sendonly = sora.sendonly(channelId, metadata, options);
  await sendonly.connect(stream);

  console.log("Connected to Sora");
};

connectToSora();

クライアントIDを指定する

接続時やサーバー認証成功時に任意の文字列を指定できる値です。 詳しくは Sora ドキュメント WebSocket 経由のシグナリング client_id を参照してください。

オプション で指定します

import Sora from "sora-js-sdk";

const connectToSora = async () => {
  // オーディオとビデオのストリームを取得
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true,
  });

  const debug = true;
  // Sora への接続を作成
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    multistream: true,
    // client-id に xyz を指定
    // client-id は重複可能
    clientId: "xyz",
  };

  const sendrecv = sora.sendrecv(channelId, metadata, options);
  await sendrecv.connect(stream);

  console.log("Connected to Sora");
};

connectToSora();

DataChannel 経由のシグナリングを使用する

WebRTC 接続確立後に、シグナリングを WebSocket 経由から DataChannel 経由に切り替える機能です。 詳しくは Sora ドキュメント DataChannel 経由のシグナリング を参照してください。

オプション で指定します

import Sora from "sora-js-sdk";

const connectToSora = async () => {
  const mediaStream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true,
  });

  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    multistream: true,
    // シグナリングを WebSocket 経由から DataChannel 経由に切り替えるかどうかを指定
    dataChannelSignaling: true,
    // シグナリングを DataChannel 経由に切り替えたあとに WebSocket を切断するかどうかを指定
    ignoreDisconnectWebSocket: false,
  };

  const sendrecv = sora.sendrecv(channelId, metadata, options);
  await sendrecv.connect(mediaStream);
};

connectToSora();

メッセージング機能を使用する

DataChannel を利用したデータの送受信を行える機能です。 詳しくは Sora ドキュメント メッセージング機能 も合わせて参照してください。

オプション で指定します。

import Sora, { type DataChannelDirection } from "sora-js-sdk";

const connectAndSendMessage = async () => {
  const mediaStream = await navigator.mediaDevices.getUserMedia({
    audio: true,
    video: true,
  });

  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;
  const options = {
    multistream: true,
    // メッセージング機能を利用するには、データチャネルを利用したシグナリングを有効にする必要がある
    dataChannelSignaling: true,
    dataChannels: [
      {
        // メッセージングのラベルは # から始める必要がある
        label: "#example",
        // メッセージングの方向、sendrecv は送受信可能
        // sendonly の場合は送信のみ可能
        // recvonly の場合は受信のみ可能
        direction: "sendrecv" as DataChannelDirection,
        // https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/maxPacketLifeTime
        // https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/maxRetransmits
        maxPacketLifeTime: 60000,
      },
    ],
  };
  const sendrecv = sora.sendrecv(channelId, metadata, options);

  // メッセージ送信が可能な datachannel との接続が確立した場合に on datachannel イベントが発火する
  sendrecv.on("datachannel", (event) => {
    // event.datachannel にメッセージ送信可能な datachannel の情報が含まれる
    const label = event.datachannel.label; // #example
    console.log("ondatachannel", label);
    // メッセージを送信する
    sendrecv.sendMessage(label, new TextEncoder().encode("Hello world."));
  });

  // メッセージを受信した際に on message イベントが発火する
  sendrecv.on("message", (event) => {
    const label = event.label;
    const data = event.data;
    console.log("onmessage", label, data);
  });

  await sendrecv.connect(mediaStream);

  console.log("Connected to Sora");
};

// Soraへの接続とメッセージ送受信を開始
connectAndSendMessage();

メッセージングのみで接続することも可能です。ただし connect 時に空のメディアストリームを渡す必要があります。

import Sora, { type DataChannelDirection } from "sora-js-sdk";

const connectAndSendMessage = async () => {
  const debug = true;
  // 接続先の Sora を設定する
  const sora = Sora.connection("wss://sora.example.com/signaling", debug);
  const channelId = "sora";
  const metadata = undefined;

  // ConnectionOptions の dataChannels を指定する
  const options = {
    // データチャネルメッセージオンリーを使う場合は設定が必要
    // https://sora-doc.shiguredo.jp/MESSAGING#3a3616
    audio: false,
    video: false,
    multistream: true,
    // データチャネルシグナリングを利用する
    dataChannelSignaling: true,
    // データチャネルメッセージングの定義を追加
    dataChannels: [
      {
        label: "#example",
        direction: "sendrecv" as DataChannelDirection,
      },
    ],
  };

  const sendrecv = sora.sendrecv(channelId, metadata, options);
  // 空のメディアストリームを渡す
  await sendrecv.connect(new MediaStream());

  // メッセージを送信する
  sendrecv.sendMessage("#example", new TextEncoder().encode("Hello world."));
};

connectAndSendMessage();
© Copyright 2023, Shiguredo Inc. Created using Sphinx 7.2.5