Sora Android SDK ドキュメント

このドキュメントは Sora Android SDK バージョン 2025.2.0 に対応しています。

Sora 自体の製品お問い合わせは sora at shiguredo dot jp までお願い致します。 (このメールアドレスへの特定電子メールの送信を拒否いたします)

問い合わせについて

Sora Android SDK の質問などについては Discord の #sora-sdk-faq をご利用ください。 ただし、 Sora のライセンス契約の有無に関わらず、応答時間と問題の解決を保証しませんのでご了承ください。

https://discord.gg/shiguredo

Sora Android SDK に対する有償のサポートについては提供しておりません。

重要なお知らせ

Sora Android SDK 2025.2.0 リリースについて

Sora Android SDK 2025.2.0 のリリースには多くの破壊的変更が含まれています。

移行が必要な条件や、移行方法について 2025.1.x から 2025.2.x への移行 を参照して対応をお願いします。

目次:

Sora Android SDK 概要

Sora Android SDK は 株式会社時雨堂WebRTC SFU Sora の Android 専用クライアントフレームワークです。

WebRTC の複雑な接続処理を肩代わりする API を提供し、 Sora を利用する Android アプリケーションを最小限のソースコードで実装できます。

主な仕様・特徴
ピア接続処理

Sora と接続してメディアチャネルの通信を確立します。

メディアデータの送受信

Sora との間に送受信されるメディアデータ (映像と音声) を送信・受信するための MediaStream を提供します。

カメラ用のユーティリティ

Android 端末のカメラを簡単に利用できるユーティリティを提供します。

ソースコード
サンプルソースコード
問い合わせについて

Sora Android SDK の質問などについては Discord の #sora-sdk-faq チャンネルにお願いします。 ただし、 Sora のライセンス契約の有無に関わらず、応答時間と問題の解決を保証しませんのでご了承ください。

https://discord.gg/shiguredo

またビルドやパッケージングに関する質問に対しては、コミュニティ管理者は回答は行いません。

リリースノート

CHANGE

後方互換性のない変更

UPDATE

後方互換性がある変更

ADD

後方互換性がある追加

FIX

バグ修正

2025.2.0
日時:

2025-09-17

対応 Sora:

2025.1.0 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m138.7204.0.5

ハイライト
  • SoraMediaChannel.Listener に、Sora から切断された際のステータスコードと理由を取得できる onClose(SoraMediaChannel, SoraCloseEvent) を追加しました

