FAQ

一般

Sora Flutter SDK のライセンスはなんですか?

Sora Flutter SDK はオープンソースライセンス Apache License, Version 2.0 で配布しています。

Sora Flutter SDK は WebRTC SFU Sora 以外の SFU にも利用できますか?

WebRTC SFU Sora のシグナリング方式に対応している SFU であれば利用できます。

Sora Flutter SDK はどのプラットフォームに対応していますか?

対応プラットフォームについては プラットフォーム をご確認ください。

サンプルコードはありますか?

サンプルコードはありませんが、 Sora に接続できる開発者ツール実装を用意しています。 https://github.com/shiguredo/sora-flutter-sdk/tree/develop/devtools をご確認ください。

ソースコードをダウンロードする際の注意点はありますか?

git clone などでソースコードをダウンロードする場合は、タグを指定するか main ブランチを選択してください。

Dart 以外の言語で使えますか?

使えません。 Sora Flutter SDK は Dart 専用です。

設定

Sora Flutter SDK が対応している音声コーデックを教えてください

Sora Flutter SDK は以下の音声コーデックに、すべてのプラットフォームで対応しています。

  • Opus

Sora Flutter SDK が対応している映像コーデックを教えてください

映像コーデックの実際の対応状況は、プラットフォームと端末 / OS バージョンに依存します。SDK は次の映像エンコーダー / デコーダーを利用します。

バックエンド

対応プラットフォーム

エンコード

デコード

ソフトウェア

全プラットフォーム

VP8 / VP9 / AV1

VP8 / VP9 / AV1

Apple VideoToolbox

iOS / macOS

H.264 / H.265

H.264 / H.265

Android MediaCodec

Android

H.264 / H.265 / VP8 / VP9 / AV1

H.264 / H.265 / VP8 / VP9 / AV1

Sora.supportedVideoCodecTypes で、実行中のプラットフォームのデコーダーが対応するコーデックを確認できます。

final codec = VideoCodecType.h264;
final supportedCodecs = Sora.supportedVideoCodecTypes;

if (!supportedCodecs.contains(codec)) {
  throw UnsupportedError('このプラットフォームのデコーダーは対応していません');
}

この API は実際にハードウェア / ソフトウェアデコードが可能なコーデックを返します。送信側のエンコーダー対応を保証する API ではないため、 videoCodecType に指定したコーデックで送信できることを確認する用途には使えません。

H.264 と H.265 を利用する条件はありますか?

あります。 H.264 / H.265 のハードウェアエンコード / デコードを利用するには、 iOS / macOS デバイスが Apple VideoToolbox に、 Android デバイスが Android MediaCodec に対応している必要があります。端末や OS バージョンによって利用できない場合があります。

ハードウェアアクセラレーターを利用するにはどうすればいいですか?

ハードウェアアクセラレーターを利用する際は以下の条件を全て満たしている必要があります。

  • デバイスが利用したいコーデックのハードウェアアクセラレーターを搭載していること
  • SDK が対象プラットフォームのハードウェアエンコーダー / デコーダーに対応していること

Sora Flutter SDK では、 iOS / macOS は Apple VideoToolbox 、 Android は Android MediaCodec を利用します。

Windows / Linux の H.264 / H.265 対応は、このハードウェア対応表には含まれません。

受信したリモート映像の黒画面が相手の切断後も残り続けるのはなぜですか?

受信側が対応していないコーデックの映像を受信すると、画面が真っ黒のままで映像が表示されない状態になります。この黒画面が相手の切断後も残り続けることがあります。

非対応コーデックの映像の場合、answer で拒否するため映像フレームが届かず、映像が映らない状態が続きます。このとき、 SoraTrackEvent で映像トラックが通知されるため、 textureId を取得することはできます。

通常は相手が切断した際、 SoraRemoveTrackEvent が映像トラック削除時に通知され、 画面表示更新に利用することができます。しかし answer で拒否した映像トラックについては libwebrtc の挙動で通知されません。その結果、黒画面のままトラックが表示に残り続けます。

