FAQ

対応ブラウザについて

Sora JavaScript SDK の 2024.2.0 以降を利用するには Compression Stream API をサポートしているブラウザのバージョンが必要になります。

  • Chrome / Chrome 80 以降

  • Firefox 113 以降

  • Safari 16.4 以降

Sora JavaScript SDK のサンプルについて

Sora JavaScript SDK のサンプル

Sora JavaScript SDK の最小限の書き方を確認できるサンプルです。

https://github.com/shiguredo/sora-js-sdk-examples

Sora JavaScript SDK ドキュメントのサンプル

Sora JavaScript SDK の解説を目的としたサンプルです。

サンプル

仕様

MediaStreamTrack と Connection ID の紐付け

Sora JavaScript SDK は MediaStreamTrack と Connection ID の紐付けを行う仕組みは提供していません。

ただし track コールバック時に、 RTCTrackEventstreams から MediaStream を取得できます。 MediaStreamstream.id が Connection ID となります。

client.on("track", (event: RTCTrackEvent) => {
  // Sora では必ず 1 クライアント から送られてくるのは 1 音声/ 1 映像に固定されています
  // そのため track.streams[0] でクライアントのメディアストリームを取得できます
  const stream = event.streams[0];

  // メディアストリームの ID はその音声と映像を配信しているクライアントの connectionId です
  // stream.id で取得できます
  console.log("connectionId: ", stream.id);
});

メディアストリームの扱い

Sora JavaScript SDK は音声や映像といったメディアストリームを SDK から扱うことはありません。

そのため音声や映像を扱う場合は MediaDevices.getUserMedia() API や MediaDevices.getDisplayMedia() API を利用し、 アプリケーション開発者がメディアストリームを取得し、Sora JavaScript SDK に渡す必要があります。

マルチトラック

Sora JavaScript SDK が配信可能なメディアストリームは 1 本で 1 音声トラック、1 映像トラックとなります。 これは Sora の仕様になります。

そのため、マルチトラックには対応しておりません。

もし複数の音声や映像を 1 クライアントで配信したい場合は複数のコネクションを張るようにしてください。

"type": "answer" の SDP 書き換えは SDK の挙動に影響はありますか?

Sora JS SDK では createAnswer が生成した SDP をそのまま利用するようにしています。 そのため、書き換え処理で SDK 側には基本的に影響することはありません。

もし SDP 書き換えをを行う場合は "type": "answer" だけでなく、 "type": "re-answer" も書き換えるようにしてください。

注釈

WebRTC API を利用せずに手動で SDP を変更する処理を "SDP Munging" と呼びます。

Sora への影響については Sora または Sora Cloud のサポートまでご連絡ください。

シグナリング

Sora との接続が完了したことを通知するコールバックはありますか?

Sora JavaScript SDK には Sora との接続完了を通知するには、 Sora のシグナリング通知機能を利用してください。

シグナリング通知機能の connection.createdconnection_id を利用してください。

// 色々省略
const sendrecv = soraConnection.sendrecv(channelId, metadata, options);
await sendrecv.connect(stream);

// シグナリング通知
sendrecv.on("notify", (event: SignalingNotifyMessage) => {
  console.log("notify", event.event_type);
  if (
    // connection.created が Sora とクライアントの間で WebRTC が確立した事を通知しています
      event.event_type === "connection.created" &&
      // 自分の connection_id と一致
      sendrecv.connectionId === event.connection_id
  ) {
      // 接続が成功
      console.log("self-connection_id: ", event.connection_id);
  }

  // 自分以外の参加者の connection_id の取得
  if (event.event_type === "connection.created") {
    console.log("connection_id", event.connection_id);
  }
});

データチャネルメッセージング

メッセージングのみを利用したいです

messaging() を利用する事でメッセージングのみを利用できます。

const options = {
  dataChannelSignaling: true,
  dataChannels: [
    {
      label: "#example",
      direction: "sendrecv" as DataChannelDirection,
    },
    {
      label: "#example2",
      direction: "recvonly" as DataChannelDirection,
    },
  ],
};
const messaging = soraConnection.messaging(channelId, metadata, options);
await messaging.connect();

maxPacketLifeTime や maxRetransmits が設定できません

Sora のシグナリング仕様では snake_case での指定ですが、 Sora JavaScript SDK では camelCase での指定となります。

const options = {
  dataChannelSignaling: true,
  dataChannels: [
    {
    label: "#example",
    direction: "sendrecv" as DataChannelDirection,
    maxPacketLifeTime: 60000,
    },
  ],
};
const options = {
  dataChannelSignaling: true,
  dataChannels: [
    {
      label: "#example",
      direction: "sendrecv" as DataChannelDirection,
      maxRetransmits: 0,
    },
  ],
};

WebRTC API

Sora JavaScript SDK には Sora との接続部分の機能のみを提供しています。

そのため、映像や音声、データなどを実際に処理する場合はすべて JavaScript の WebRTC API やライブラリなどを利用する必要があります。