破壊的変更
非推奨情報
変更履歴
  • [CHANGE] CameraCapturerFactory 初期化時の引数 fixedResolution を廃止しました

    • これまでは CameraCapturerFactory.create の引数 fixedResolution に true を指定することにより送信する映像の解像度維持をすることができていましたが、この仕様を廃止しました。

    • 代替の機能として、SoraMediaOption.degradationPreference を追加しました

  • [CHANGE] connect メッセージの multistream を自動で true に設定する仕様を廃止しました

    • SoraMediaOption.enableSpotlight を設定すると、内部で multistream を true に設定していましたが、この仕様を廃止しました

    • 以下の設定の組み合わに応じて自動で multistream を true に設定していましたが、この仕様を廃止しました

      • enableAudioDownstream

      • enableVideoDownstream

      • enableAudioUpstream

      • enableVideoUpstream

  • [CHANGE] SignalingChannelImplWebSocketListener.onClosed の処理において、WebSocket のステータスコードが 1000 以外の場合でも onError を呼び出さないように変更しました

    • これまでの実装では、onError のコールバック呼び出しが定義されていましたが、実際には onClosing が実行された時点で SignalingChannelImpl の listener の参照が削除されるため、onError が確実に呼び出される保証はありませんでした

    • 今回の変更により、onClose においてステータスコードと切断理由を取得できるようになりエラーハンドリングが可能となったため、onError の呼び出しは不要となりました

    • これにより、onError はネットワーク切断などによる異常終了のみを通知する仕様となります

    • もし、ステータスコード 1000 以外の Sora からの切断を onError によって検知する実装を行っていた場合、今後は onClose のステータスコードを参照し、適切な処理を行う必要があります

  • [CHANGE] SoraMediaOption.videoCodec が未設定の場合の動作変更

    • これまでは、SoraMediaOption.videoCodec が未設定の場合、connect メッセージの video.codec_type にデフォルトで VP9 が設定され、送信されていました

    • 今回の変更により、未設定の場合は video.codec_type を送信しなくなりました

    • 未設定の場合、Sora 側でデフォルトのビデオコーデックとして VP9 が設定されます

    • SoraMediaOption.videoCodec が未設定であり、かつ SoraMediaOption.videoVp9Params を設定している場合は破壊的変更の影響を受けるため、明示的に SoraMediaOption.videoCodecSoraVideoOption.Codec.VP9 を設定する必要があります

  • [CHANGE] SoraMediaOption.audioCodec が未設定の場合の動作変更

    • これまでは SoraMediaOption.audioCodec が未設定の場合、connect メッセージの audio.codec_type にデフォルトで OPUS が設定され、送信されていました

    • 今回の変更により、未設定の場合は audio.codec_type を送信しなくなりました

    • 未設定の場合、Sora 側でデフォルトのオーディオコーデックとして OPUS が設定されます

    • SoraMediaOption.audioCodec が未設定であり、かつ SoraMediaOption.audioOption.opusParams を設定している場合は破壊的変更の影響を受けるため、明示的に SoraMediaOption.audioCodecSoraAudioOption.Codec.OPUS を設定する必要があります

  • [CHANGE] SoraMediaChannel.ListeneronError(SoraMediaChannel, SoraErrorReason) を廃止しました

    • onError(SoraMediaChannel, SoraErrorReason) を呼び出していた箇所は onError(SoraMediaChannel, SoraErrorReason, String) に置き換えられます

    • String にはエラーの詳細情報が渡されます

      • 詳細がない場合は空文字列が渡されます

  • [UPDATE] libwebrtc を 138.7204.0.5 にアップデートしました

  • [UPDATE] Sora 2025.1.0 でのレガシーストリーム廃止に伴い不要となる設定を非推奨に変更しました

    • Sora 2025.1.0 以降は connect メッセージの multistream 項目が廃止されました

    • これに合わせ、SDK でも multistream を自動で true に設定する挙動を廃止しました(関連: シグナリング の "type": "connect" メッセージの multistream を自動で true に設定する仕様を廃止

    • 非推奨にした設定

      • SoraMediaOption.enableMultistream: これまで multistream: true を明示するための設定でしたが、Sora 2025.1.0 以降は非推奨です

      • SoraMediaOption.enableLegacyStream: これまで ``multistream: false``(レガシーストリーム)を明示するための互換設定でしたが、レガシーストリーム自体が廃止されたため非推奨です

  • [UPDATE] SoraMediaChannel.Listener に、Sora から切断された際のステータスコードと理由を取得できる onClose(SoraMediaChannel, SoraCloseEvent) を追加しました

    • Sora から切断された際に通知されるイベントである SoraCloseEvent を追加しました

    • WebSocket シグナリング切断時に通知されるイベントである SignalingChannelCloseEvent を追加しました

    • 以下の場合に、Sora から切断された際に SoraCloseEvent が通知されます:

      • SoraMediaChannel.disconnect() を呼び出した場合

      • WebSocket 経由のシグナリングを利用している場合

      • DataChannel 経由のシグナリングを利用する場合、かつ ignore_disconnect_websocket が true であり、かつ Sora の設定で data_channel_signaling_close_message が有効な場合

  • [UPDATE] SoraMediaChannel.ListeneronClose(SoraMediaChannel) を非推奨にしました

    • 今後は onClose(SoraMediaChannel, SoraCloseEvent) を利用してください

  • [UPDATE] compileSdk と targetSdkVersion を 36 にアップデートしました

  • [UPDATE] Android Gradle Plugin (AGP) を 8.10.1 にアップデートしました

  • [UPDATE] Gradle を 8.11.1 にアップデートしました

  • [UPDATE] 依存ライブラリーのバージョンをアップデートしました

    • org.jetbrains.dokka:dokka-gradle-plugin を 1.9.20 にアップデートしました

    • com.google.code.gson:gson を 2.13.1 にアップデートしました

    • org.ajoberstar.grgit:grgit-gradle を 5.3.2 にアップデートしました

    • org.jetbrains.kotlinx:kotlinx-coroutines-android を 1.9.0 にアップデートしました

    • org.robolectric:robolectric を 4.15.1 にアップデートしました

  • [ADD] SoraMediaOptiondegradationPreference を追加しました

    • クライアント側の状況により設定した解像度やフレームレートを維持できなくなった場合にどのように質を下げるか制御できるオプションです

    • オプション追加前よりデフォルトの挙動で動作していたため互換性に影響はありません

  • [ADD] サイマルキャストの映像におけるエンコーディングパラメーター scaleResolutionDownTo を追加しました

  • [ADD] Sora から DataChannel シグナリングを切断する際に "type": "close" メッセージを受信する機能を追加する

    • DataChannel シグナリングが有効、かつ ignore_disconnect_websocket が true、かつ Sora の設定で data_channel_signaling_close_message が有効な場合に受信可能です

    • 受信したメッセージは SoraCloseEvent として onClose(SoraMediaChannel, SoraCloseEvent?) に通知されます

  • [ADD] SoraMediaOptionsoftwareVideoEncoderOnly を追加しました

    • 映像配信時に端末のハードウェアエンコーダーを使わず、ソフトウェアエンコーダーのみで送信するためのオプションです

    • デフォルトは false であるため互換性に影響はありません

    • true の場合、サイマルキャスト有効時を含めソフトウェアエンコーダーのみでエンコードするようになります

    • 映像の配信が有効な場合に適用されるため、視聴のみの場合は影響ありません

    • videoEncoderFactory を設定している場合は本オプションは無視されます

    • ソフトウェアエンコードは CPU 使用率・発熱・電力消費が増える可能性がありますので注意してください

  • [FIX] SoraMediaChannel.internalDisconnect における SoraMediaChannel.Listener.onClose の呼び出しタイミングを、切断処理の完了後に修正しました

    • 従来は切断処理の完了前に onClose が呼び出されていましたが、 onClose は切断後に通知されるのが望ましいため、切断完了後に呼び出されるよう修正しました

2025.1.1
日時:

2025-08-07

対応 Sora:

2024.2.0 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m132.6834.5.0

  • [FIX] Sora の設定が、DataChannel 経由のシグナリングの設定、かつ、WebSocket の切断を Sora への接続が切断したと判断しない設定の場合に、SDP 再交換に失敗することがある問題を修正しました

    • WebSocket 経由から DataChannel 経由へのシグナリング切替時に type: switchedtype: re-offer をほぼ同時に受信した際、type: re-answer を WebSocket 経由で送信する前に WebSocket を切断してしまい type: re-answer の送信に失敗することがあるためです

    • DataChannel 経由へのシグナリング切替後でも、まだ WebSocket 経由で送信中のメッセージが存在する可能性を考慮し、余裕を持って切断するために 10 秒の待機時間を設けるようにしました

2025.1.0
日時:

2025-01-27

対応 Sora:

2024.2.0 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m132.6834.5.0

  • [UPDATE] libwebrtc を 132.6834.5.0 にアップデートしました

  • [UPDATE] SoraForwardingFilterOption 型の引数を Sora での 2025 年 12 月の廃止に向けて非推奨にしました

  • [UPDATE] OfferMessage に以下の項目を追加しました

    • version

    • simulcastMulticodec

    • spotlight

    • channelId

    • sessionId

    • audio

    • audioCodecType

    • audioBitRate

    • video

    • videoCodecType

    • videoBitRate

  • [UPDATE] NotificationMessage に以下の項目を追加しました

    • timestamp

    • spotlightNumber

    • failedConnectionId

    • currentState

    • previousState

  • [ADD] 転送フィルター機能の設定を表すクラス SoraForwardingFilterOptionnamepriority を追加しました

  • [ADD] 転送フィルターをリスト形式で指定するためのプロパティを追加しました

  • [FIX] SoraMediaChannel の signalingMetadatasignalingNotifyMetadata の Map オブジェクトに value が null のフィールドを設定した場合、そのフィールドが connect メッセージに含まれない問題を修正しました

    • signalingMetadatasignalingNotifyMetadata に設定する情報はユーザが任意に設定する項目であり value 値が null の情報も送信できるようにする必要がありましたが Gson は JSON シリアライズ時にデフォルトで null フィールドを無視するため、null を持つフィールドは省略されていました

    • 今後は value 値が null の情報も送信されます。値を送信したくない場合は Map オブジェクトに含めないようにしてください

2024.3.0, 2024.3.1
日時:

2024-08-30

対応 Sora:

2024.1.0 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m127.6533.1.1

  • [UPDATE] libwebrtc を m127.6533.1.1 にアップデートしました

  • [UPDATE] Android Gradle Plugin (AGP) を 8.5.0 にアップデートしました

  • [UPDATE] Gradle を 8.7 にアップデートしました

  • [UPDATE] Kotlin のバージョンを 1.9.25 にアップデートしました

  • [UPDATE] 依存ライブラリーのバージョンをアップデートしました

    • com.google.code.gson:gson を 2.11.0 にアップデートしました

    • com.squareup.okhttp3:okhttp を 4.12.0 にアップデートしました

    • org.jetbrains.kotlinx:kotlinx-coroutines-android を 1.8.1 にアップデートしました

    • androidx.test:core を 1.6.1 にアップデートしました

    • org.robolectric:robolectric を 4.13 にアップデートしました

  • [FIX] Offer メッセージの encodings 内 maxFramerate の値が整数でない値であった場合にエラーとなる問題を修正

    • Offer メッセージでは W3C の定義に合わせて maxFramerate を Double で定義していますが、 libwebrtc では Integer で定義されているため、 Offer メッセージに設定された maxFramerate を int にキャストして設定するように修正しました

  • [FIX] Offer メッセージでサイマルキャスト有効を指定した場合にサイマルキャストが有効にならない問題を修正しました

2024.2.0
日時:

2024-04-23

対応 Sora:

2023.2.0 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m122.6261.1.0

  • [UPDATE] libwebrtc を m122.6261.1.0 にアップデートしました

    • libwebrtc の AV1 デコード機能の脆弱性対応が含まれています

2024.1.0, 2024.1.1
日時:

2024-03-19

対応 Sora:

2023.2.0 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m121.6167.4.0

  • [CHANGE] NotificationMessagemetadata_list を削除しました

    • 2022.1.0 の Sora で metadata_list が廃止されたためあわせて廃止します

    • metadata_listdata に名称が変更されています

  • [CHANGE] NotificationMessagechannel_id を削除しました

    • 未使用項目であり、値が設定されない項目のため削除しました

  • [UPDATE] 転送フィルターの項目追加に対応しました

    • version が指定できるようになりました

    • metadata が指定できるようになりました

  • [UPDATE] 解像度に qHD (960x540, 540x960) を追加しました

  • [UPDATE] システム条件を更新しました

    • Android Studio 2023.2.1 以降

    • WebRTC SFU Sora 2023.2.0 以降

  • [UPDATE] libwebrtc を m121.6167.4.0 にアップデートしました

  • [ADD] 映像コーデックに H265 を追加しました

  • [FIX] connect メッセージに設定するバージョンの取得方法を変更しました

    • 開発中のブランチでの出力値が意図せぬ結果になるため修正しました

    • リリースされた Sora Android SDK を利用している場合、この問題は発生しません

  • [FIX] ForwardingFilteraction を未指定にできるようにしました

  • [FIX] NotificationMessage に項目を追加しました

    • session_id

    • kind

    • destination_connection_id

    • source_connection_id

    • recv_connection_id

    • send_connection_id

    • stream_id

2023.2.0
日時:

2023-08-29

対応 Sora:

2023.1.0 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m115.5790.8.0

  • [UPDATE] システム条件を更新しました

    • Android Studio 2022.2.1 以降

    • WebRTC SFU Sora 2023.1.0 以降

  • [UPDATE] libwebrtc を 115.5790.8.0 にアップデートしました

  • [ADD] 転送フィルター機能を追加しました

  • [ADD] scalability mode に対応しました

    • VP9 / AV1 のサイマルキャストに対応可能になりました

  • [ADD] 映像コーデックパラメータを追加しました

2023.1.0
日時:

2023-04-05

対応 Sora:

2022.2.0 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m112.5615.1.0

  • [CHANGE] type: offer の mid を必須とする修正をしました

    • この修正の結果、 type: offer に mid が含まれない場合は、エラーになります

    • 最新の Sora をご利用であれば問題は発生しません

  • [UPDATE] システム条件を更新しました

    • Android Studio 2021.3.1 以降

    • WebRTC SFU Sora 2022.2.2 以降

  • [UPDATE] Gradle を 7.6.1 にアップデートしました

  • [UPDATE] 依存ライブラリーのバージョンをアップデートしました

    • org.jetbrains.dokka:dokka-gradle-plugin を 1.8.10 にアップデートしました

    • com.android.tools.build:gradle を 7.4.2 にアップデートしました

    • com.github.ben-manes:gradle-versions-plugin を 0.46.0 にアップデートしました

    • org.jlleitschuh.gradle:ktlint-gradle を 11.3.1 にアップデートしました

    • com.google.code.gson:gson を 2.10.1 にアップデートしました

    • androidx.test:core を 1.5.0 にアップデートしました

    • org.robolectric:robolectric: を 4.9.2 にアップデートしました

  • [UPDATE] libwebrtc を 112.5615.1.0 にアップデートしました

  • [UPDATE] 映像コーデックに AV1 を追加しました

  • [ADD] SoraMediaOptionaudioStreamingLanguageCode を追加しました

  • [FIX] テストコード内に廃止された role が残っていたため修正しました

  • [FIX] PeerConnection.ContinualGatheringPolicy.GATHER_CONTINUALLY の設定を行なっていましたが Sora がネットワーク変更に対応しておらず不要な設定であるため削除しました

2022.4.0
日時:

2022-09-16

対応 Sora:

2022.1.1 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m105.5195.0.0

  • [CHANGE] type: offer の mid を必須とする修正をしました

    • この修正の結果、 type: offer に mid が含まれない場合は、エラーになります

    • 最新の Sora をご利用であれば問題は発生しません

  • [UPDATE] libwebrtc を 105.5195.0.0 にアップデートしました

  • [UPDATE] compileSdkVersion を 32 にアップデートしました

  • [UPDATE] targetSdkVersion を 32 にアップデートしました

  • [UPDATE] Kotlin のバージョンを 1.7.10 にアップデートしました

  • [UPDATE] Gradle を 7.5.1 にアップデートしました

  • [UPDATE] 依存ライブラリーのバージョンをアップデートしました

    • com.android.tools.build:gradle を 7.2.2 にアップデートしました

    • org.jetbrains.kotlin:kotlin-gradle-plugin を 1.7.10 にアップデートしました

    • org.ajoberstar.grgit:grgit-gradle を 5.0.0 にアップデートしました

    • org.jetbrains.dokka:dokka-gradle-plugin を 1.7.10 にアップデートしました

    • com.github.ben-manes:gradle-versions-plugin を 0.42.0 にアップデートしました

    • org.jlleitschuh.gradle:ktlint-gradle を 10.3.0 にアップデートしました

    • com.pinterest:ktlint を 0.45.2 にアップデートしました

    • com.google.code.gson:gson を 2.9.1 にアップデートしました

    • com.squareup.okhttp3:okhttp を 4.10.0 にアップデートしました

    • org.jetbrains.kotlinx:kotlinx-coroutines-android を 1.6.4 にアップデートしました

    • org.robolectric:robolectric を 4.8.1 にアップデートしました

  • [FIX] mid を nullable に変更しました

    • develop で開発中に発生した不具合であり、リリース済みの Android SDK でこの問題は発生しません

    • 「type: offer の mid を必須にする」の対応で role が recvonly の時にエラーとなる不具合の修正です

  • [FIX] offer で受信した encodings が反映されない不具合を修正しました

    • develop で開発中に発生した不具合であり、リリース済みの Android SDK でこの問題は発生しません

  • [FIX] EGLContext が取れなかった場合、DefaultVideoDecoderFactory, SoraDefaultVideoEncoderFactory を使用するよう修正しました

    • EGLContext が取れなかった場合の Decoder を SoftwareVideoDecoderFactory から DefaultVideoDecoderFactory に変更しました

    • EGLContext が取れなかった場合の Encoder を SoftwareVideoEncoderFactory から SoraDefaultVideoEncoderFactory に変更しました

    • EGLContext は null でも Hardware を使用する MediaCodec は動作するため Hardware も動作可能な DefaultVideoDecoderFactory, SoraDefaultVideoEncoderFactory に変更する対応です

2022.3.0
日時:

2022-06-29

対応 Sora:

2022.1.0 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m103.5060.4.0

  • [CHANGE] SoraMediaOptionhardwareVideoEncoderResolutionAdjustment を追加しました

    • HW エンコーダーに入力されるフレームの解像度が指定されたピクセル数の倍数になるように調整します。デフォルト値は 16 です。このオプションを実装した経緯は解像度が 16 の倍数でない場合、 HW エンコーダーの初期化がエラーになる変更が libwebrtc のメインストリームに入ったことによります。

    • Sora Android SDK では libwebrtc にパッチを当て、上記の HW エンコーダー初期化時の解像度のチェックを無効化しています。そのため、このフラグを SoraVideoOption.ResolutionAdjustment.NONE に設定することで、従来通り、解像度を調整することなく HW エンコーダーを利用できます。

    • 加えて、解像度調整ありでエンコーダーの初期化またはエンコード処理に失敗した際に、解像度調整なしで操作をリトライする処理を追加しています。

      • Android OS 11 の Xperia 5 II で VGA のサイマルキャストを H.264 で送信しようとした際、解像度調整ありの場合は HW エンコーダーの初期化が失敗するが、解像度調整なしの場合は成功する現象を確認したためです。

  • [UPDATE] SoraMediaOption.enableSpotlight() の引数に enableSimulcast を追加し、サイマルキャスト無効の状態でスポットライト機能を利用できるようにしました

  • [UPDATE] libwebrtc を 103.5060.4.0 にアップデートしました

  • [UPDATE] 依存ライブラリー org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9 を追加しました

  • [UPDATE] システム条件を Android Studio 2021.2.1 にアップデートしました

  • [ADD] SoraMediaChannelproxy を追加し、接続時に HTTP プロキシの設定を追加できるようにしました

  • [ADD] SoraMediaChannelbundleId を追加しました

2022.2.0
日時:

2022-04-04

対応 Sora:

2021.2.1 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m96.4664.2.1

  • [CHANGE] Sora で廃止となった以下のフィールドを削除しました

    • NotificationMessage.numberOfUpstreamConnections

    • NotificationMessage.numberOfDownstreamConnections

    • ChannelAttendeesCount.numberOfUpstreams

    • ChannelAttendeesCount.numberOfDownstreams

  • [UPDATE] SoraMediaChannelcontactSignalingEndpoint を追加しました

    • 最初に type: connect を送信したエンドポイントが設定されます

  • [UPDATE] SoraMediaOptionrole を追加しました

  • [ADD] メッセージング機能に対応しました

  • [FIX] SoraMediaChannel.ListeneronOfferMessage を追加しました

    • type: offer に含まれる metadata などにアクセスできるよう修正しました

2022.1.0
日時:

2022-01-12

対応 Sora:

2021.2.0 以降

対応 Android:

5.0 以降

対応 libwebrtc:

m96.4664.2.1

  • [CHANGE] スポットライトレガシー機能を廃止しました

  • [UPDATE] libwebrtc を 96.4664.2.1 アップデートしました

  • [UPDATE] dokka を 1.5.31 にアップデートしました

  • [ADD] 複数シグナリング URL が指定できるようになりました

  • [ADD] redirect メッセージに対応しました

  • [ADD] type: disconnect に reason を追加しました

  • [FIX] 視聴のみかつ H.264 した場合に接続できない問題についてのワークアラウンドを削除しました

    • SoraMediaOption.videoUpstreamContext が無く SoraMediaOption.videoDownstreamContext がある場合はコーデック指定に依らず、 DefaultVideoEncoderFactory を使用するように変更しています

  • [FIX] libwebrtc のアップデート後に発生するようになったサイマルキャストのクラッシュを修正しました

    • SimulcastVideoEncoderFactoryWrapper.kt の Fallback クラスが原因で java.lang.UnsupportedOperationException が発生していました

    • 調査の結果、 Fallback クラスを削除できることがわかったため、その方向で修正をしました

    • libwebrtc に適用している Android のサイマルキャスト対応のパッチを更新し、 SimulcastVideoEncoderFactory の fallback に null を指定できるように修正しました

既知の問題

正常に動作しない場合がある端末
Samsung A41 SCV 48
  • H.264 / H.265 で 120p の映像を送信しようとするとクラッシュする

OUTKITEL 13P
HUAWEI Mate 20 Pro
非対応エンコーディングパラメーター

Sora Android SDK はサイマルキャストやマルチストリームで利用できるエンコーディングパラメーター adaptivePtime に対応していません。

優先実装にて対応可能です。

FAQ

一般
Sora Android SDK のライセンスはなんですか?

Apache License, Version 2.0 です。

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

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

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

あります。 https://github.com/shiguredo/sora-android-sdk-samples をご確認ください。

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

Sora Android SDK は以下の音声コーデックに対応しています。

  • Opus

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

Sora Android SDK は以下の映像コーデックに対応しています。

  • VP8

  • VP9

  • AV1

  • H.264

  • H.265

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

あります。 H.264 または H.265 を利用するには Android デバイスがハードウェアアクセラレーターを搭載している必要があります。

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

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

  • Android デバイスが利用したいコーデックのハードウェアアクセラレーターを搭載していること

  • SDK が利用したいコーデックのハードウェアアクセラレーターに対応していること

Android デバイスが対応している映像コーデックを確認する方法はありますか?

HardwareVideoEncoderFactory または HardwareVideoDecoderFactory クラスの getSupportedCodecs メソッドを使って確認できます。 前者のクラスはエンコーダー、後者のクラスはデコーダーの対応しているコーデックの一覧を返します。

以下は Sora Android SDK のサンプルで、対応しているコーデックの一覧をログに出力している例です。

...
// 利用可能なコーデックの一覧
// デコーダー (受信)
RTCComponentFactory     jp.shiguredo.sora.sample             D  decoderFactory supported codec: VP8 {}
RTCComponentFactory     jp.shiguredo.sora.sample             D  decoderFactory supported codec: VP9 {profile-id=0}
...
// エンコーダー (送信)
RTCComponentFactory     jp.shiguredo.sora.sample             D  encoderFactory supported codec: VP8 {}
RTCComponentFactory     jp.shiguredo.sora.sample             D  encoderFactory supported codec: AV1 {}
RTCComponentFactory     jp.shiguredo.sora.sample             D  encoderFactory supported codec: VP9 {profile-id=0}
RTCComponentFactory     jp.shiguredo.sora.sample             D  encoderFactory supported codec: H264 {level-asymmetry-allowed=1, profile-level-id=42e01f, packetization-mode=1}
RTCComponentFactory     jp.shiguredo.sora.sample             D  encoderFactory supported codec: H265 {}
...

getSupportedCodecs は Android の MediaCodec API を利用しています。 Google Play ストアでは MediaCodec API を利用してデバイスのコーデックの一覧を表示するアプリケーションが配布されています。 そのようなアプリケーションを利用することで、詳細な情報を確認することができます。

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

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

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

Tip

160x120 など低めの解像度で問題が起きることが多いです。

注釈

問題が発生した場合は Discord へのフィードバックして頂けると助かります。

正常に動作しない端末一覧は 正常に動作しない場合がある端末 をご確認ください。

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

受信したストリームから Sora のコネクション ID を取得することができます。

SoraMediaChannel のコールバックイベントである onAddRemoteStream() から受信したストリーム( org.webrtc.MediaStream ) が連携されます。 Sora の仕様では org.webrtc.MediaStream の id にはそのストリームを配信しているクライアントのコネクション ID が設定されています。

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

警告

libwebrtc ライブラリの仕様について言及がありますが正確性は保証されません。

SoraMediaChannel のコールバックイベントである onAddRemoteStream() から受信したストリーム( org.webrtc.MediaStream ) が連携されます。 Sora は、1 つの org.webrtc.MediaStream について 1 つの音声トラック( org.webrtc.AudioTrack ) を設定します。 この音声トラックには音量を変更するための API が用意されており、この API を利用することで音量を変更することができます。

// SoraMediaChannel からのコールバックイベントを受け取るリスナー
private val channelListener = object : SoraMediaChannel.Listener {

  // 受信したストリームが追加されたときに呼び出されるコールバック
  override fun onAddRemoteStream(mediaChannel: SoraMediaChannel, ms: MediaStream) {
      // Sora は MediaStream に 1 つの AudioTrack を設定するので 1 つ目の AudioTrack に対して音量を設定する
      // AudioTrack.setVolume() の音量の範囲は double 型で 0.0 から 10.0 までの値が設定できる
      // https://webrtc.googlesource.com/src/+/refs/heads/main/sdk/android/api/org/webrtc/AudioTrack.java
      ms.audioTracks[0].setVolume(3.0)
  }
  // その他のリスナーインタフェースの実装
  ...
}
音声のステレオ送受信に対応していますか?

音声の送信、受信ともに対応していません。

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

できません。

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

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

サポートは提供しておりません。

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

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

https://discord.gg/shiguredo

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

質問やバグ報告にあたり、開発環境のバージョンを「メジャーバージョン、マイナーバージョン、メンテナンスバージョン」まで含めて書いてください。

  • 利用している Sora のバージョン

  • 利用している Sora Android SDK のバージョン

  • Android Studio を動作させている OS とそのバージョン

  • Android Studio のバージョン

  • Android デバイスのモデル名と Android OS のバージョン

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

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

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

2025.1.x から 2025.2.x への移行

Sora Android SDK 2025.1.x から 2025.2.x へのアップデートではいくつかの破壊的変更と SDK としての新機能があります。

このドキュメントでは、それらの変更点と移行方法について説明します。

シグナリング の "type": "connect" メッセージの JSON に multistream 項目をデフォルトでは含めないように変更

2025.1.x まではデフォルトの挙動として multistream: false を connect メッセージに設定していましたが、2025.2.x 以降はデフォルトでは multistream 項目を含めないようにしました。

経緯

Sora は 2025 年 6 月のリリースでレガシーストリームが廃止され、connect メッセージの multistream 項目が廃止されました。

この変更に合わせて Sora Android SDK でも connect メッセージの multistream 項目をデフォルトで送信しない仕様に変更しました。

これに伴い、デフォルトでは multistream を含めない挙動にするために SoraMediaOption の設定に応じて自動的に connect メッセージに multistream: true を設定する仕様も廃止しました。

影響を受けるケース

2025.1.x までは Sora Android SDK のデフォルト挙動は multistream 項目に false を入れて connect メッセージを送信するようになっていたため この挙動に依存している場合は影響を受けます。

移行方法

2025.1.x までのデフォルト挙動と同じように connect メッセージに multistream: false を含ませたい場合は SoraMediaOption.enableLegacyStream() を呼び出してください。

val option = SoraMediaOption().apply {
   // 明示的に multistream を false に設定する
   enableLegacyStream()
}
シグナリング の "type": "connect" メッセージの multistream を自動で true に設定する仕様を廃止

2025.1.x までは SoraMediaOption の設定時に条件に応じて自動的に connect メッセージに multistream: true を設定していましたが、 2025.2.x では本仕様を廃止しました。

廃止の経緯は シグナリング の "type": "connect" メッセージの JSON に multistream 項目をデフォルトでは含めないように変更 の経緯に記載しています。

影響を受けるケース

自動的に multistream: true が設定される仕様に依存していた場合は影響を受ける可能性があります。

2025.1.x までで multistream: true が設定されていた条件:

  • Sora がデフォルトでレガシーストリームを使うように設定されている、かつ SoraMediaOption が以下のいずれかの設定になっている場合

    • enableAudioDownstream() または enableVideoDownstream() を呼び出している、かつ enableAudioUpstream() または enableVideoUpstream() を呼び出している場合

    • enableSpotlight() を呼び出している場合

移行方法

SoraMediaOption.enableMultistream() を使うことで connect メッセージに multistream: true を含めることことができます。

val option = SoraMediaOption().apply {
   // 明示的に multistream を true に設定する
   enableMultistream()
}
WebSocket が Sora から切断された際に受信したステータスコードが 1000 以外の場合でも onError を呼び出さないように変更

2025.1.x までは、WebSocket 切断時のステータスコードが 1000 以外の場合に onError を呼び出していましたが、2025.2.x からは onError を呼び出さないように変更しました。

経緯

WebSocket 切断時のステータスコードが 1000 以外の場合に onError を呼び出す仕様でしたが、実際にはそれ以前に切断処理が実行されており onError を実装している Listener の参照がなくなっているため、onError が呼び出されるケースはほとんどありませんでした。

また、2025.2.x からは onClose で切断時のステータスコードと理由を取得できるようになったため、 ユーザーが Sora から受信したステータスコードと切断理由を用いて、エラーハンドリングを行うことができるようになりました。

これを踏まえ、WebSocket 切断時のステータスコードが 1000 以外の場合に onError を呼び出す必要はないと判断し、 onError を呼び出さないように変更しました。

影響を受けるケース
  • ステータスコード 1000 以外の Sora からの切断を onError によって検知する実装を行っていた場合

移行方法

ステータスコード 1000 以外の Sora からの切断を検知する場合は、 onClose でステータスコードと切断理由を取得してエラーハンドリングを行ってください。

private val channelListener = object : SoraMediaChannel.Listener {

   // onError ではなく onClose でエラーハンドリングを行うようにしてください
   override fun onClose(mediaChannel: SoraMediaChannel, closeEvent: SoraCloseEvent) {
      // 実装例
      // ステータスコード 1000 以外の Sora からの切断はエラーとして扱う
      when {
          closeEvent.code != 1000 -> Log.e(TAG, "onClose: エラーにより Sora から切断されました: $closeEvent")
          else -> Log.d(TAG, "onClose: Sora から正常に切断されました: $closeEvent")
      }
   }
}
SoraMediaOption.videoCodec 未設定時の動作変更

2025.1.x までは SoraMediaOption.videoCodec が未設定の場合、connect メッセージの video.codec_type に自動で VP9 が設定され送信されていましたが、 2025.2.x からは、未設定の場合は video.codec_type を送信しなくなりました。

video.codec_type が未設定の場合、VP9 がデフォルトで設定されます。

詳しくは Sora のドキュメントの ビデオコーデック指定 を参照してください。

影響を受けるケース
  • SoraMediaOption.videoCodec が未設定、かつ SoraMediaOption.videoVp9Params を設定している場合

移行方法

影響を受けるケースに該当する場合は、以下のように SoraMediaOption.videoCodec を明示的に設定することで対処できます。

val option = SoraMediaOption().apply {
   // videoCodec を明示的に設定する
   videoCodec = SoraVideoOption.Codec.VP9

   videoVp9Params = object {
      var profile_id: Int = 0
   }
}
SoraMediaOption.audioCodec 未設定時の動作変更

2025.1.x までは SoraMediaOption.audioCodec が未設定の場合、connect メッセージの audio.codec_type に自動で OPUS が設定され送信されていましたが、 2025.2.x からは、未設定の場合は audio.codec_type を送信しなくなりました。

audio.codec_type が未設定の場合、OPUS がデフォルトで設定されます。

詳しくは Sora のドキュメントの オーディオコーデック指定 を参照してください。

影響を受けるケース
  • SoraMediaOption.audioCodec が未設定、かつ SoraMediaOption.audioOption.opusParams を設定している場合

移行方法

影響を受けるケースに該当する場合は、以下のように SoraMediaOption.audioCodec を明示的に設定することで対処できます。

val option = SoraMediaOption().apply {
   // audioCodec を明示的に設定する
   audioCodec = SoraAudioOption.Codec.OPUS

   audioOption = SoraAudioOption().apply {
      opusParams = OpusParams(
         stereo = true,
         useinbandfec = true,
      )
   }
}
onError(SoraMediaChannel, SoraErrorReason) を廃止

2025.1.x までは、2 種類の onError がそれぞれ異なるタイミングで発火していましたが、 2025.2.x からは onError(SoraMediaChannel, SoraErrorReason) が廃止され、エラー発生時のコールバックは onError(SoraMediaChannel, SoraErrorReason, String) のみとなりました。

これにより、2 種類の onError の実装を行う必要がなくなり、エラーハンドリングの実装が簡素化されます。

onError の詳細は、コールバックドキュメントの onError を参照してください。

移行方法

以下のように両方の onError を実装している場合、2025.2.x からは onError(SoraMediaChannel, SoraErrorReason, String) のみを利用するように修正してください。

private val channelListener = object : SoraMediaChannel.Listener {

   // この onError は廃止となるため、削除してください。
   override fun onError(mediaChannel: SoraMediaChannel, reason: SoraErrorReason) {}

   // この onError を実装してください。
   // 特に message がない場合は空文字列が渡されます
   override fun onError(mediaChannel: SoraMediaChannel, reason: SoraErrorReason, message: String) {
      // エラー処理や切断処理を記述する
   }
}
解像度維持方法の fixedResolution を廃止、 DegradationPreference を追加

2025.1.x までは送信する映像の解像度維持の方法として CameraCapturerFactory.create の引数 fixedResolution に true を指定していましたが、 2025.2.x ではクライアント側の状況により設定した解像度やフレームレートを維持できなくなった場合にどのように質を下げるか制御できるパラメータ DegradationPreferenceSoraMediaOption に追加し、 fixedResolution による解像度維持は廃止しました。

これに伴い fixedResolutionCameraCapturerFactory.create の引数から削除され、また CameraVideoCapturerWrapper クラスは fixedResolution 使用のためのラッパークラスだったため不要となり削除されました。 移行方法の内容に従い、CameraCapturerFactory.create 呼び出し箇所のコードを修正する必要があります。

DegradationPreference の指定は必須ではありません。

移行方法

2025.2.x からは以下のように CameraCapturerFactory.create 呼び出し箇所から fixedResolution に該当する引数を削除してください。

// 実装例
override fun createCapturer(): CameraVideoCapturer? {
   // 移行前(第二引数が fixedResolution)
   return CameraCapturerFactory.create(context, true, frontFacingFirst)

   // 移行後
   return CameraCapturerFactory.create(context, frontFacingFirst)
}

DegradationPreference を使用するには SoraMediaOption のパラメータとして指定します。 指定できる値は以下のようになります

  • MAINTAIN_RESOLUTION: 解像度を維持し、フレームレートを下げる

  • MAINTAIN_FRAMERATE: フレームレートを維持し、解像度を下げる

  • BALANCED: フレームレートと解像度のバランスを取る

  • DISABLED: 品質調整機能を無効化

fun connect() {
   ...
   val mediaOption = SoraMediaOption().apply {
      ...
      // degradationPreference の指定を追加する例
      degradationPreference = SoraVideoOption.DegradationPreference.MAINTAIN_RESOLUTION
      ...
   }
}
Sora からの切断理由を取得できる onClose の追加

注釈

この変更は破壊的変更ではありませんが、移行をおすすめします。

2025.1.x までの onClose では Sora から切断された際の理由を取得できませんでしたが、2025.2.x からは切断理由を取得できる onClose を新たに追加しました。

これにより、Sora から切断された理由が認証エラーなのか、切断 API による切断なのかなどの情報を取得できるようになります。

onClose の詳細は、コールバックドキュメントの onClose を参照してください。

移行方法

旧 onClose を削除して新しい onClose を追加してください。

private val channelListener = object : SoraMediaChannel.Listener {

   // この onClose は削除します。
   override fun onClose(mediaChannel: SoraMediaChannel) {}

   // 新しい onClose を追加します。
   override fun onClose(mediaChannel: SoraMediaChannel, closeEvent: SoraCloseEvent) {
      // 実装例
      // Sora から切断された理由をログに出力する
      when {
          closeEvent.code != 1000 -> Log.e(TAG, "onClose: エラーにより Sora から切断されました: $closeEvent")
          else -> Log.d(TAG, "onClose: Sora から切断されました: $closeEvent")
      }
      // 切断されたときの処理を記述する
   }
}

クイックスタート

この章では、 Sora Android SDK を使った、 シンプルなクイックスタートアプリケーションを実行するまでの流れを紹介します。

  • メディアデータ (映像と音声) の送信と受信

  • 送受信する映像の描画

  • 端末のカメラとマイクの使用

ソースコードは次のリポジトリで配布しています。

用意するもの
  • WebRTC SFU Sora バージョン 2025.1.0 以降

  • Android 5 以降 (シミュレーターは不可)

  • Android Studio バージョン 2025.1.1 以降

Sora については、ここでは次の条件での運用を仮定します。 詳しくは Sora のドキュメントを参照してください。

  • Sora のホスト名: "sora.example.com"

  • 開発者ツール: 有効

  • WebSocket の接続に WebSocket over TLS を使用

  • チャネル ID: sora

以下、アプリケーションのダウンロード、依存ライブラリのダウンロードと配置、 アプリケーションの設定と起動の順に説明します。

Android Studio のセットアップ

Android Studio をダウンロードし、 インストール方法 に従いセットアップしてください。

クイックスタートアプリケーションのダウンロード

クイックスタートアプリケーションのソースコードは sora-android-sdk-quickstart リポジトリで配布しています。 git コマンドでリポジトリをクローンして、利用したいタグをチェックアウトしてください (例: sora-android-sdk-2025.2.0 )

$ git clone https://github.com/shiguredo/sora-android-sdk-quickstart.git
$ cd sora-android-sdk-quickstart
$ git checkout <tag>
SDK への依存設定

本アプリケーションは Sora Android SDK への依存を持ちます。 以下、設定方法を記します。GitHub からクローンしたコードベースには これらの設定は入っているため、あらためての設定は不要です。

JitPack リポジトリの追加

Sora Android SDK は JitPack から取得できます。 そのため、トップレベルの build.gradle で JitPack のリポジトリを追加します。

allprojects {
    repositories {
        jcenter()
        google()
        maven { url 'https://jitpack.io' }  // この行を追加する
    }
}
Sora Android SDK のバージョン設定

同じ build.gradle にて、SDK のバージョンを定義しておきましょう。 <version> は使用する SDK のバージョンを入れてください。最新版は 2025.2.0 です。

buildscript {
    // 中略
    ext.sora_android_sdk_version = '<version>' // この行を追加する
}

この定義は次の implementation 依存の追加で参照しますが、定義を省略して、次の設定に直接値を設定しても構いません。

Sora Android SDK への依存を追加する

次に Sora Android SDK への依存を追加します。 SDK を利用するモジュールのビルド設定ファイル(ここでは quickstart/build.gradle )に 以下の設定を追加します。

dependencies {
    // 中略
    // 以下の 3 行を追加する
    implementation("com.github.shiguredo:sora-android-sdk:${sora_android_sdk_version}@aar") {
        transitive = true
    }
}

以上で SDK を利用するための依存設定は完了です。

補足 transitive を指定しない場合は libwebrtc のバージョンとして 138.7204.0.5 を指定してください。

api "com.github.shiguredo:shiguredo-webrtc-android:${libwebrtc_version}"

警告

libwebrtc のバージョンは Sora Android SDK のバージョンと個別に指定可能ですが、特定バージョンのみで動作を確認しています。 必ず SDK バージョンに対応する libwebrtc のバージョンを指定してください。

アプリケーションの設定

クイックスタートアプリケーションの実行には Sora の URL を設定する必要があります。 Sora の URL を gradle.properties に設定します。

gradle.properties.example を元に gradle.properties を作成します。

$ cp gradle.properties.example gradle.properties

このファイルでは、接続する Sora のシグナリングエンドポイント URL signaling_endpoint を指定します。環境に応じて設定してください。 好みでチャネル ID channel_id の指定も可能です(そのままでも結構です)。

gradle.properties:

# Setting Sora's signaling endpoint and channel_id
signaling_endpoint = wss://sora.example.com/signaling
channel_id         = sora

以上でアプリケーションの設定は完了です。 クローンしたディレクトリを Android Studio で開き、アプリケーションの起動を行ってください。

アプリケーションの起動

Android 端末をマシンに接続します。Sora Android SDK はシミュレーターに対応していません。実機を利用してください。 そして、接続した Android 端末を選択してビルド・実行します (メニュー "Run" > "Run (quickstart)")。

起動したアプリケーションの画面で、 START ボタンをタップすると映像、音声の送受信処理が開始されます。

カメラとマイクの権限許可を取得する

Sora Android SDK で映像の送受信を行うにはカメラ(android.permission.CAMERA) と音声(android.permission.RECORD_AUDIO)の権限許可が必要です。

クイックスタートアプリケーションでは上記の権限を取得するために、接続開始時に Manifest.permission.CAMERAManifest.permission.RECORD_AUDIO の権限をリクエストします。

Sora に接続する

起動したアプリケーションの画面で、 START ボタンをタップすると Sora に接続します。 このとき、「写真と動画の撮影」と「音声の録音」の許可を求めるダイアログが表示されるので許可してください。

接続に成功するとカメラ(利用可能な場合は前面カメラを優先して使用)の映像が表示されます。

接続できなかった場合は Sora のエンドポイント URL やネットワークの状態を確認してください。

このアプリケーションでは、次のパラメータで Sora に接続しています。

双方向でビデオチャットするには、例えば、PC ブラウザから Sora DevTools でマルチストリーム接続 を行うと、クイックスタートアプリケーションに相手側の映像が表示されます。 もちろん、Android 端末をもうひとつ用意して本アプリケーションをインストール、起動しても よいですし、iOS アプリケーションとのビデオチャットも可能です。

参考

シグナリング

概要

WebRTC SFU Sora に SDK を利用して接続する仕組みを シグナリング と呼びます。

WebRTC SFU Sora のシグナリングの仕様については以下をご確認ください。

シグナリングの手順

Sora へのシグナリングは次の手順で行います。

  1. SoraMediaChannel.Listener を準備する

  2. SoraMediaOption を準備する

    • 映像と音声の送受信設定を行います。

    • 映像の送信にはキャプチャラー、映像の送受信には EGL コンテキストが必要です。生成方法について video を参照してください。

  3. SoraMediaChannel を生成し接続する

使用例
// (1) SoraMediaChannel.Listener の準備
private val channelListener = object : SoraMediaChannel.Listener {

  override fun onConnect(mediaChannel: SoraMediaChannel) {
  }
  // その他の Listener インタフェースの実装
}

fun start() {

  // (2) SoraMediaOption の準備
  val option = SoraMediaOption().apply {
    // キャプチャラー(capturer)と EGL コンテキスト(eglBaseContext)は別途作成済みの想定です。
    enableAudioDownstream()
    enableVideoDownstream(egl!!.eglBaseContext)

    enableAudioUpstream()
    enableVideoUpstream(capturer!!, egl!!.eglBaseContext)
  }

  // (3) SoraMediaChannel の作成、接続
  mediaChannel = SoraMediaChannel(
    context           = this,
    signalingEndpoint = "wss://sora.example.com/signaling",
    channelId         = "sora",
    mediaOption       = option,
    listener          = channelListener)

  mediaChannel.connect()
}

fun stop() {
  mediaChannel.disconnect()
}
シグナリング時の主な設定内容
SoraMediaOption の主な設定内容

SoraMediaOption の主な設定内容を次に示します。

DataChannel を利用したリアルタイムメッセージングのみで接続する ケースを除き映像、音声の送受信設定が必要です。

デフォルトの設定はいずれも無効です。

  • enableVideoUpstream()

    • 映像を送信します。引数にキャプチャラーと EGL コンテキストを与えます。

  • enableVideoDownstream()

    • 映像を受信します。引数に EGL コンテキストを与えます。

  • enableAudioUpstream()

    • 音声を送信します。

  • enableAudioDownstream()

    • 音声を受信します。

  • videoCodec

    • 映像コーデックを指定します。デフォルトは VP9 です。

  • videoBitrate

    • 映像ビットレートを指定します。

  • videoVp9Params

  • videoAv1Params

  • videoH264Params

  • audioCodec

    • 音声コーデックを指定します。デフォルトは OPUS です。

  • audioBitrate

    • 音声ビットレートを指定します。

  • enableMultistream()

  • enableSimulcast()

  • enableSpotlight()

  • proxy

  • forwardingFilterOption

  • hardwareVideoEncoderResolutionAdjustment

    • 解像度の縦横のピクセル数が指定した値の整数倍となるように調整します。デフォルトは 16 です。

  • degradationPreference

SoraMediaChannel の主な設定内容

SoraMediaChannel の主な設定内容を次に示します。

以下の項目は必須で設定する項目です。signalingEndpoint, signalingEndpointCandidates についてはいずれかを設定します。listener は必須ではありませんが、通常アプリケーションでは SDK のイベントを受け取る必要があるため必須としています。

  • context

    • android.content.Context を設定してください

  • signalingEndpoint

    • シグナリング URL を指定します。複数指定する場合は signalingEndpointCandidates を使用してください。

  • signalingEndpointCandidates

  • channelId

    • 接続するチャネル ID を指定します。

  • mediaOption

  • listener

オプションで以下を設定することが可能です。利用する機能に応じて設定を行います。

  • dataChannelSignaling

  • dataChannels

  • signalingMetadata

    • 認証時に Sora に送信する任意のメタデータを指定します。詳細は 認証メタデータの送信 を参照してください。

  • signalingNotifyMetadata

  • clientId

    • 接続時に任意に指定可能な ID を指定します。

  • bundleId

    • マルチストリーム利用時、同一の bundle_id が設定されている別の接続からの音声や映像、リアルタイムメッセージングを受信しなくなります。

role の自動設定について

映像または音声の送受信の設定により Sora 接続時のロールが自動的に判定されます。 ロールについては Sora ドキュメントの ロール の項も参考にしてください。

  • 送信と受信両方の設定が行われている

    • SoraChannelRole.SENDRECV

  • 送信のみの設定が行われている

    • SoraChannelRole.SENDONLY

  • 受信のみの設定が行われている

    • SoraChannelRole.RECVONLY

// 以下は映像と音声の送受信を設定しているので Sora 接続時のロールは SoraChannelRole.SENDRECV となります。
val option = SoraMediaOption().apply {

  enableVideoUpstream(capturer, egl.eglBaseContext)
  enableAudioUpstream()
  enableVideoDownstream()
  enableAudioDownstream()
}
認証メタデータの送信

Sora との接続時に認証に利用するメタデータを送信することができます。

シグナリング接続時に送信する metadata については Sora ドキュメントの 認証メタデータ をご確認ください。

Sora Android SDK では metadata を、 SoraMediaChannelsignalingMetadata に値を設定します。 JSON 形式に変換可能なデータを設定してください。設定したデータは Gson により変換されます。

// 接続して映像を送受信します
// signalingMetadata, signalingNotifyMetadata には JSON 形式に変換可能なデータを設定します
val mediaChannel = SoraMediaChannel(
              context                     = this,
              signalingEndpoint           = "wss://example.com/signaling",
              channelId                   = "sora",
              signalingMetadata           = mapOf("spam" to "egg"),
              mediaOption                 = option,
              listener                    = channelListener)

mediaChannel.connect()
認証サーバーから払い出されたメタデータの取得

認証サーバから払い出されたメタデータを取得することができます。

認証サーバーから払い出された metadata については Sora ドキュメントの "type": "offer" の項を参照してください。

Sora Android SDK では offer メッセージの受信が、 SoraMediaChannel.ListeneronOfferMessage で通知されます。

認証サーバから払い出されたメタデータは OfferMessage の metadata に格納されます。

// 接続通知を受信するための Listener を宣言します。
private val channelListener = object : SoraMediaChannel.Listener {

  // Sora から type: offer メッセージを受信した際に呼び出されるコールバック
  override fun onOfferMessage(mediaChannel: SoraMediaChannel, offer: OfferMessage) {

    // 認証サーバーから返却された metadata は OfferMessage.metadata に設定されます
    val offerMetadata = offer.metadata

  }
}
シグナリング通知メタデータの送信

Sora との接続時に認証に利用するメタデータを送信することができます。

シグナリング接続時に送信する signaling_notify_metadata については Sora ドキュメントの シグナリング通知メタデータ をご確認ください。

Sora Android SDK では signaling_notify_metadata を、 SoraMediaChannelsignalingNotifyMetadata に値を設定します。 JSON 形式に変換可能なデータを設定してください。設定したデータは Gson により変換されます。

// 接続して映像を送受信します
// signalingMetadata, signalingNotifyMetadata には JSON 形式に変換可能なデータを設定します
val mediaChannel = SoraMediaChannel(
              context                 = this,
              signalingEndpoint       = "wss://example.com/signaling",
              channelId               = "sora",
              signalingNotifyMetadata = mapOf("spam" to "egg"),
              mediaOption             = option,
              listener                = channelListener)

mediaChannel.connect()
シグナリング通知メタデータの取得

シグナリング通知時に連携されるメタデータについては、 Sora のドキュメント シグナリング通知メタデータ をご確認ください。

Sora Android SDK ではシグナリング通知メタデータが、 SoraMediaChannel.ListeneronNotificationMessage で通知されます。

シグナリング通知メタデータは NotificationMessage 内に格納されます。項目の詳細については Sora のドキュメントを参照してください。

// 接続通知を受信するための Listener を宣言します。
private val channelListener = object : SoraMediaChannel.Listener {

  // Sora のシグナリング通知機能の通知を受信したときに呼び出されるコールバック
  override fun onNotificationMessage(mediaChannel: SoraMediaChannel, notification: NotificationMessage) {

    when (notification.eventType) {
      // シグナリング通知メタデータは NotificationMessage に格納されます
      // 項目の詳細については Sora のドキュメントを参照してください
      "connection.created", "connection.destroyed", "connection.updated" -> {

        var signalingNotifyConnectionId  = notification.clientId
        var signalingNotifyAuthnMetadata = notification.authnMetadata
        var signalingNotifyAuthzMetadata = notification.authzMetadata
        var signalingNotifyDataList      = notification.data
      }
    }
  }
}
プッシュ通知の取得

プッシュ通知については Sora のドキュメントの プッシュ通知 API をご確認ください。

Sora Android SDK では ブッシュ通知の受信が、 SoraMediaChannel.ListenerPushMessage で通知されます。

// 接続通知を受信するための Listener を宣言します。
private val channelListener = object : SoraMediaChannel.Listener {

  // Sora のプッシュ通知機能の通知を受信したときに呼び出されるコールバック
  override fun onPushMessage(mediaChannel: SoraMediaChannel, push: PushMessage) {

    // プッシュされたメッセージは PushMessage.data に格納されます
    val data = push.data
    if (data is Map<*, *>) {
        data.forEach { (key, value) ->
            Log.d(TAG, "received push data: $key=$value")
        }
    }
  }
}
DataChannel 経由のシグナリング

Sora Android SDK で Sora と DataChannel を経由したシグナリング通信を行う場合は SoraMediaChanneldataChannelSignalingtrue を設定します。 デフォルトの設定はいずれも無効です。

ignoreDisconnectWebsocket プロパティに true をセットした場合、 DataChannel への切り替え完了後に Android SDK は WebSocket を切断します。

// 接続して映像を送受信します
// DataChannel 経由のシグナリングを有効にしています
// ignoreDisconnectWebSocket = true にすると DataChannel への切り替え完了後に WebSocket は切断されます
val mediaChannel = SoraMediaChannel(
              context                     = this,
              signalingEndpoint           = "wss://example.com/signaling",
              channelId                   = "sora",
              dataChannelSignaling        = true,
              ignoreDisconnectWebSocket   = true,
              mediaOption                 = option,
              listener                    = channelListener)

mediaChannel.connect()
HTTP プロキシ・サーバーの設定

Sora Android SDK は HTTP プロキシ・サーバーを経由した通信を行うことができます。

  • HTTP プロキシに対応しています

    • SOCKS プロキシも設定できますが、動作を確認していません

  • HTTP の CONNECT メソッドは HTTPS ではなく HTTP で送信します

  • Proxy-Authorization ヘッダーを利用した Basic 認証に対応しています

  • Android OS の Wi-Fi に設定されたプロキシの項目を参照しません

プロキシ・サーバーの情報は SoraMediaOption.proxy に設定します。

val mediaOption = SoraMediaOption().apply {

  proxy.type = ProxyType.HTTPS

  // ホスト名、または IP アドレスを指定します
  proxy.hostname = "proxy.example.com"
  proxy.port = 3128

  // プロキシに認証が設定されている場合は username と password を指定します
  proxy.username = "ham"
  proxy.password = "egg"

  // エージェントの設定は任意です
  // 未設定の場合は、シグナリング・メッセージに含まれる `sora_client` の値が使用されます
  proxy.agent = "spam"

}
転送フィルター機能

転送フィルター機能は、Sora 側でクライアントへ転送する音声や映像のパケットをフィルターする機能です。 詳しくは Sora ドキュメントの転送フィルター機能 を参照してください。

この機能は SoraChannelRoleSENDRECV または RECVONLY の場合にのみ利用できます。

フィルターを設定する

サーバー接続時に SoraMediaChannelforwardingFiltersOption を設定します。

設定例

以下の例は、自分の接続に対して、以下の条件で映像または音声の受信をブロックします。

  • connection_id が "S8YEN0TSE13JDC2991NG4XZ150" の場合は音声と映像の受信をブロックする、または client_id が "screen-share" の場合は音声の受信をブロックする

val forwardingFilters =
    listOf(
        SoraForwardingFilterOption(
            name = "filter1",
            priority = 1,
            action = SoraForwardingFilterOption.Action.BLOCK,
            rules =
                listOf(
                    listOf(
                        SoraForwardingFilterOption.Rule(
                            SoraForwardingFilterOption.Rule.Field.CONNECTION_ID,
                            SoraForwardingFilterOption.Rule.Operator.IS_IN,
                            listOf("S8YEN0TSE13JDC2991NG4XZ150")
                        )
                    ),
                    listOf(
                        SoraForwardingFilterOption.Rule(
                            SoraForwardingFilterOption.Rule.Field.CLIENT_ID,
                            SoraForwardingFilterOption.Rule.Operator.IS_IN,
                            listOf("screen-share")
                        ),
                        SoraForwardingFilterOption.Rule(
                            SoraForwardingFilterOption.Rule.Field.KIND,
                            SoraForwardingFilterOption.Rule.Operator.IS_IN,
                            listOf("audio")
                        )
                    )
                )
        )
    )


val mediaChannel =
    SoraMediaChannel(
        context = this,
        signalingEndpoint = "wss://sora.example.com/signaling",
        channelId = "sora",
        mediaOption = option,
        listener = channelListener,
        forwardingFiltersOption = forwardingFilters
    )
映像コーデックパラメーターの設定

送信する映像コーデックの設定と合わせて、映像コーデックのパラメータを指定可能です。 この機能は映像を送信する際に利用できます。

指定できる値の内容については以下の Sora ドキュメントを参照してください。

Sora Android SDK では上記の SoraMediaOptionvideoVp9Params, videoAv1Params, videoH264Params に値を設定します。 JSON 形式に変換可能なデータを設定してください。設定したデータは Gson により変換されます。

val mediaOption = SoraMediaOption().apply {

  // 映像コーデックパラメーターを指定する場合は必ず映像コーデックを指定する必要があります
  // 映像コーデックの設定は VP9 / AV1 / H.264 のいずれか 1 種類のみです
  // 利用しない映像コーデックパラメーターは設定しないでください

  // VP9 の映像コーデックパラメーターを指定する
  // videoCodec = SoraVideoOption.Codec.VP9
  // videoVp9Params = object {
  //   var profile_id: Int = 0
  // }

  // AV1 の映像コーデックパラメーターを指定する
  // videoCodec = SoraVideoOption.Codec.AV1
  // videoAv1Params = object {
  //   var profile: Int = 0
  // }

  // H.264 の映像コーデックパラメーターを指定する
  // videoCodec = SoraVideoOption.Codec.H264
  // videoH264Params = object {
  //   var profile_level_id: String = "42e034"
  // }
}
ネットワーク逼迫時の映像品質制御を設定する

ネットワーク状況の逼迫等により設定した解像度やフレームレートを維持できなくなった場合の挙動を制御するためのパラメータを設定可能です。 この機能は映像を送信する際に利用できます。

指定できる値は以下のようになります。指定は任意であり指定しない場合はデフォルトの BALANCED で動作します。

  • MAINTAIN_RESOLUTION: 解像度を維持し、フレームレートを下げる

  • MAINTAIN_FRAMERATE: フレームレートを維持し、解像度を下げる

  • BALANCED: フレームレートと解像度のバランスを取る

  • DISABLED: 品質調整機能を無効化

fun connect() {
    ...
    val mediaOption = SoraMediaOption().apply {
       ...
       // 解像度維持優先を設定する例
       degradationPreference = SoraVideoOption.DegradationPreference.MAINTAIN_RESOLUTION
       ...
    }
 }
複数のシグナリング URL を指定する

Sora Android SDK では、 signalingEndpointCandidates に複数のシグナリング URL を指定することができます。

Sora Android SDK は全ての URL に対して接続を試行し、最初に成功した接続をシグナリングに使用します。 このため、1台でも正常なサーバーが残っていれば Sora への接続が成功します。 クラスター機能は複数の URL を指定しなくても利用できますが、冗長性を高めるために複数 URL の指定を推奨します。

// 接続して映像を送受信する
val mediaChannel = SoraMediaChannel(
              context           = this,
              // signalingEndpointCandidates に複数の URL を指定する
              signalingEndpointCandidates = [
                  "wss://sora1.example.com/signaling",
                  "wss://sora2.example.com/signaling",
                  "wss://sora3.example.com/signaling",
              ],
              channelId         = "sora",
              mediaOption       = option,
              listener          = channelListener)
mediaChannel.connect()
  • 実際にシグナリングに利用されている URL は SoraMediaChannel クラスの connectedSignalingEndpoint プロパティから確認できます。

クラスター機能利用時のシグナリングのリダイレクト

クラスター機能を有効にすると、 Sora から、 type: offer の代わりに type: redirect が送られてくることがあります。 この場合、Sora Android SDK は Sora の接続を一度切断し、 type: redirect で指定された location に再接続します。

クラスター機能の詳細な仕組みについては Sora のドキュメント を参照してください。

マルチストリーム機能

概要

重要

Sora ではデフォルトでマルチストリームを利用します。

マルチストリームとは、1 つのピア接続で複数のストリームを管理する機能です。この機能を利用して、1 つの接続で送信と受信の両方を行うことができます。

詳細は Sora ドキュメントの マルチストリーム機能 をご確認ください。

マルチストリーム機能の利用

Sora はデフォルトでマルチストリームを利用するので、設定は必要ありません。

送受信を指定
val option = SoraMediaOption().apply {
    // 音声を送受信する
    enableAudioUpstream()
    enableAudioDownstream()
}
送信のみを指定
val option = SoraMediaOption().apply {
    // 映像と音声を送信する
    enableVideoUpstream()
    enableAudioUpstream()
}
受信のみを指定
val option = SoraMediaOption().apply {
    // 映像と音声を受信する
    enableVideoDownstream()
    enableAudioDownstream()
}

サイマルキャスト機能

概要

サイマルキャストは複数画質の映像を同時に配信する仕組みです。

サイマルキャストの詳細については Sora の サイマルキャスト機能 <https://sora-doc.shiguredo.jp/SIMULCAST> をご確認ください。

サイマルキャスト機能を利用する

サイマルキャスト機能を利用するには SoraMediaOption.enableSimulcast() を実行します。 サイマルキャストで 受信する映像の画質 を指定する rid は SimulcastRid で指定します。

サイマルキャストが利用可能な映像コーデック

Android SDK は Sora で利用可能な全てのコーデックでサイマルキャストが利用可能です。

  • VP8

  • VP9

  • AV1

  • H264

  • H265

送受信を指定
val capturer = CameraCapturerFactory.create(this)

val option = SoraMediaOption().apply {

    // 映像、音声の送受信の設定を行います

    enableVideoUpstream(capturer!!, egl.eglBaseContext)
    enableAudioUpstream()
    enableVideoDownstream()
    enableAudioDownstream()

    // サイマルキャスト機能を有効にします
    enableSimulcast()

    // 受信する画質 (rid) を指定することが可能です
    // enableSimulcast(SimulcastRid.R0)

    // 映像コーデックを指定します
    videoCodec = SoraVideoOption.Codec.VP8

    // 3 段階の画質に対応するためにビットレートを高めに指定します
    videoBitrate = 5000

}

// Sora との接続後、カメラ起動時に解像度とフレームレートを指定します
// 3 段階の画質に対応するためにカメラの解像度を高めに指定します
capturer?.startCapture(1920, 1080, 30)
送信のみを指定
val capturer = CameraCapturerFactory.create(this)

val option = SoraMediaOption().apply {

    // 映像、音声の送受信の設定を行います

    enableVideoUpstream(capturer!!, egl.eglBaseContext)
    enableAudioUpstream()

    // サイマルキャスト機能を有効にします
    enableSimulcast()

    // 配信する映像コーデックを指定します
    videoCodec = SoraVideoOption.Codec.VP8

    // 3 段階の画質に対応するためにビットレートを高めに指定します
    videoBitrate = 5000

}

// Sora との接続後、カメラ起動時に解像度とフレームレートを指定します
// 3 段階の画質に対応するためにカメラの解像度を高めに指定します
capturer?.startCapture(1920, 1080, 30)

スポットライト機能

概要

スポットライト機能は、直近で話をした話者の画質を優先して配信する機能です。

スポットライト機能の詳細は Sora のドキュメント を参照してください。

スポットライト機能を利用する

スポットライト機能を利用するには SoraMediaOption.enableSpotlight() を指定します。 引数でスポットライト機能の設定と、スポットライトで サイマルキャスト機能 を有効にするかどうかを指定します。

送受信を指定
val capturer = CameraCapturerFactory.create(this)

val mediaOption = SoraMediaOption().apply {
    // 映像と音声を送受信する
    enableVideoUpstream(capturer!!, egl!!.eglBaseContext)
    enableVideoDownstream(egl!!.eglBaseContext)
    enableAudioUpstream()
    enableAudioDownstream()

    // スポットライト機能の設定
    val spotlight = SoraSpotlightOption()

    // 最大アクティブ配信数
    spotlight.spotlightNumber = 3

    // スポットライトがフォーカスされている映像、フォーカスされていない映像の rid (オプション)
    // 映像を受信しない設定も可能
    spotlight.spotlightFocusRid = SoraVideoOption.SpotlightRid.R1
    spotlight.spotlightUnfocusRid = SoraVideoOption.SpotlightRid.NONE

    // スポットライト機能を有効にする
    enableSpotlight(spotlight)

    // サイマルキャスト機能を無効化した状態でスポットライト機能を利用する場合は enableSimulcast に false を設定する
    // enableSpotlight(spotlight, false)

    // 映像コーデックを指定します
    videoCodec = SoraVideoOption.Codec.VP8
}

...
// Sora との接続後、カメラ起動時に解像度とフレームレートを指定する
// 解像度: VGA, フレームレート: 30
capturer?.startCapture(640, 480, 30)

映像の送受信と描画

映像を送受信する
カメラの映像を取得する

カメラの映像を取得するキャプチャラー (org.webrtc.CameraVideoCapturer) は jp.shiguredo.sora.sdk.camera.CameraCapturerFactory を呼ぶと取得できます。

create() の定義は次の通りです:

fun create(
    context: android.content.Context,
    frontFacingFirst: Boolean = true
): org.webrtc.CameraVideoCapturer?
  • context: アプリケーションコンテキスト。 Activity オブジェクトを渡します。

  • frontFacingFirst: true であれば前面カメラを優先します。 false であれば背面カメラを優先します。デフォルトは true です。

使用例
class MainActivity : AppCompatActivity() {

  fun start() {
    // 背面カメラを優先したい場合の設定例
    capturer = CameraCapturerFactory.create(this, frontFacingFirst = false)
    ...
  }

}
映像を描画する

Sora Android SDK は基本的に libwebrtc の API を隠蔽していますが、映像の描画には直接 libwebrtc の API を使う必要があります。

UI コンポーネント

映像を描画する UI コンポーネントは org.webrtc.SurfaceViewRenderer です。 SurfaceViewRendererandroid.view.SurfaceView のサブクラスであり、 OpenGL ES を利用して映像を描画します。

レイアウト

SurfaceViewRenderer は一般的なレイアウトと同様に XML ファイルでレイアウトを定義できます。

次に例を示します:

<LinearLayout
    android:id="@+id/renderers"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="20dp">

    <org.webrtc.SurfaceViewRenderer
        android:id="@+id/localRenderer"
        android:layout_width="match_parent"
        android:layout_height="300dp"/>

    <org.webrtc.SurfaceViewRenderer
        android:id="@+id/remoteRenderer"
        android:layout_width="match_parent"
        android:layout_height="300dp" />
</LinearLayout>
初期化と終了処理

SurfaceViewRenderer で映像を描画する際は、明示的な初期化と終了処理を行う必要があります。 映像の描画を行う前に init() を呼び出して初期化し、 SurfaceViewRenderer を使い終えたら release() を呼び出して終了処理を行います。 終了処理を忘れるとリソースがリークする原因になります。

init() は EGL の API である android.opengl.EGLContext を引数に取ります。 EGLContextorg.webrtc.EglBase のプロパティであり、他にも様々な箇所で使います。

EglBase は EGL のレンダリングコンテキストを保持するオブジェクトです。 こちらも使い終えたら release() で終了処理を行う必要があります。

一般的には、アクティビティの生成時に EglBase の生成と SurfaceViewRenderer の初期化を行い、アクティビティの終了時に両方の終了処理を行うとよいでしょう。 次に例を示します:

class MyActivity : AppCompatActivity() {

    private val egl: EglBase? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        egl = EglBase.create()
        // その他の初期化
    }

    // UIの組み立てが終わった直後にこのメソッドを呼ぶようにする
    fun initRenderers() {
        // localRenderer, remoteRenderer は XML ファイルで定義済み
        localRenderer.init(egl.eglContext, null)
        remoteRenderer.init(egl.eglContext, null)
    }

    // このメソッドを最後に必ず呼ぶようにする
    fun releaseRenderers() {
        localRenderer.release()
        remoteRenderer.release()
        egl.release()
    }
}
動画の左右を反転する