そのため、アプリケーション側で切断したコネクションのトラックが表示に残らないように対処してください。削除のタイミングと方法はアプリケーションの設計に合わせてください。例えば、相手の切断時に connection.destroyed 通知を受けて該当するコネクションのトラックを削除する方法があります。

また、自分側から切断した場合は、 SDK が全リモート映像トラックを破棄し、 SoraRemoveTrackEvent が通知されます。

Sora Flutter SDK の DevTools では、 connection.destroyed 通知で切断したコネクションのトラックを削除しています。実装は devtools をご確認ください。

特定の解像度が利用できません

Android / iOS / macOS デバイスのハードウェアアクセラレーターの問題で、指定した解像度を利用できないことがあります。

エンコーダー/デコーダーの初期化時に例外が発生したり、 エンコード/デコード処理が失敗して映像が正常に送受信されないケースがある場合があります。

自分の接続のコネクション ID を取得することはできますか?

できます。 SoraConnection の connectionId プロパティで取得できます。 connectionId はサーバーから offer を受信したタイミングで更新されます。接続前や offer が未到達のときは null です。

conn.events.listen((event) {
  if (event case SoraConnectionStateChangedEvent(state: SoraConnectedState())) {
    // 接続後にコネクション ID を取得する
    print('connection_id: ${conn.connectionId}');
  }
});

受信したストリームと Sora のコネクション ID を紐づける方法はありますか?

conn.events の SoraTrackEvent から受信したトラック ( RemoteMediaStreamTrack ) が通知されます。 RemoteMediaStreamTrack の connectionId フィールドに、そのストリームを配信しているクライアントのコネクション ID が設定されています。

conn.events.listen((event) {
  if (event case SoraTrackEvent(:final track)) {
    // track.connectionId で配信元のコネクション ID を取得できる
    print('track: ${track.trackId}, connection_id: ${track.connectionId}');
  }
});

受信したストリーム毎に音量を変更する方法はありますか?

Sora Flutter SDK の公開 API では、リモート音声ごとの再生音量変更はできません。 受信音声は SDK とプラットフォームの標準経路で再生され、出力のルーティングは OS と libwebrtc の挙動に従います。

詳細は 音声の送受信 をご確認ください。

音声のステレオ送受信に対応していますか?

音声の送信、受信ともに対応していません。ただし、Sora の実験的機能である Opus の詳細パラメータで stereo / sprop_stereo を指定することでステレオを利用できます。利用する場合は、事前に Sora のサポートへ連絡してください。詳細は シグナリング設定 をご確認ください。

Sora の TURN 機能を無効にして利用できますか?

できません。

Sora Flutter SDK は Sora を turn = false に設定して利用することはできません。

接続/切断処理を連続して実行しても安全ですか?

Sora Flutter SDK では connect() 呼び出し時に既存の接続を自動で切断し、 disconnect() も内部で直列化されています。 そのため、ユーザーが接続/切断ボタンを連続してタップした場合でも、SDK 側で処理の衝突は防がれます。

ただし、意図しないタイミングでの切断や再接続を避けるため、UI 側でのボタン連打抑止の実装を推奨します。

Sora への切断後に同じ SoraConnection インスタンスで再接続できますか?

できます。 disconnect() を呼んだあと、同じインスタンスで再度 connect() を呼ぶことができます。 完全に使い終わった場合は、 disconnect() の後に dispose() を呼んでリソースを破棄してください。

接続に失敗した場合のタイムアウト時間を変更できますか?

できます。 SoraConnectionConfig の timeoutOptions で SoraTimeoutOptions を指定してください。

  • connectionTimeout: WebSocket 接続から PeerConnection 接続完了まで (デフォルト: 30 秒)
  • disconnectWaitTimeout: disconnect() のリソース解放待機 (デフォルト: 10 秒)
  • signalingCandidateTimeout: WebSocket 接続確立時間 (デフォルト: 5 秒)