WebRTC API - Web API | MDN

解像度を変更するにはどうしたらいいですか?

解像度の変更は MediaDevices.getUserMedia()MediaDevices.getDisplayMedia() API 側で行ってください。

背景をぼかすにはどうしたらいいですか?

時雨堂がオープンソースとして公開している @shiguredo/virtual-background - npm を利用することで簡単にブラウザで背景ぼかし機能を利用可能です。

以下で動作確認が可能です。 https://shiguredo.github.io/media-processors/virtual-background/

ライトを調整はできますか?

時雨堂がオープンソースとして公開している @shiguredo/light-adjustment - npm を利用することで簡単にブラウザでライト調整機能を利用可能です。

以下で動作確認が可能です。 https://shiguredo.github.io/media-processors/light-adjustment/

ノイズを抑制できますか?

時雨堂がオープンソースとして公開している @shiguredo/noise-suppression - npm を利用することで簡単にブラウザでノイズ抑制機能を利用可能です。

以下で動作確認が可能です。 https://shiguredo.github.io/media-processors/noise-suppression/

音声でステレオは利用できますか?

WebRTC の Opus はデフォルトで 2 チャンネル利用するためステレオに対応しています。

ただし、ステレオ音声を利用する場合はデフォルトで有効になっているエコーキャンセルを無効にする必要があります。

https://www.w3.org/TR/mediacapture-streams/#dom-mediatracksupportedconstraints-echocancellation

画面キャプチャはできますか?

MediaDevices.getDisplayMedia() を利用して画面のストリームを取得してください。

カメラを切り替えられますか?

トラックを切り替えたい場合は RTCRtpSender.replaceTrack() を利用して既存のトラックと置き換えを行ってください。

音声をミュートにできますか?

Sora JavaScript SDK はトラックのミュートは行いません。

トラックのミュートを行いたい場合は MediaStreamTrack.enabled を利用して、ミュートを行ってください。

Electron で利用したいです

Sora JavaScript SDK は Electron でも利用可能です。

MediaStreamTrack から MediaStream の ID を取得したいです

MediaStreamTrack から MediaStream の ID は取得できません。 そのため、もし取得したい場合は何かしらの方法で ID を保持しておく必要があります。

ただし removetrack コールバックは MediaStream が発火させるため event.target で発火した MediaStream を取得可能です。

MediaStream: removetrack event - Web APIs | MDN

CPU や帯域による解像度やフレームレートの制限を無効にしたいです

無効にできません。

ブラウザで CPU 負荷が高まったと判断して、利用ビットレートを下げたことにより解像度やフレームレートが下がる場合、 Chrome 102 までは googCpuOveruseDetection という設定があり、 false にすることで、判定を無効にできていましたが、 その設定は Chrome 103 にて廃止されました。

Tip

制限の理由は qualityLimitationReason で確認できます。

映像を回転させたいです

getUserMedia で取得した映像を回転させるには Canvas API を利用してください。

<!doctype html>
<html lang="ja">

<head>
  <meta charset="UTF-8" />
</head>

<body>
  <video id="originalVideo" autoplay="" playsinline="" controls="" muted=""></video>
  <video id="rotatedVideo" autoplay="" playsinline="" controls="" muted=""></video>
  <hr />
  <script type="module" src="./main.ts"></script>

</body>

</html>
// getUserMedia で取得した映像を Canvas API を利用して 90 度回転する

document.addEventListener("DOMContentLoaded", async () => {
  const originalVideo = document.getElementById("originalVideo") as HTMLVideoElement;
  const rotatedVideo = document.getElementById("rotatedVideo") as HTMLVideoElement;

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

  originalVideo.srcObject = mediaStream;

  const rotatedMediaStream = rotateMediaStream(mediaStream);
  rotatedVideo.srcObject = rotatedMediaStream;
});

const rotateMediaStream = (mediaStream: MediaStream): MediaStream => {
  // 元の映像トラックを取得
  const videoTrack = mediaStream.getVideoTracks()[0];

  // 映像の設定を取得
  const settings = videoTrack.getSettings();
  const width = settings.width || 640;
  const height = settings.height || 480;

  // Canvas要素を作成
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  // 90度回転させるため、幅と高さを入れ替える
  canvas.width = height;
  canvas.height = width;

  // Video要素を作成
  const video = document.createElement("video");
  video.srcObject = mediaStream;
  video.autoplay = true;

  // 映像フレームを描画して回転させる
  video.addEventListener("play", () => {
    const draw = () => {
      if (ctx) {
        // Canvasを90度回転
        ctx.save();
        ctx.translate(canvas.width, 0);
        ctx.rotate(Math.PI / 2);
        ctx.drawImage(video, 0, 0, width, height);
        ctx.restore();
      }
      requestAnimationFrame(draw);
    };
    draw();
  });

  // 回転した映像をMediaStreamとして取得
  return canvas.captureStream();
};
© Copyright 2024, Shiguredo Inc. Created using Sphinx 8.1.3