setMirror() を呼ぶと動画の左右を反転させることができます。

localRenderer.setMirror(true)
キャプチャーの操作
キャプチャーを開始する

映像のキャプチャーを開始するには startCapture() を呼びます。

キャプチャーを停止する

キャプチャーを停止するには stopCapture() を呼びます。

キャプチャーのフォーマットを変更する

changeCaptureFormat() を使うと、キャプチャーした映像のサイズとフレームレートを変更できます。

VideoEncoderFactory

VideoEncoderFactory は、 SoraMediaOption.videoEncoderFactory で指定することができます。

注釈

VideoEncoderFactory は libwebrtc に定義された interface です。

参考リンク: https://chromium.googlesource.com/external/webrtc/+/HEAD/sdk/android/api/org/webrtc/VideoEncoderFactory.java

VideoEncoderFactory を設定しない場合の挙動

VideoEncoderFactory を設定しない場合は、以下のように VideoEncoderFactory が決定されます (Sora Android SDK の持つ VideoEncoderFactory は internal なので SDK ユーザーが直接利用することはできません)。

  • サイマルキャストが有効な場合

    • SimulcastVideoEncoderFactoryWrapper

  • それ以外

    • SoraDefaultVideoEncoderFactory

ソフトウェアエンコーダーの使用を強制する