詳細は タイムアウト機能 をご確認ください。

音声・映像の送信をミュートで無効化できますか?

setAudioEnabled(false) や setVideoEnabled(false) で音声・映像トラックの送信を無効化できます。 ただし、これらの API はトラックの enabled を切り替えるものであり、マイクやカメラのハードウェア自体を停止するわけではありません。 そのため、端末のプライバシーインジケーター (ランプ) の消灯は保証しません。

詳細は メディアデバイス をご確認ください。

受信した音声の音量が小さいです ( iOS / iPadOS )

iOS / iPadOS では AVAudioSession の category が .playAndRecord に設定されるため、受信音量が小さくなる場合があります。 これは iOS の仕様です。必要に応じて接続後に AVAudioSession の category を変更してください。

自己署名証明書は利用できますか?

できません。優先実装にて対応可能です。

音声の再生先 (スピーカー) を選択できますか?

Sora Flutter SDK の公開 API では、再生先スピーカーの明示的な切り替えはできません。 音声の再生先は、基本的に各プラットフォームの標準ルーティングに従います。

  • Android: Android / libwebrtc の音声ルーティングに従います
  • iOS / iPadOS: AVAudioSession の音声ルートに従います。 AirPlay や Bluetooth などの再生先をユーザーに選ばせる場合は、アプリケーション側で AVRoutePickerView を利用してください
  • macOS: OS / CoreAudio の既定音声出力へ再生されます

現在利用可能な音声出力デバイスの一覧は MediaDevices.enumerateAudioOutputDevices() で取得できます。

詳細は 音声の送受信 をご確認ください。

リアルタイムメッセージング機能

いつ sendDataChannelMessage() を呼べばよいですか?

connect() 呼び出し後、 SoraDataChannelOpenEvent で対象 label の open を確認してから送ってください。DataChannel が未確立のまま送ると、内部実装上は該当 channel が見つからず送信されません。

import 'dart:convert';
import 'dart:typed_data';

conn.events.listen((event) {
  if (event is SoraDataChannelOpenEvent &&
      event.event.label == '#messaging') {
    conn.sendDataChannelMessage(
      '#messaging',
      Uint8List.fromList(utf8.encode('ready')),
    );
  }
});

compress: true のとき、アプリケーション側で圧縮や展開は必要ですか?

不要です。

送信時は SDK が compress 設定に従って sendDataChannelMessage() の payload を圧縮し、受信時は SDK が展開したうえで SoraDataChannelMessageEvent に渡します。

サポート

Sora Flutter SDK の有償サポートは提供していますか?

Sora Flutter SDK の有償サポートは提供しておりません。

質問やバグ報告はどこで行えますか?

Sora Flutter SDK についての質問やバグ報告は Discord の #sora-sdk-faq チャンネルにお願いします。

https://discord.gg/shiguredo

ただし、 Sora のライセンス契約の有無に関わらず、応答時間と問題の解決を保証しませんのでご了承ください。

質問やバグ報告にあたり、どのような情報を記載すればよいですか?

次の開発環境のバージョンを「メジャーバージョン、マイナーバージョン、メンテナンスバージョン」まで含めて記載してください。

  • 利用している Sora のバージョン
  • 利用している Sora Flutter SDK のバージョン
  • 利用している Flutter SDK のバージョン
  • 利用している Dart のバージョン
  • 動作させている OS とそのバージョン ( iOS / Android / macOS / Windows など)
  • 動作させているデバイスのモデル名 ( Android や iOS 端末の場合)
  • 開発環境のバージョン ( Android Studio / Xcode など)

リリース

リリースサイクルを教えてください

Sora のメジャーバージョンアップ後に、 Sora へ追従を目的としたバージョンアップを行います。

ただし、具体的なリリースサイクルはありません。