Sora Android SDK ドキュメント¶
このドキュメントは Sora Android SDK バージョン 2025.2.0 に対応しています。
Sora 自体の製品お問い合わせは sora at shiguredo dot jp までお願い致します。 (このメールアドレスへの特定電子メールの送信を拒否いたします)
問い合わせについて¶
Sora Android SDK の質問などについては Discord の #sora-sdk-faq
をご利用ください。
ただし、 Sora のライセンス契約の有無に関わらず、応答時間と問題の解決を保証しませんのでご了承ください。
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 のライセンス契約の有無に関わらず、応答時間と問題の解決を保証しませんのでご了承ください。
またビルドやパッケージングに関する質問に対しては、コミュニティ管理者は回答は行いません。
リリースノート¶
- 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)
を追加しましたこれにより、Sora から切断された際の理由を詳細に取得できるようになりました
詳細は Sora からの切断理由を取得できる onClose の追加 を参照してください
破壊的変更¶
シグナリング type: connect メッセージの
multistream
を自動で true に設定する仕様を廃止しましたWebSocket が Sora から切断された際に受信したステータスコードが 1000 以外の場合でも onError を呼び出さないように変更しました
SoraMediaOption.videoCodec
が未設定の場合のデフォルト動作を変更しました詳細は SoraMediaOption.videoCodec 未設定時の動作変更 を参照してください
SoraMediaOption.audioCodec
が未設定の場合のデフォルト動作を変更しました詳細は SoraMediaOption.audioCodec 未設定時の動作変更 を参照してください
SoraMediaChannel.Listener の
onError(SoraMediaChannel, SoraErrorReason)
を廃止しました詳細は onError(SoraMediaChannel, SoraErrorReason) を廃止 を参照してください
解像度維持方法の fixedResolution を廃止し、 DegradationPreference を追加しました
詳細は 解像度維持方法の fixedResolution を廃止、 DegradationPreference を追加 を参照してください
非推奨情報¶
SoraMediaChannel.Listener
のonClose(SoraMediaChannel)
を非推奨にしました今後は
onClose(SoraMediaChannel, SoraCloseEvent)
を利用してください移行方法は Sora からの切断理由を取得できる onClose の追加 を参照してください
変更履歴¶
[CHANGE]
CameraCapturerFactory
初期化時の引数fixedResolution
を廃止しましたこれまでは
CameraCapturerFactory.create
の引数fixedResolution
に true を指定することにより送信する映像の解像度維持をすることができていましたが、この仕様を廃止しました。代替の機能として、
SoraMediaOption.degradationPreference
を追加しました
[CHANGE] connect メッセージの
multistream
を自動で true に設定する仕様を廃止しましたSoraMediaOption.enableSpotlight
を設定すると、内部で multistream を true に設定していましたが、この仕様を廃止しました以下の設定の組み合わに応じて自動で multistream を true に設定していましたが、この仕様を廃止しました
enableAudioDownstream
enableVideoDownstream
enableAudioUpstream
enableVideoUpstream
[CHANGE]
SignalingChannelImpl
のWebSocketListener.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.videoCodec
にSoraVideoOption.Codec.VP9
を設定する必要があります
[CHANGE]
SoraMediaOption.audioCodec
が未設定の場合の動作変更これまでは
SoraMediaOption.audioCodec
が未設定の場合、connect メッセージのaudio.codec_type
にデフォルトでOPUS
が設定され、送信されていました今回の変更により、未設定の場合は
audio.codec_type
を送信しなくなりました未設定の場合、Sora 側でデフォルトのオーディオコーデックとして
OPUS
が設定されますSoraMediaOption.audioCodec
が未設定であり、かつSoraMediaOption.audioOption.opusParams
を設定している場合は破壊的変更の影響を受けるため、明示的にSoraMediaOption.audioCodec
にSoraAudioOption.Codec.OPUS
を設定する必要があります
[CHANGE]
SoraMediaChannel.Listener
のonError(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.Listener
のonClose(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]
SoraMediaOption
にdegradationPreference
を追加しましたクライアント側の状況により設定した解像度やフレームレートを維持できなくなった場合にどのように質を下げるか制御できるオプションです
オプション追加前よりデフォルトの挙動で動作していたため互換性に影響はありません
[ADD] サイマルキャストの映像におけるエンコーディングパラメーター
scaleResolutionDownTo
を追加しましたscaleResolutionDownTo の詳細については Sora のドキュメントの サイマルキャスト機能 を参照してください
[ADD] Sora から DataChannel シグナリングを切断する際に
"type": "close"
メッセージを受信する機能を追加するDataChannel シグナリングが有効、かつ
ignore_disconnect_websocket
が true、かつ Sora の設定でdata_channel_signaling_close_message
が有効な場合に受信可能です受信したメッセージは
SoraCloseEvent
としてonClose(SoraMediaChannel, SoraCloseEvent?)
に通知されます
[ADD]
SoraMediaOption
にsoftwareVideoEncoderOnly
を追加しました映像配信時に端末のハードウェアエンコーダーを使わず、ソフトウェアエンコーダーのみで送信するためのオプションです
デフォルトは 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: switched
とtype: 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] 転送フィルター機能の設定を表すクラス
SoraForwardingFilterOption
にname
とpriority
を追加しました[ADD] 転送フィルターをリスト形式で指定するためのプロパティを追加しました
[FIX] SoraMediaChannel の
signalingMetadata
とsignalingNotifyMetadata
の Map オブジェクトに value が null のフィールドを設定した場合、そのフィールドが connect メッセージに含まれない問題を修正しましたsignalingMetadata
とsignalingNotifyMetadata
に設定する情報はユーザが任意に設定する項目であり 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]
NotificationMessage
のmetadata_list
を削除しました2022.1.0 の Sora で metadata_list が廃止されたためあわせて廃止します
metadata_list
はdata
に名称が変更されています
[CHANGE]
NotificationMessage
のchannel_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]
ForwardingFilter
のaction
を未指定にできるようにしました[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] 映像コーデックパラメータを追加しました
SoraMediaOption
にvideoVp9Params
,videoAv1Params
,videoH264Params
を追加しました詳細は 映像コーデックパラメーターの設定 をご確認ください
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]
SoraMediaOption
にaudioStreamingLanguageCode
を追加しました[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]
SoraMediaOption
にhardwareVideoEncoderResolutionAdjustment
を追加しました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]
SoraMediaChannel
にproxy
を追加し、接続時に HTTP プロキシの設定を追加できるようにしました詳細は HTTP プロキシ・サーバーの設定 をご確認ください
[ADD]
SoraMediaChannel
にbundleId
を追加しました
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]
SoraMediaChannel
にcontactSignalingEndpoint
を追加しました最初に type: connect を送信したエンドポイントが設定されます
[UPDATE]
SoraMediaOption
にrole
を追加しましたtype: connect の role を明示的に指定できるようになりました
DataChannel を利用したリアルタイムメッセージングのみで接続する ときに利用されることを想定しています
未指定の場合は、従来通り、 SDK が role を自動的に決定しますので影響はありません
[ADD] メッセージング機能に対応しました
詳細は メッセージング機能 をご確認ください
[FIX]
SoraMediaChannel.Listener
にonOfferMessage
を追加しました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 を追加しました
Sora クライアント要求仕様 に紐づく修正です
[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¶
H.264 で映像を送受信できない
Mate 20 Pro に限らず、古い HUAWEI 端末は H.264 に対応していない可能性があります
https://discord.com/channels/501033497255870474/645802833454694402/685719197069869082
非対応エンコーディングパラメーター¶
Sora Android SDK はサイマルキャストやマルチストリームで利用できるエンコーディングパラメーター adaptivePtime
に対応していません。
優先実装にて対応可能です。
FAQ¶
一般¶
Sora Android SDK のライセンスはなんですか?¶
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
チャンネルにお願いします。
ただし、 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 ではクライアント側の状況により設定した解像度やフレームレートを維持できなくなった場合にどのように質を下げるか制御できるパラメータ DegradationPreference
を SoraMediaOption
に追加し、
fixedResolution
による解像度維持は廃止しました。
これに伴い fixedResolution
は CameraCapturerFactory.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.CAMERA
と Manifest.permission.RECORD_AUDIO
の権限をリクエストします。
Sora に接続する¶
起動したアプリケーションの画面で、 START ボタンをタップすると Sora に接続します。 このとき、「写真と動画の撮影」と「音声の録音」の許可を求めるダイアログが表示されるので許可してください。
接続に成功するとカメラ(利用可能な場合は前面カメラを優先して使用)の映像が表示されます。
接続できなかった場合は Sora のエンドポイント URL やネットワークの状態を確認してください。
このアプリケーションでは、次のパラメータで Sora に接続しています。
Sora への接続
映像コーデック: VP9
音声コーデック: OPUS
双方向でビデオチャットするには、例えば、PC ブラウザから Sora DevTools でマルチストリーム接続 を行うと、クイックスタートアプリケーションに相手側の映像が表示されます。 もちろん、Android 端末をもうひとつ用意して本アプリケーションをインストール、起動しても よいですし、iOS アプリケーションとのビデオチャットも可能です。
参考¶
PC ブラウザからのアクセス: Sora 開発者ツール
Sora iOS SDK: Sora iOS SDK のドキュメント
シグナリング¶
概要¶
WebRTC SFU Sora に SDK を利用して接続する仕組みを シグナリング と呼びます。
WebRTC SFU Sora のシグナリングの仕様については以下をご確認ください。
シグナリングの手順¶
Sora へのシグナリングは次の手順で行います。
SoraMediaOption を準備する
映像と音声の送受信設定を行います。
映像の送信にはキャプチャラー、映像の送受信には EGL コンテキストが必要です。生成方法について video を参照してください。
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
映像の VP9 設定を指定します。詳細は 映像コーデックパラメーターの設定 を参照してください。
videoAv1Params
映像の AV1 設定を指定します。詳細は 映像コーデックパラメーターの設定 を参照してください。
videoH264Params
映像の H264 設定を指定します。詳細は 映像コーデックパラメーターの設定 を参照してください。
audioCodec
音声コーデックを指定します。デフォルトは OPUS です。
audioBitrate
音声ビットレートを指定します。
enableMultistream()
マルチストリーム機能 を有効にします。
enableSimulcast()
サイマルキャスト機能 を有効にします。
enableSpotlight()
スポットライト機能 を有効にします。
proxy
HTTP プロキシ・サーバーの設定 を行います。
forwardingFilterOption
転送フィルター機能 の設定を行います。
hardwareVideoEncoderResolutionAdjustment
解像度の縦横のピクセル数が指定した値の整数倍となるように調整します。デフォルトは 16 です。
degradationPreference
ネットワーク状況の逼迫等により、設定した解像度やフレームレートを維持できなくなった場合にどのように質を下げるか制御します。詳細は ネットワーク逼迫時の映像品質制御を設定する を参照してください。
SoraMediaChannel の主な設定内容¶
SoraMediaChannel の主な設定内容を次に示します。
以下の項目は必須で設定する項目です。signalingEndpoint, signalingEndpointCandidates についてはいずれかを設定します。listener は必須ではありませんが、通常アプリケーションでは SDK のイベントを受け取る必要があるため必須としています。
context
android.content.Context
を設定してください
signalingEndpoint
シグナリング URL を指定します。複数指定する場合は
signalingEndpointCandidates
を使用してください。
signalingEndpointCandidates
シグナリング URL を複数指定します。詳細は 複数のシグナリング URL を指定する を参照してください。
channelId
接続するチャネル ID を指定します。
mediaOption
listener
イベント通知をうけるための SoraMediaChannel.Listener を設定してください。
オプションで以下を設定することが可能です。利用する機能に応じて設定を行います。
dataChannelSignaling
DataChannel 経由のシグナリング を有効にします
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
を、 SoraMediaChannel の signalingMetadata
に値を設定します。
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.Listener の onOfferMessage
で通知されます。
認証サーバから払い出されたメタデータは 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
を、 SoraMediaChannel の signalingNotifyMetadata
に値を設定します。
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.Listener の onNotificationMessage
で通知されます。
シグナリング通知メタデータは 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.Listener の PushMessage で通知されます。
// 接続通知を受信するための 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 を経由したシグナリング通信を行う場合は SoraMediaChannel の dataChannelSignaling
に true
を設定します。
デフォルトの設定はいずれも無効です。
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 ドキュメントの転送フィルター機能 を参照してください。
この機能は SoraChannelRole
が SENDRECV
または RECVONLY
の場合にのみ利用できます。
フィルターを設定する¶
サーバー接続時に SoraMediaChannel
に forwardingFiltersOption
を設定します。
設定例¶
以下の例は、自分の接続に対して、以下の条件で映像または音声の受信をブロックします。
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 では上記の SoraMediaOption の videoVp9Params
, 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
です。
SurfaceViewRenderer
は android.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
を引数に取ります。
EGLContext
は org.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 です。
VideoEncoderFactory を設定しない場合の挙動¶
VideoEncoderFactory を設定しない場合は、以下のように VideoEncoderFactory が決定されます (Sora Android SDK の持つ VideoEncoderFactory は internal なので SDK ユーザーが直接利用することはできません)。
サイマルキャストが有効な場合
SimulcastVideoEncoderFactoryWrapper
それ以外
SoraDefaultVideoEncoderFactory
ソフトウェアエンコーダーの使用を強制する¶
Sora Android SDK ではデフォルトでハードウェアエンコーダーをメインに設定し、ソフトウェアエンコーダーをフォールバック先に指定します。
この挙動を変更してソフトウェアエンコーダーのみを利用するには SoraMediaOption の softwareVideoEncoderOnly: Boolean
に true
を設定してください。デフォルト値は 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()
メッセージを受信する¶
SoraMediaChannel.Listener.onDataChannel にて DataChannel の開始通知を受け取ることができます。また、利用可能な DataChannel 情報の参照が可能です。
SoraMediaChannel.Listener.onDataChannelMessage にてメッセージの受信を行います。
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)
}
}
メッセージを送信する¶
SoraMediaChannel.sendDataChannelMessage を利用してメッセージの送信を行います。String 型、ByteBuffer 型 に対応しています。
// メッセージ送信する
mediaChannel.sendDataChannelMessage("#spam", "Hello World")
DataChannel を利用したリアルタイムメッセージングのみで接続する¶
音声と映像を送受信せずにメッセージのみの送受信を行う方法の詳細については、 Sora のドキュメント 音声と映像を送受信せずにメッセージのみで接続する をご確認ください。 Sora Android SDK では、
SoraMediaOption.role
にSoraChannelRole.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 の onOfferMessage
と onDataChannelMessage
を利用して以下のように処理します。
SoraMediaChannel.Listener.onOfferMessage でヘッダーの長さ(バイト数)を取得する
SoraMediaChannel.Listener.onDataChannelMessage で受けとったメッセージを先頭からヘッダーの長さ分とそれ以降に分割する
以下はヘッダーに 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 初期化時に PeerConnectionOption
の getStatsIntervalMSec
に 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]
NotificationMessage
にturnTransportType
を追加しました[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:junit
を4.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.Listener
にonWarning
メソッドを追加しましたこのバージョンでは
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_version
とuser_agent
を追加しましたシグナリング connect メッセージに
audio.opus_params
を追加しました1:N サイマルキャストの視聴に対応しました
CHANGE¶
時雨堂ビルドの libwebrtc ライブラリ名称を変更しました - 旧:
sora-webrtc-android
、 新:shiguredo-webrtc-android
-transitive = true
でsora-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¶
SoraMediaOption
にaudioBitrate
設定を追加しましたSoraMediaOption
にaudioOption: 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)することが分かっています。
関連 issue: 10713 - Transceiver/encodings based simulcast does not work in desktop sharing
closed になっているため、libwebrtc の最新版では修正されている可能性があります。
getStats を定期的に実行し統計を取得する API を追加しました
CHANGE¶
org.webrtc.PeerConnectionFactory
に明示的にJavaAudioDeviceModule
を渡すように変更しましたlibwebrtc にて
org.webrtc.LegacyAudioDeviceModule
が無くなり、明示的に audio device module を 指定するよう変更されたため。7452 - Move Android audio code to webrtc/sdk/android - webrtc - Monorail - https://bugs.chromium.org/p/webrtc/issues/detail?id=7452
Use JavaAudioDeviceModule as default (Ib99adc50) · Gerrit Code Review - https://webrtc-review.googlesource.com/c/src/^/123887
org.webrtc.audio.JavaAudioDeviceModule
のHardwareAcousticEchoCanceler
,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 に対応しました
SoraMediaOption
にVideoEncoderFactory
、VideoDecoderFactory
を指定するオプションを追加しました[プレビュー版]
SoraMediaChannel
のコンストラクタに@JvmOverloads
を追加し、Java からオーバーロードされて見えるよう 変更しましたこれにより第 6 引数のタイムアウト値を省略したコンストラクタを呼び出せるようになります。
シグナリング connect メッセージの metadata を文字列だけでなく任意の型を受け付けるよう変更しました
値は gson で変換できる必要があります。
Map
,List
は利用できます。文字列化された JSON を受け取った場合には、1.8.0 までと同様に、そのまま文字列値として取扱います。
シグナリング connect メッセージに
client_id
フィールドを追加しました - Sora 19.04 より前のバージョンでは、このフィールドを文字列に設定するとエラーになりますシグナリング connect メッセージの
signaling_notify_metadata
をSoraMediaChannel
コンストラクタから 指定できるようにしました値は gson で変換できる必要があります。
Map
,List
は利用できます。オプション引数のため、これまでのコードでは指定なしで動作します。
Java で書かれたアプリケーションでは
SoraMediaChannel
のコンストラクタでsignalingNotifyMetadata
を を指定するにはclientId
を渡す必要があります。アプリケーションとして指定しない場合には null を渡すことで シグナリング connect メッセージにはclient_id
が含まれません。
シグナリングパラメータのフィールド、型を Sora 19.04 に合わせ更新しました
型定義は https://sora-doc.shiguredo.jp/SIGNALING_TYPE を参照してください。
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 をスキップしました
バグにより AAR のビルドはできるが動作しないためです。
そのバグは M73 branch では修正済みです: https://webrtc-review.googlesource.com/c/112283
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
としていますNotificationMessage
にclientId
を追加しました必須項目です (SDK が設定します)
NotificationMessage
にaudio
,video
,metadata
,metadataList
,channelId
,spotlightId
,fixed
を追加しましたすべてオプション(nullable)項目です
SoraMediaChannel
にシグナリング通知機能のメッセージ受信コールバックを追加しましたonNotificationMessage
を実装することで独自のメッセージ処理が可能です
### CHANGE
NotificationMessage
のrole
,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 最初のリリースです。