Sora Android SDK ではデフォルトでハードウェアエンコーダーをメインに設定し、ソフトウェアエンコーダーをフォールバック先に指定します。

この挙動を変更してソフトウェアエンコーダーのみを利用するには SoraMediaOptionsoftwareVideoEncoderOnly: Booleantrue を設定してください。デフォルト値は false です。

これにより、ハードウェアエンコーダーではなくソフトウェアエンコーダーを利用することができます。

注釈

videoEncoderFactory を設定している場合、softwareVideoEncoderOnly は無視されます。

val capturer = CameraCapturerFactory.create(this)

val option = SoraMediaOption().apply {

    // ソフトウェアエンコーダーのみを利用するように設定
    softwareVideoEncoderOnly = true

    // 映像、音声の送受信の設定
    enableVideoUpstream(capturer!!, egl.eglBaseContext)
    enableAudioUpstream()
    enableVideoDownstream()
    enableAudioDownstream()

    // 映像コーデックを指定
    videoCodec = SoraVideoOption.Codec.VP9
}
VideoEncoderFactory の設定方法

Sora Android SDK は利用したい VideoEncoderFactory を指定できます。

実装例

val capturer = CameraCapturerFactory.create(this)

val option = SoraMediaOption().apply {

    // 独自のエンコーダー実装を利用するように設定する
    videoEncoderFactory = MyVideoEncoderFactory()

    // 映像、音声の送受信の設定
    enableVideoUpstream(capturer!!, egl.eglBaseContext)
    enableAudioUpstream()
    enableVideoDownstream()
    enableAudioDownstream()

    // 映像コーデックを指定
    videoCodec = SoraVideoOption.Codec.VP9
}
org.webrtc.SoftwareVideoEncoderFactory を videoEncoderFactory に設定する際の注意

重要

ソフトウェアエンコーダーを利用したい場合は、まず ソフトウェアエンコーダーの使用を強制する を試してみることをおすすめします。

以下の実装例のように libwebrtc で提供されている、 org.webrtc.SoftwareVideoEncoderFactory を videoEncoderFactory に設定する場合は、 SoftwareVideoEncoderFactory をインスタンス化する前に jingle_peerconnection_so をロードしてください。

注釈

なぜ jingle_peerconnection_so をロードする必要があるのか

SoftwareVideoEncoderFactory 生成時に JNI の nativeCreateFactory() を即時に呼び出すようになりました。 そのため PeerConnectionFactory.initialize(...) より前に本クラスを生成すると、 まだ jingle_peerconnection_so がロードされておらず JNI 解決に失敗し、 次の UnsatisfiedLinkError が発生します。

java.lang.UnsatisfiedLinkError: No implementation found for long org.webrtc.SoftwareVideoEncoderFactory.nativeCreateFactory()

そのため、System.loadLibrary("jingle_peerconnection_so") を先に呼んで明示的にロード しておく必要があります。

この対応が必要になったのはこの commit 以降です。 https://source.chromium.org/chromium/_/webrtc/src.git/+/c97651cbb4e94ef3f9768015c2bb3b93c953ebe9

実装例

val capturer = CameraCapturerFactory.create(this)

// jingle_peerconnection_so をロードしてから
// SoftwareVideoEncoderFactory を初期化しないと実行時に例外が起こります
try {
   System.loadLibrary("jingle_peerconnection_so")
} catch (e: UnsatisfiedLinkError) {
}

val option = SoraMediaOption().apply {

    // ソフトウェアエンコーダーを利用するように設定する
    videoEncoderFactory = SoftwareVideoEncoderFactory()

    // 映像、音声の送受信の設定
    enableVideoUpstream(capturer!!, egl.eglBaseContext)
    enableAudioUpstream()
    enableVideoDownstream()
    enableAudioDownstream()

    // 映像コーデックを指定
    videoCodec = SoraVideoOption.Codec.VP9
}

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

概要

リアルタイムメッセージング機能は WebRTC の DataChannel を利用して、データの送受信を行う機能です。 詳細は Sora のドキュメント を参照してください。 また、サンプルアプリケーションに リアルタイムメッセージング を用意していますのでこちらも参考にしてください。

Sora Android SDK では SoraMediaChannel の初期化時に dataChannels に compress = true を指定した場合、メッセージの圧縮と解凍は SDK 内部で自動的に行われます。アプリケーション側で意識する必要はありません。

メッセージを送受信する
Sora 接続時にリアルタイムメッセージング用 DataChannel を設定する

Sora の 接続時に SoraMediaChannel にリアルタイムメッセージング用の DataChannel を指定できます。 List<Map<String, Any>> の形式で指定します。

// リアルタイムメッセージング機能に利用する DataChannel を指定する
val dataChannels = listOf(
  mapOf(
      "label" to "#spam",
      "direction" to "sendrecv"
  ),
  mapOf(
      "label" to "#egg",
      "max_retransmits" to 0,
      "ordered" to false,
      "protocol" to "abc",
      "compress" to false,
      "direction" to "recvonly",
      "header" to listOf(
         mapOf(
            "type" to "sender_connection_id"
         )
      )
  ),
)

// オプションを設定する。通常の接続と設定内容は変わりません。
val mediaOption = SoraMediaOption()
mediaOption.enableVideoDownstream(null)

// Sora に接続する。SoraMediaChannel 生成時に dataChannels を設定する。
val mediaChannel = SoraMediaChannel(
              context = this,
              signalingEndpointCandidates = [
                  "wss://sora.example.com/signaling",
              ],
              channelId = "sora",
              mediaOption = option,
              listener = channelListener,
              // DataChannel シグナリングを有効化する
              dataChannelSignaling = true,
              dataChannels = dataChannels)
mediaChannel.connect()
メッセージを受信する
val channelListener = object : SoraMediaChannel.Listener {

  // DataChannel が利用可能になったタイミングで実行されるコールバック
  override fun onDataChannel(mediaChannel: SoraMediaChannel, dataChannels: List<Map<String, Any>>?) {
      super.onDataChannel(mediaChannel, dataChannels)
      // リアルタイムメッセージングで利用できる DataChannel 一覧を出力する
      Log.d("onDataChannel", "$dataChannels")
    }
  }

  // DataChannel メッセージ受信時のコールバック
  override fun onDataChannelMessage(mediaChannel: SoraMediaChannel, label: String, data: ByteBuffer) {
    // ByteBuffer を String に変換して出力する
    val message = mediaChannel.dataToString(data)
    Log.d("onDataChannelMessage", message)
  }

}
メッセージを送信する
// メッセージ送信する
mediaChannel.sendDataChannelMessage("#spam", "Hello World")
DataChannel を利用したリアルタイムメッセージングのみで接続する

音声と映像を送受信せずにメッセージのみの送受信を行う方法の詳細については、 Sora のドキュメント 音声と映像を送受信せずにメッセージのみで接続する をご確認ください。 Sora Android SDK では、 SoraMediaOption.roleSoraChannelRole.SENDRECV を指定して接続を行います。

// オプションを設定する
val mediaOption = SoraMediaOption()
mediaOption.role = SoraChannelRole.SENDRECV

// Sora に接続する
val mediaChannel =
   SoraMediaChannel(
      context = this,
      signalingEndpointCandidates =
            [
               "wss://sora.example.com/signaling",
            ],
      channelId = "sora",
      mediaOption = option,
      listener = channelListener,
      // DataChannel シグナリングを有効化する
      dataChannelSignaling = true,
      dataChannels = dataChannels
   )

mediaChannel.connect()
ヘッダーとメッセージを分割する

リアルタイムメッセージングにヘッダーが追加されている場合、onDataChannelMessaging で受け取るデータにはヘッダーとメッセージが結合された状態で入っています。 これを分離するには SoraMediaChannel.Listener の onOfferMessageonDataChannelMessage を利用して以下のように処理します。

以下はヘッダーに sender_connection_id が指定されている場合の例です

// label ごとにヘッダーの長さを保持するための変数
private var headerLengthMap: MutableMap<String, Int> = mutableMapOf()

private val channelListener = object : SoraMediaChannel.Listener {
   override fun onOfferMessage(mediaChannel: SoraMediaChannel, offer: OfferMessage) {
      val dataChannels = offer.dataChannels
      // dataChannels の null チェック
      if (dataChannels != null) {
         for (dataChannel in dataChannels) {
            // label の 先頭に # がついているものがリアルタイムメッセージング用
            // # がついていないものは処理しない
            val label = dataChannel["label"] as String
            if (!label.startsWith("#")) {
               continue
            }

            // dataChannel に header (List<Map<String, Any>>) がある場合は
            // header の中から type: sender_connection_id の Map を取得し
            // length の値を取得する
            val header = dataChannel["header"] as? List<*>?
            if (header != null) {
               for (headerMap in header) {
                  if (headerMap is Map<*, *>) {
                     if (headerMap["type"] == "sender_connection_id") {
                         // Double で取得されるため Int に変換する
                         val length = headerMap["length"] as Double
                         headerLengthMap[label] = length.toInt()
                     }
                  }
               }
            }
         }
      }
   }

   override fun onDataChannelMessage(
      mediaChannel: SoraMediaChannel,
      label: String,
      data: ByteBuffer
   ) {
      // headerLengthMap に label が存在するか確認する
      // 存在する場合はその length を取得し、以下のように分割処理する
      // 1. 先頭から length バイトが sender_connection_id
      // 2. 残りがメッセージ本体
      if (headerLengthMap.containsKey(label)) {
         val length = headerLengthMap[label]!!
         val senderConnectionId = ByteArray(length)
         data.get(senderConnectionId)
         val message = ByteArray(data.remaining())
         data.get(message)
         // String() で utf-8 文字列に変換する
         Log.d(
            "tag",
            "received data: label=$label," +
            "sender_connection_id=${String(senderConnectionId)}," +
            "message=${String(message)}"
         )
      } else {
         Log.d("tag", "received data: label=$label, message=${mediaChannel.dataToString(data)}")
      }
   }
}

API リファレンス

API リファレンスは こちら を参照ください。

主に使う API を次に示します:

コールバック

Sora Android SDK には WebRTC API のイベントや Sora 固有の機能のイベントをハンドリングするためのコールバックを用意しています。

ここではそのコールバックの利用方法について説明します。

onAddLocalStream

ローカルストリーム(自分)が追加されたときに呼び出されるコールバックです。

Sora では各 MediaStream の videoTracks には 1 つしか VideoTrack が含まれないため、MediaStream.videoTracks[0] で VideoTrack を取得できます。

private var localAudioTrack: AudioTrack? = null

private val channelListener = object : SoraMediaChannel.Listener {

   // ローカル(送信用)の MediaStream が準備できたときに呼ばれます。
   // メディア送信時に必要となる設定をここで行います。
   // SoraMediaOption で、音声や映像を upstream で送信する指定を行っていない場合は
   // このメソッドを実装する必要はありません。
   override fun onAddLocalStream(mediaChannel: SoraMediaChannel, ms: MediaStream) {

      // 動画の表示(UI)に関係する処理になるので、
      // Activity の runOnUiThread メソッドを利用し、UIスレッドで実行することを推奨します。
      runOnUiThread {
         if (ms.videoTracks.size > 0) {
            // 予め用意しておいた、localRenderer(SurfaceViewRendererオブジェクト)を
            // 以下のように、videoTrackに紐付けておきます
            // ただし、自分が送信するデータを表示したくない場合には、これらの処理は必要ありません
            val track = ms.videoTracks[0]
            track.setEnabled(true)
            track.addSink(localRenderer)
            capturer?.startCapture(400, 400, 30)
         }

         if (ms.audioTracks.size > 0) {
            // 必要であれば AudioTrack をここで掴んでおきます。
            localAudioTrack = ms.audioTracks[0]
         }
      }
   }
}

// onAddLocalStream で AudioTrack を掴んでおくと、一時的にミュートしたい場合などに便利です。
private fun muteAudio() {
   localAudioTrack?.setEnabled(false)
}

private fun unmuteAudio() {
   localAudioTrack?.setEnabled(true)
}
onAddRemoteStream

リモートストリームが追加されたときに呼び出されるコールバックです。

Sora では各 MediaStream の videoTracks には 1 つしか VideoTrack が含まれないため、MediaStream.videoTracks[0] で VideoTrack を取得できます。

private val channelListener = object : SoraMediaChannel.Listener {

   // リモート(受信用)の MediaStream が準備できたときに呼ばれます。
   // メディア受信時に必要となる設定をここで行います。
   // SoraMediaOption で、音声や映像を downstream で受信する設定を行っていない場合は
   // このメソッドを実装する必要はありません。
   override fun onAddRemoteStream(mediaChannel: SoraMediaChannel, ms: MediaStream) {

      // 動画の表示(UI)に関係する処理になるので、
      // Activity の runOnUiThread メソッドを利用し、UIスレッドで実行することを推奨します。
      runOnUiThread {
         if (ms.videoTracks.size > 0) {
            // 予め用意しておいた、remoteRenderer(SurfaceViewRendererオブジェクト)を
            // 以下のように、videoTrackに紐付けておきます
            // ただし、受信する映像を表示したくない場合には、これらの処理は必要ありません
            val track = ms.videoTracks[0]
            track.setEnabled(true)
            track.addSink(remoteRenderer)
         }
      }
   }
}
onRemoveRemoteStream

リモートストリームが削除されたときに呼び出されるコールバックです。

private val channelListener = object : SoraMediaChannel.Listener {
   override fun onRemoveRemoteStream(mediaChannel: SoraMediaChannel, label: String) {
      runOnUiThread {
         // 例: リモートストリームの描画領域をクリア
         binding.remoteRenderer.clearImage()
      }
   }
}
onConnect

Sora との接続が確立されたときに呼び出されるコールバックです。

private val channelListener = object : SoraMediaChannel.Listener {

   override fun onConnect(mediaChannel: SoraMediaChannel) {
      // 接続が確立されたときの処理を記述する
   }
}
onClose

Sora との接続が切断されたときに呼び出されるコールバックです。Sora から切断された場合、closeEvent に切断理由が設定されます。

このコールバックが呼び出されたとき、SoraMediaChannel 内部ではすでに切断処理が行われた後の状態になっており、Sora との接続に関わるオブジェクトは破棄されています。 そのため、再接続を行う場合は、SoraMediaChannel を作成し直す必要があります。

以下のようなタイミングで呼び出されます。

  • SoraMediaChannel.disconnect() を呼び出したとき

  • Sora から切断されたことを検知したとき

  • PeerConnection の state が切断になったとき

  • 上記以外で何かしら異常が発生したとき

closeEvent について

closeEvent は Sora から切断された場合のステータスコードと理由が設定されます。

closeEvent は SoraCloseEvent オブジェクトで、以下のプロパティを持ちます。

  • code

    • Sora から切断されたときのステータスコード

    • Sora からの切断メッセージが取得できない場合は 1000 が設定されます

  • reason

    • Sora から切断されたときの理由

    • Sora からの切断メッセージが取得できない場合は NO-ERROR が設定されます

Sora からの切断メッセージがが取得できない場合は以下のようなケースです。

  • SoraMediaChannel.disconnect() を呼び出しなど、クライアント契機の切断

  • ネットワークの切断や Sora のサーバーの障害など、Sora からの切断メッセージが受信できなかった場合

  • DataChannel 経由のシグナリングを利用する場合、かつ ignore_disconnect_websocket が true の場合 - 上記の設定の場合、 Sora の切断メッセージを受信するには data_channel_signaling_close_message を有効にする必要があります - data_channel_signaling_close_message が有効の場合も、 切断メッセージの受信より先に DataChannel の切断をクライアントが検知した場合は切断メッセージの受信は行われません

private val channelListener = object : SoraMediaChannel.Listener {

   override fun onClose(mediaChannel: SoraMediaChannel, closeEvent: SoraCloseEvent) {
      when {
          closeEvent.code != 1000 -> Log.e(TAG, "onClose: エラーにより Sora から切断されました: $closeEvent")
          else -> Log.d(TAG, "onClose: Sora から切断されました: $closeEvent")
      }
      // 切断されたときの処理を記述する
   }
}
onError

Sora との通信やメディアでエラーが発生したときに呼び出されるコールバックです。

onError が発生した場合も、onClose は呼び出されるため、終了処理は onClose に実装されていれば問題ありません。

private val channelListener = object : SoraMediaChannel.Listener {

   override fun onError(mediaChannel: SoraMediaChannel, reason: SoraErrorReason, message: String) {
      // エラーが発生したときの処理を記述する
   }
}
onWarning

Sora との通信やメディアで警告が発生したときに呼び出されるコールバックです。

private val channelListener = object : SoraMediaChannel.Listener {

   override fun onWarning(mediaChannel: SoraMediaChannel, reason: SoraErrorReason) {
      // 警告が発生したときの処理を記述する
   }
}
onAttendeesCountUpdated

接続しているチャネルの参加者が増減したときに呼び出されるコールバックです。

ChannelAttendeesCount は、ロールごとに接続数を保持しているオブジェクトです。

例えば、視聴者数 (recvonly の数) の更新を UI に反映させる場合は以下のようにします。

private val channelListener = object : SoraMediaChannel.Listener {

   override fun onAttendeesCountUpdated(
      mediaChannel: SoraMediaChannel,
      attendees: ChannelAttendeesCount
   ) {
      // 例: 視聴者数を更新する
      updateViewerCount(attendees.numberOfRecvonlyConnections)
   }
}
onOfferMessage

Sora から type: offer メッセージを受信したときに呼び出されるコールバックです。

private val channelListener = object : SoraMediaChannel.Listener {

   override fun onOfferMessage(mediaChannel: SoraMediaChannel, offer: OfferMessage) {
      // offer メッセージを受信したときの処理を記述する
   }
}
onNotificationMessage

Sora のシグナリング通知機能の通知を受信したときに呼び出されるコールバックです。

詳しくは Sora ドキュメントの シグナリング通知機能 を参照してください。

private val channelListener = object : SoraMediaChannel.Listener {

   override fun onNotificationMessage(
      mediaChannel: SoraMediaChannel,
      notification: NotificationMessage
   ) {
      // 通知を受信したときの処理を記述する
   }
}
onPushMessage

Sora のプッシュ API によりメッセージを受信したときに呼び出されるコールバックです。

詳しくは Sora ドキュメントの プッシュ API を参照してください。

private val channelListener = object : SoraMediaChannel.Listener {

   override fun onPushMessage(mediaChannel: SoraMediaChannel, push: PushMessage) {
      Log.d("onPushMessage", "push=$push")
      val data = push.data
      if (data is Map<*, *>) {
         data.forEach { (key, value) ->
             Log.d("onPushMessage", "received push data: $key=$value")
         }
      }
   }
}
onPeerConnectionStatsReady

PeerConnection の getStats() 統計情報を取得したときに呼び出されるコールバックです。

SoraMediaChannel 初期化時に PeerConnectionOptiongetStatsIntervalMSec に 0 より大きい値を設定すると、getStatsIntervalMSec ミリ秒ごとにこのコールバックが呼び出されます。

private val channelListener = object : SoraMediaChannel.Listener {

   override fun onPeerConnectionStatsReady(
      mediaChannel: SoraMediaChannel,
      statsReport: RTCStatsReport
   ) {
      // RTCStatsReport の解析処理を記述する
   }
}
onSenderEncodings

サイマルキャスト配信のエンコーダー設定を変更するためのコールバックです。

引数の encodings は Sora が送ってきた設定を反映した RtpParameters.Encoding のリストです。 このコールバックを実装し、引数のオブジェクトを変更することで、アプリケーションの要件に従った設定をエンコーダーにわたすことができます。

private val channelListener = object : SoraMediaChannel.Listener {

   override fun onSenderEncodings(
      mediaChannel: SoraMediaChannel,
      encodings: List<RtpParameters.Encoding>
   ) {
      // 例: エンコーダー設定を変更する処理を記述する
   }
}
参考

Web 標準の対応 API は次のとおりです。libwebrtc の native(C++) と android の実装は異なりますので注意してください。

onDataChannel

データチャネルが利用可能になったときに呼び出されるコールバックです。

private val channelListener = object : SoraMediaChannel.Listener {

   // DataChannel が利用可能になったタイミングで実行されるコールバック
   override fun onDataChannel(mediaChannel: SoraMediaChannel, dataChannels: List<Map<String, Any>>?) {
      // リアルタイムメッセージングで利用できる DataChannel 一覧をログに出力する
      Log.d("onDataChannel", "$dataChannels")
   }
}
onDataChannelMessage

リアルタイムメッセージング機能のメッセージを受信したときに呼び出されるコールバックです。 ラベルが # から始まるメッセージのみが通知されます。

private val channelListener = object : SoraMediaChannel.Listener {

   // DataChannel メッセージ受信時のコールバック
   override fun onDataChannelMessage(mediaChannel: SoraMediaChannel, label: String, data: ByteBuffer) {
      // ByteBuffer を String に変換して出力する
      val message = mediaChannel.dataToString(data)
      Log.d("onDataChannelMessage", message)
   }
}

古いリリースノート

CHANGE

後方互換性のない変更

UPDATE

後方互換性がある変更

ADD

後方互換性がある追加

FIX

バグ修正

2021.3
日時:

2021-10-07

対応 Sora:

2021.1 以降

対応 libwebrtc:

m93.4577.8.2

  • [UPDATE] libwebrtc を 93.4577.8.2 にアップデートしました

  • [FIX] stats メッセージに含まれる統計情報のフォーマットを修正しました

2021.2
日時:

2021-08-05

対応 Sora:

2021.1

対応 libwebrtc:

m92.4515.9.1

  • [CHANGE] SoraMediaChannel のコンストラクタ引数 channelId の型を String? から String に変更しました

  • [CHANGE] connect メッセージの定義を以下の通り見直しました

    • connectionId の型を String? から String に変更しました

    • sdp_error を削除しました

  • [UPDATE] スポットライト接続時に spotlight_focus_rid / spotlight_unfocus_rid を指定できるようにしました

  • [UPDATE] offer に mid が含まれる場合は、 mid を利用して sender を設定するようにしました

  • [UPDATE] libwebrtc を 92.4515.9.1 にアップデートしました

  • [UPDATE] com.android.tools.build:gradle を 4.2.2 にアップデートしました

  • [UPDATE] JCenter サービスの利用を終了しました

  • [UPDATE] AES-GCM を利用可能にしました

  • [ADD] データチャネルシグナリングに対応しました

    • data_channel_signlaing, ignore_disconnect_websocket パラメータ設定を追加しました

    • onDataChannel コールバックを実装しました

    • 各 label に対応するデータチャネル関係のコールバックを実装しました

    • WebSocket 側の type:switched 受信の処理を追加しました

  • [FIX] 終了前にシグナリング Disconnect メッセージ送信を追加しました

    • 状態により WebSocket, DataChannel どちらかで送信するよう変更

  • [FIX] offer に data_channels が含まれない場合に対応しました

  • [FIX] 接続 / 切断を検知する処理を改善しました

    • 修正前は IceConnectionState を参照していましたが、 PeerConnectionState を参照するように修正しました

    • SoraErrorReason の以下の値を参照するコードは修正が必要です

      • ICE_FAILURE => PEER_CONNECTION_FAILED

      • ICE_CLOSED_BY_SERVER => PEER_CONNECTION_CLOSED

      • ICE_DISCONNECTED => PEER_CONNECTION_DISCONNECTED

  • [FIX] NotificationMessageturnTransportType を追加しました

  • [FIX] SoraSpotlightOption から simulcastRid を削除しました

    • スポットライトでは simulcast_rid を指定しても動作しないためです

  • [FIX] 接続成功時のコールバックが複数回実行されないように修正しました

    • 修正前は、 PeerConnectionState が CONNECTED に遷移する度に PeerChannel.Listener.onConnect が実行される可能性があったため初回のみコールバックが実行されるように修正しました

2021.1.1
日時:

2021-07-01

対応 Sora:

2021.1

対応 libwebrtc:

m89.4389.7.0

  • [CHANGE] SimulcastRid の定義を jp.shiguredo.sora.sdk.channel.signaling.message から jp.shiguredo.sora.sdk.channel.option.SoraVideoOption に変更しました

  • [FIX] Sora への接続時に simulcast_rid を指定するとエラーになる問題を修正しました

2021.1
日時:

2021-03-31

対応 Sora:

2020.3

対応 libwebrtc:

m89.4389.7.0

  • [UPDATE] libwebrtc を 89.4389.7.0 にアップデートしました

  • [UPDATE] Kotlin を 1.4.31 にアップデートしました

  • [UPDATE] Gradle を 6.8.3 にアップデートしました

  • [UPDATE] com.android.tools.build:gradle を 4.1.2 にアップデートしました

  • [UPDATE] com.squareup.okhttp3:okhttp を 4.8.1 にアップデートしました

  • [UPDATE] io.reactivex.rxjava2:rxjava を 2.2.19 にアップデートしました

  • [UPDATE] io.reactivex.rxjava2:rxkotlin を 2.4.0 にアップデートしました

  • [UPDATE] com.github.ben-manes:gradle-versions-plugin を 0.38.0 にアップデートしました

  • [UPDATE] org.ajoberstar.grgit:grgit-gradle を 4.1.0 にアップデートしました

  • [UPDATE] com.squareup.okhttp3:okhttp を 4.9.1 にアップデートしました

  • [UPDATE] io.reactivex.rxjava2:rxjava を 2.2.21 にアップデートしました

  • [UPDATE] シグナリング pong に統計情報を含めるようにしました

  • [UPDATE] 最新のサイマルキャストの仕様に追従しました

  • [UPDATE] サイマルキャストで VP8 / H.264 (ハードウェアアクセラレーション含む) に対応しました

  • [UPDATE] サイマルキャストで TextureBuffer のエンコードに対応しました

  • [UPDATE] 最新のスポットライトの仕様に追従しました

  • [UPDATE] SoraMediaOption.enableSimulcast() に引数を追加しました

  • [UPDATE] SoraMediaOption.enableSpotlight() を追加しました

  • [UPDATE] SoraSpotlightOption を追加しました

  • [UPDATE] SoraMediaChannel.connectionId を追加しました

  • [UPDATE] 廃止予定のプロパティに Deprecated アノテーションを追加しました

    • ChannelAttendeesCount.numberOfUpstreams

    • ChannelAttendeesCount.numberOfDownstreams

    • NotificationMessage.numberOfUpstreamConnections

    • NotificationMessage.numberOfDownstreamConnections

  • [FIX] NotificationMessage に漏れていた以下のフィールドを追加しました

    • authn_metadata

    • authz_metadata

    • channel_sendrecv_connections

    • channel_sendonly_connections

    • channel_recvonly_connections

  • [FIX] サイマルキャストパラメータ active: false が無効化されてしまう問題を修正しました

  • [FIX] スポットライトレガシーに対応しました

    • スポットライトレガシーを利用する際は Sora.usesSpotlightLegacy = true を設定する必要があります

    • スポットライトレガシーは 2021 年 12 月に予定されている Sora のアップデートで廃止されます

2020.3
日時:

2020-07-04

対応 Sora:

2020.1

対応 libwebrtc:

m83.4103.12

  • [CHANGE] 古いロール upstream, downstream を削除しました

  • [CHANGE] SoraAudioOption.audioSource のデフォルト値を VOICE_COMMUNICATION に変更しました

  • [UPDATE] libwebrtc を 83.4103.12.2 にアップデートしました

  • [UPDATE] com.android.tools.build:gradle を 4.0.0 にアップデートしました

  • [UPDATE] com.squareup.okhttp3:okhttp を 4.7.2 にアップデートしました

  • [ADD] 新しいロール sendonly, recvonly, sendrecv に対応しました

2020.2
日時:

2020-05-19

  • [CHANGE] compileSdkVersion を 29 に変更しました

  • [CHANGE] targetSdkVersion を 29 に変更しました

  • [CHANGE] シグナリング connect に含めるクライアント情報を変更しました

  • [UPDATE] Kotlin を 1.3.72 にアップデートしました

  • [UPDATE] Dokka を 0.10.1 にアップデートしました

  • [UPDATE] libwebrtc を 79.5.1 にアップデートしました

  • [UPDATE] com.android.tools.build:gradle を 3.6.3 にアップデートしました

  • [UPDATE] com.squareup.okhttp3:okhttp を 4.6.0 にアップデートしました

  • [UPDATE] junit:junit4.13 にアップデートしました

  • [UPDATE] Offer SDP 生成失敗時、エラーメッセージをシグナリング connect の sdp_error に含めて送信するよう変更しました

2020.1
日時:

2020-04-07

  • [UPDATE] com.android.tools.build:gradle を 3.5.3 にアップデートしました

  • [ADD] CameraCapturerFactory にフロント/リアカメラの優先順位のオプションを追加しました

  • [ADD] サイマルキャスト配信のエンコーダー設定変更用コールバックを追加しました

    • SoraMediaChannel.Listener#onSenderEncodings()

  • [ADD] 定数 SoraErrorReason.ICE_DISCONNECTED を追加しました

  • [ADD] SoraMediaChannel.ListeneronWarning メソッドを追加しました

    • このバージョンでは ICE_DISCONNECTED の通知のみに利用しています

    • ネットワークが不安定であることを UI に伝えることを想定ユースケースとしています

    • デフォルト実装は処理なしです

  • [FIX] IceConnectionState = disconnected では切断処理を行わないよう変更します

1.x
1.10.0
日時:

2019-11-14

対応 Sora:

19.04.9

対応 libwebrtc:

75.16.0

UPDATE
  • minSdkVersion を 21 にアップデートしました - com.squareup.okhttp3:okhttp 4.2.2 が minSdkVersion 21 以上にのみ対応するため

  • libwebrtc を 78.8.0 にアップデートしました

  • Android Studio 3.5.1 に対応しました

  • Kotlin を 1.3.50 にアップデートしました

  • Dokka を 0.10.0 にアップデートしました

  • com.android.tools.build:gradle を 3.5.2 にアップデートしました

  • com.squareup.okhttp3:okhttp を 4.2.2 にアップデートしました

  • com.google.code.gson:gson を 2.8.6 にアップデートしました

  • org.robolectric:robolectric を 4.3.1 にアップデートしました

  • AudioDeviceManager 生成時のパラメータをオプション SoraAudioOption に追加しました - audioSource: android.media.MediaRecorder.AudioSource のいずれか - useStereoInput: boolean - useStereoOutput: boolean

ADD
  • シグナリング connect メッセージに sdk_type, sdk_versionuser_agent を追加しました

  • シグナリング connect メッセージに audio.opus_params を追加しました

  • 1:N サイマルキャストの視聴に対応しました

CHANGE
  • 時雨堂ビルドの libwebrtc ライブラリ名称を変更しました - 旧: sora-webrtc-android 、 新: shiguredo-webrtc-android - transitive = truesora-android-sdk に依存している場合はアプリケーション側の変更は不要です

  • シグナリング connect メッセージから simulcast_rid を削除しました

FIX
  • 視聴のみかつ H.264 を指定した場合に接続できない現象を修正しました

1.9.0
日時:

2019-08-02

対応 Sora:

19.04.9

対応 libwebrtc:

75.16.0

UPDATE
  • libwebrtc を 75.16.0 にアップデートしました

  • Android Studio 3.4.2 に対応しました

  • Kotlin を 1.3.41 にアップデートしました

  • com.squareup.okhttp3:okhttp を 3.14.2 にアップデートしました

  • io.reactivex.rxjava2:rxjava を 2.2.10 にアップデートしました

  • androidx.test:core を 1.2.0 にアップデートしました

  • org.robolectric:robolectric を 4.3 にアップデートしました

ADD
  • SoraMediaOptionaudioBitrate 設定を追加しました

  • SoraMediaOptionaudioOption: SoraAudioOption を追加しました

  • SoraAudioOption に libwebrtc 独自の音声処理設定のキーを追加しました

    • media constraints キーとの対応は以下の通りです:

    • ECHO_CANCELLATION_CONSTRAINT: "googEchoCancellation" 設定のキー

    • AUTO_GAIN_CONTROL_CONSTRAINT: "googAutoGainControl" 設定のキー

    • HIGH_PASS_FILTER_CONSTRAINT: "googHighpassFilter" 設定のキー

    • NOISE_SUPPRESSION_CONSTRAINT: "googNoiseSuppression"" 設定のキー

  • SoraAudioOption に音声処理に関するインターフェースを追加しました

    • AudioDeviceModule インスタンスの設定、デフォルトは null で JavaAudioDeviceModule を内部で生成します

    • ハードウェアの AEC (acoustic echo canceler) の利用有無を設定します。デフォルトでは可能であれば利用します。

    • ハードウェアの NS (noise suppressor) の利用有無を設定します。デフォルトでは可能であれば利用します。

    • libwebrtc 独自の音声処理の無効化設定、デフォルトはすべて有効です。 - audioProcessingEchoCancellation: "googEchoCancellation" に対応しました - audioProcessingAutoGainControl: "googAutoGainControl" に対応しました - audioProcessingHighpassFilter: "googHighpassFilter" に対応しました - audioProcessingNoiseSuppression: "googNoiseSuppression"" に対応しました

    • これらの設定の組み合わせ方によっては、端末依存でマイクからの音声が取れないことがあるため、 設定を決める際には実端末での動作確認が必要です

  • SoraErrorReason に音声の録音(audio record)、音声トラック(audio track)のエラーを追加しました

  • SoraMediaChannel.Lister のコールバックに onError(SoraErrorReason, String) を追加しました

    • デフォルトで何もしない実装のため、ソースコード上の変更は不要です

    • このバージョンでは JavaAudioDeviceModule の audio record, audio track 関連のエラーが このコールバックを通して通知されます。

  • rid-based simulcast に部分的に対応しました

    • 現状では、ソフトウェアエンコーダーのみで動作します。

    • 映像コーデックは VP8 のみの対応しています。

    • fixed resolution と一緒に使うとクラッシュ(SEGV)することが分かっています。

  • getStats を定期的に実行し統計を取得する API を追加しました

CHANGE
  • org.webrtc.PeerConnectionFactory に明示的に JavaAudioDeviceModule を渡すように変更しました

  • org.webrtc.audio.JavaAudioDeviceModuleHardwareAcousticEchoCanceler, HardwareNoiseSuppressor をデフォルトで有効にしました

    • 無効化したい場合には、個別に SoraAudioOption で設定し SoraMediaOption 経由で設定を渡せます。

  • audio source 作成時のデフォルト MediaConstraint で、libwebrtc 独自の音声処理をすべて有効化しました

    • 無効化したい場合には、個別に SoraAudioOption で設定し SoraMediaOption 経由で設定を渡せます。

1.8.1
日時:

2019-04-18

対応 Sora:

19.04.0

対応 libwebrtc:

73.10.1

UPDATE
  • libwebrtc を 73.10.1 にアップデートしました

  • encoder/decoder の対応コーデックのログ出力を追加しました

  • Kotlin を 1.3.30 にアップデートしました

  • Android Studio 3.4.0 に対応しました

  • SoraMediaOptionVideoEncoderFactoryVideoDecoderFactory を指定するオプションを追加しました

    • [プレビュー版]

  • SoraMediaChannel のコンストラクタに @JvmOverloads を追加し、Java からオーバーロードされて見えるよう 変更しました

    • これにより第 6 引数のタイムアウト値を省略したコンストラクタを呼び出せるようになります。

  • シグナリング connect メッセージの metadata を文字列だけでなく任意の型を受け付けるよう変更しました

    • 値は gson で変換できる必要があります。 Map, List は利用できます。

    • 文字列化された JSON を受け取った場合には、1.8.0 までと同様に、そのまま文字列値として取扱います。

  • シグナリング connect メッセージに client_id フィールドを追加しました - Sora 19.04 より前のバージョンでは、このフィールドを文字列に設定するとエラーになります

  • シグナリング connect メッセージの signaling_notify_metadataSoraMediaChannel コンストラクタから 指定できるようにしました

    • 値は gson で変換できる必要があります。 Map, List は利用できます。

    • オプション引数のため、これまでのコードでは指定なしで動作します。

    • Java で書かれたアプリケーションでは SoraMediaChannel のコンストラクタで signalingNotifyMetadata を を指定するには clientId を渡す必要があります。アプリケーションとして指定しない場合には null を渡すことで シグナリング connect メッセージには client_id が含まれません。

  • シグナリングパラメータのフィールド、型を Sora 19.04 に合わせ更新しました

  • gradle.properties.example に Robolectric の設定 android.enableUnitTestBinaryResources=true を追加しました

  • Sora 19.04.0 での connection_id 導入に伴い、ローカルトラック判定を connection_id で行うよう変更しました

    • 以前のバージョンでも動作するよう、offer に connection_id がない場合はこれまでどおり client_id を使います。

  • シグナリング通知機能の network.status に対応しました

  • com.squareup.okhttp3:okhttp を 3.14.1 にアップデートしました

  • io.reactivex.rxjava2:rxandroid を 2.1.1 にアップデートしました

  • io.reactivex.rxjava2:rxjava を 2.2.8 にアップデートしました

CHANGE
  • kotlin-stdlib-jdk7 依存を kotlin-stdlib に変更しました

    • sora-android-sdk の minSdkVersion が 16 であるためです

ADD
  • CameraCapturerFactory に解像度維持を優先するオプションを追加しました

1.8.0
日時:

2019-02-01

対応 Sora:

18.10.5

対応 libwebrtc:

71.16.0

UPDATE
  • libwebrtc を 71.16.0 にアップデートしました

  • Kotlin を 1.3.20 にアップデートしました

  • libwebrtc の M72 をスキップしました

  • com.squareup.okhttp3:okhttp を 3.12.1 にアップデートしました

  • io.reactivex.rxjava2:rxjava を 2.2.6 にアップデートしました

  • Android Studio 3.3 に対応しました

  • com.github.dcendents:android-maven-gradle-plugin を 2.1 にアップデートしました

  • WebRTC 1.0 spec に一部追従しました

    • offerToReceiveAudio/offerToReceiveVideo から Transceiver API に変更しました。

    • onTrack, onRemoveTrack は libwebrtc android sdk で対応されていないため見送っています。

CHANGE
  • SDP semantics のデフォルト値を Unified Plan に変更しました

    • upstream のシグナリングで audio や video が false の場合でも、他の配信者の audio や video のトラックを受信する SDP が Sora から offer されるように変更されます。

    • Plan B のときには audio false のときには audio track が SDP に含まれず、 video が false のときには video のトラックが含まれていませんでした。 これは Plan B の制限による挙動でした。

1.7.1
日時:

2018-10-18

対応 Sora:

18.04.12

対応 libwebrtc:

70.14.0

UPDATE
  • libwebrtc を 70.14.0 にアップデートしました

  • com.google.code.gson:gson を 2.8.5 にアップデートしました

  • com.squareup.okhttp3:okhttp を 3.11.0 にアップデートしました

  • io.reactivex.rxjava2:rxandroid を 2.1.0 にアップデートしました

  • io.reactivex.rxjava2:rxjava を 2.2.2 にアップデートしました

  • io.reactivex.rxjava2:rxkotlin を 2.3.0 にアップデートしました

ADD
  • Unified Plan に試験的に対応しました

    • 正式対応ではありません

FIX
  • Sora で turn が無効の場合にシグナリングに失敗する問題を修正しました

1.7.0
日時:

2018-08-14

対応 Sora:

18.04.10

対応 libwebrtc:

68.10.1.1

UPDATE
  • Android Studio 3.1.4 に対応しました

  • libwebrtc を 68.10.1.1 にアップデートしました

ADD
  • webrtc-buildのバージョンと webrtc git のハッシュのログを追加しました

CHANGE
  • SoraSerivceUtil.isRunning を削除しました

    • Oreo で ActivityManager#getRunningSerivces が deprecated になったため

    • このユーティリティを利用していた場合はソースコードの変更が必要です

1.6.0
日時:

2018-07-24

対応 Sora:

18.04.10

対応 libwebrtc:

67.28.0.1

UPDATE
  • Android Studio 3.1.3 に対応しました

  • Kotlin を 1.2.51 にアップデートしました

  • PeerConnectionFactory を builder から作るよう修正しました

  • libwebrtc を 67.28.0.1 にアップデートしました

ADD
  • 時雨堂ビルドの libwebrtc AAR を jitpack.io 上にホストし、本 SDK からは build.gradle での依存としました

    • 本 SDK への依存設定に transitive を使っていないアプリケーションは別途依存を追加する必要があります

  • connect オプションの spotlight に対応しました

  • 映像の解像度の選択肢を増やしました

  • SoraMediaOption に enableCpuOveruseDetection を追加しました

  • SoraMediaOption に sdpSemantics を追加しました

    • ただし動作確認は Plan-B (PLAN_B) のみ

  • SoraMediaOption に tcpCandidatePolicy を追加しました - もともと内部的に用いていたオプションの格上げです - デフォルト値はこれまでと同様に ENABLED としています

  • NotificationMessageclientId を追加しました

    • 必須項目です (SDK が設定します)

  • NotificationMessageaudio, video, metadata, metadataList, channelId, spotlightId, fixed を追加しました

    • すべてオプション(nullable)項目です

  • SoraMediaChannel にシグナリング通知機能のメッセージ受信コールバックを追加しました

    • onNotificationMessage を実装することで独自のメッセージ処理が可能です

### CHANGE

  • NotificationMessagerole, connectionTime, numberOfConnections, numberOfUpstreamConnections, numberOfDownstreamConnections フィールドをオプション(nullable)に変更しました

    • 型として下位互換性を壊す変更です これらのフィールドを参照しているソースコードは修正の必要があります

  • スナップショット機能を削除しました

  • MediaStream#label() の代わりに id を使うよう変更しました

    • libwebrtc の変更の影響です

    • label() を用いているアプリケーションコードは id に変更してください

### FIX

  • 自分のストリーム判断に配信ストリームがある場合のみの条件があったが、マルチストリームの場合という 条件に置き換えました

    • single stream (pub, sub) およびマルチストリームではこの変更は影響ありません

    • スポットライトのみ影響があり、視聴モードでも自分の clientId が MSID のストリームについて onAddRemotestream イベントを発火させないようになっています

1.5.4
日時:

2018-03-28

対応 Sora:

18.02.2

対応 libwebrtc:

66.8.1

UPDATE
  • PeerConnectionFactory.createPeerConnection/3 deprecated に対応しました

1.5.3
日時:

2018-03-28

対応 Sora:

18.02.2

対応 libwebrtc:

66.8.1

UPDATE
  • libwebrtc を 66.8.1 にアップデートしました

  • Kotlin を 1.2.31 にアップデートしました

1.5.2
日時:

2018-03-07

対応 Sora:

18.02

対応 libwebrtc:

64.5.0

UPDATE
  • libwebrtc を 64.5.0 にアップデートしました

  • deprecated warning を修正しました

  • Signaling connect 時に client offer の SDP を追加しました

  • Kotlin 1.2.30 にアップデートしました

1.5.1
日時:

2018-02-16

対応 Sora:

18.01

対応 libwebrtc:

63.13.0

ADD
  • Sora Android SDK の API ドキュメントを追加しました

1.5.0
日時:

2018-02-15

対応 Sora:

18.01

対応 libwebrtc:

63.13.0

ADD
  • Sora のプッシュ API のメッセージを SoraMediaChannel.Listener に伝える機能を追加しました

1.4.1
日時:

2017-12-22

対応 Sora:

17.10

対応 libwebrtc:

63.13.0

UPDATE
  • 依存ライブラリのバージョンをアップデートしました

1.4.0
日時:

2017-12-22

対応 Sora:

17.10

対応 libwebrtc:

63.13.0

UPDATE
  • Android Studio 3.0 に対応しました

    • gradle: 4.1

    • android-maven-gradle-plugin: 2.0

  • Kotlin 1.2.10 にアップデートしました

1.3.1
日時:

2017-12-21

対応 Sora:

17.10

対応 libwebrtc:

63.13.0

UPDATE
  • libwebrtc を 63.13.0 にアップデートしました

  • Kotlin 1.1.51 にアップデートしました

1.3.0
日時:

2017-09-22

対応 Sora:

17.08

対応 libwebrtc:

61.5.0

FIX
  • 自身が down を持たない場合に multistream が有効にならない現象を修正しました

  • 自身が up を持たない場合にリモートストリームが通知されない現象を修正しました

1.2.0
日時:

2017-09-21

対応 Sora:

17.08

対応 libwebrtc:

61.5.0

UPDATE
  • libwebrtc のバージョンをアップデートしました

1.1.0
日時:

2017-09-07

対応 Sora:

17.08

対応 libwebrtc:

60.11.0

UPDATE
  • 依存ライブラリのバージョンをアップデートしました

ADD
  • sources jar 生成の設定を追加しました

  • libwebrtc.aar ダウンロードを gradle task 化しました

  • JitPack でにビルドと配布に対応しました

CHANGE
  • libwebrtc.aar を sora-android-sdk AAR に含めました

1.0.0
日時:

2017-08-30

対応 Sora:

17.08

対応 libwebrtc:

60.11.0

Sora Android SDK 最初のリリースです。

© Copyright 2018-2025, Shiguredo Inc. Created using Sphinx 8.2.3