diff --git a/CHANGES.md b/CHANGES.md index 37d78ae0..fa2c94ef 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,145 +11,184 @@ ## develop +## 2022.4.0 + +- [CHANGE] type: offer の mid を必須にする + - この修正の結果、 type: offer に mid が含まれない場合は、エラーになります + - @enm10k +- [UPDATE] libwebrtc を 105.5195.0.0 に上げる + - @miosakuma +- [UPDATE] `compileSdkVersion` を 32 に上げる + - @miosakuma +- [UPDATE] `targetSdkVersion` を 32 に上げる + - @miosakuma +- [UPDATE] `Kotlin` のバージョンを 1.7.10 に上げる + - @miosakuma +- [UPDATE] Gradle を 7.5.1 に上げる + - @miosakuma +- [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 に上げる + - @miosakuma +- [FIX] mid を nullable に変更する + - 「type: offer の mid を必須にする」の対応で role が recvonly の時にエラーとなる不具合の修正 + - @miosakuma +- [FIX] offer で受信した encodings が反映されない不具合を修正する + - @miosakuma +- [FIX] EGLContext が取れなかった場合、DefaultVideoDecoderFactory, SoraDefaultVideoEncoderFactory を使用する + - EGLContext が取れなかった場合の Decoder を SoftwareVideoDecoderFactory から DefaultVideoDecoderFactory に変更する + - EGLContext が取れなかった場合の Encoder を SoftwareVideoEncoderFactory から SoraDefaultVideoEncoderFactory に変更する + - EGLContext は null でも Hardware を使用する MediaCodec は動作するため HW も動作可能な DefaultVideoDecoderFactory, SoraDefaultVideoEncoderFactory を使用する + - @miosakuma + ## 2022.3.0 - [CHANGE] SoraMediaOption に hardwareVideoEncoderResolutionAdjustment を追加する - - HW エンコーダーに入力されるフレームの解像度が指定された数の倍数になるように調整する - - デフォルトでは 16 が指定されている - - このオプションを実装した経緯は以下の通り - - 解像度が 16 の倍数でない場合、 HW エンコーダーの初期化がエラーになる変更が libwebrtc のメインストリームに入った - - 参照: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/sdk/android/src/java/org/webrtc/HardwareVideoEncoder.java;l=214-218;drc=0f50cc284949f225f663408e7d467f39d549d3dc - - Android CTS では、 HW エンコーダー (= MediaCodec) を 16で割り切れる解像度のみでテストしており、かつ 16 で割り切れない解像度で問題が発生する端末があったことが理由で上記の変更が行われた - - Sora Android SDK では一部の解像度が影響を受けるため、対応としてこのオプションを実装した - - Sora Android SDK では libwebrtc にパッチを当て、上記の HW エンコーダー初期化時の解像度のチェックを無効化している - - そのため、このフラグを SoraVideoOption.ResolutionAdjustment.NONE に設定することで、従来通り、解像度を調整することなく HW エンコーダーを利用できる - - より詳細な情報は以下のリンクを参照 - - https://bugs.chromium.org/p/chromium/issues/detail?id=1084702 - - 加えて、解像度調整ありでエンコーダーの初期化またはエンコード処理に失敗した際に、解像度調整なしで操作をリトライする処理も実装した - - Android OS 11 の Xperia 5 II で VGA のサイマルキャストを H.264 で送信しようとした際、解像度調整ありの場合 (= hardwareVideoEncoderResolutionAdjustment が MULTIPLE_OF_16 の場合) は HW エンコーダーの初期化が失敗するが、解像度調整なしの場合は成功する現象を確認したため、この処理を実装した - - @enm10k + - HW エンコーダーに入力されるフレームの解像度が指定された数の倍数になるように調整する + - デフォルトでは 16 が指定されている + - このオプションを実装した経緯は以下の通り + - 解像度が 16 の倍数でない場合、 HW エンコーダーの初期化がエラーになる変更が libwebrtc のメインストリームに入った + - 参照: + - Android CTS では、 HW エンコーダー (= MediaCodec) を 16で割り切れる解像度のみでテストしており、かつ 16 で割り切れない解像度で問題が発生する端末があったことが理由で上記の変更が行われた + - Sora Android SDK では一部の解像度が影響を受けるため、対応としてこのオプションを実装した + - Sora Android SDK では libwebrtc にパッチを当て、上記の HW エンコーダー初期化時の解像度のチェックを無効化している + - そのため、このフラグを SoraVideoOption.ResolutionAdjustment.NONE に設定することで、従来通り、解像度を調整することなく HW エンコーダーを利用できる + - より詳細な情報は以下のリンクを参照 + - + - 加えて、解像度調整ありでエンコーダーの初期化またはエンコード処理に失敗した際に、解像度調整なしで操作をリトライする処理も実装した + - Android OS 11 の Xperia 5 II で VGA のサイマルキャストを H.264 で送信しようとした際、解像度調整ありの場合 (= hardwareVideoEncoderResolutionAdjustment が MULTIPLE_OF_16 の場合) は HW エンコーダーの初期化が失敗するが、解像度調整なしの場合は成功する現象を確認したため、この処理を実装した + - @enm10k - [UPDATE] SoraMediaOption.enableSpotlight() の引数に `enableSimulcast` を追加し、サイマルキャスト無効の状態でスポットライト機能を利用できるようにする - @enm10k - [UPDATE] libwebrtc を 103.5060.4.0 に上げる - - @miosakuma + - @miosakuma - [UPDATE] 依存ライブラリー `org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9` を追加する - - @enm10k + - @enm10k - [UPDATE] システム条件を Android Studio 2021.2.1 に上げる - - @miosakuma + - @miosakuma - [ADD] HTTP プロキシに対応する - - @enm10k + - @enm10k - [ADD] SoraMediaChannel に `bundleId` を追加する - - @enm10k + - @enm10k ## 2022.2.0 - [CHANGE] Sora で廃止となった以下のフィールドを削除する - - NotificationMessage.numberOfUpstreamConnections - - NotificationMessage.numberOfDownstreamConnections - - ChannelAttendeesCount.numberOfUpstreams - - ChannelAttendeesCount.numberOfDownstreams - - @miosakuma + - NotificationMessage.numberOfUpstreamConnections + - NotificationMessage.numberOfDownstreamConnections + - ChannelAttendeesCount.numberOfUpstreams + - ChannelAttendeesCount.numberOfDownstreams + - @miosakuma - [UPDATE] SoraMediaChannel に contactSignalingEndpoint を追加する - - 最初に type: connect を送信したエンドポイントを表す - - この変更と併せて、 connectedSignalingEndpoint をセットするタイミングを、 type: connect 送信時から type: offer 送信時に変更した - - @enm10k + - 最初に type: connect を送信したエンドポイントを表す + - この変更と併せて、 connectedSignalingEndpoint をセットするタイミングを、 type: connect 送信時から type: offer 送信時に変更した + - @enm10k - [UPDATE] SoraMediaOption に role を追加する - - type: connect の role を明示的に指定できるようなった - - 未指定の場合は、従来通り、 SDK が role を自動的に決定する - - @enm10k + - type: connect の role を明示的に指定できるようなった + - 未指定の場合は、従来通り、 SDK が role を自動的に決定する + - @enm10k - [ADD] メッセージング機能に対応する - - @enm10k + - @enm10k - [FIX] SoraMediaChannel.Listener に onOfferMessage を追加する - - type: offer に含まれる metadata などにアクセスするために必要だった - - @enm10k + - type: offer に含まれる metadata などにアクセスするために必要だった + - @enm10k ## 2022.1.0 - [CHANGE] スポットライトレガシーを削除する - - @enm10k + - @enm10k - [UPDATE] libwebrtc を 96.4664.2.1 に上げる - - @enm10k + - @enm10k - [UPDATE] dokka を 1.5.31 に上げる - - @miosakuma + - @miosakuma - [ADD] 複数シグナリング URL の指定に対応する - - SoraMediaChannel に connectedSignalingEndpoint を追加する - - @enm10k + - SoraMediaChannel に connectedSignalingEndpoint を追加する + - @enm10k - [ADD] redirect メッセージに対応する - - @enm10k + - @enm10k - [ADD] type: disconnect に reason を追加する - - @enm10k + - @enm10k - [FIX] 視聴のみかつ H.264 した場合に接続できない問題についてのワークアラウンドを削除する - - SoraMediaOption.videoUpstreamContext が無く SoraMediaOption.videoDownstreamContext - がある場合はコーデック指定に依らず、 DefaultVideoEncoderFactory を使用する - - @miosakuma + - SoraMediaOption.videoUpstreamContext が無く SoraMediaOption.videoDownstreamContext + がある場合はコーデック指定に依らず、 DefaultVideoEncoderFactory を使用する + - @miosakuma - [FIX] libwebrtc の更新で発生するようになったサイマルキャストのクラッシュを修正する - - SimulcastVideoEncoderFactoryWrapper.kt の Fallback クラスが原因で java.lang.UnsupportedOperationException が発生していた - - 調査の結果、 Fallback クラスを削除できることがわかったので、その方向で修正した - - その過程で、 libwebrtc に適用している Android のサイマルキャスト対応のパッチを更新し、 SimulcastVideoEncoderFactory の fallback に null を指定できるようにした - - @enm10k + - SimulcastVideoEncoderFactoryWrapper.kt の Fallback クラスが原因で java.lang.UnsupportedOperationException が発生していた + - 調査の結果、 Fallback クラスを削除できることがわかったので、その方向で修正した + - その過程で、 libwebrtc に適用している Android のサイマルキャスト対応のパッチを更新し、 SimulcastVideoEncoderFactory の fallback に null を指定できるようにした + - @enm10k ## 2021.3 - [UPDATE] libwebrtc を 93.4577.8.2 に上げる - - @miosakuma + - @miosakuma - [FIX] stats メッセージに含まれる統計情報のフォーマットを修正する - - @enm10k + - @enm10k -## 2021.2 +## 2021.2 - [CHANGE] SoraMediaChannel のコンストラクタ引数 channelId の型を String? から String に変更する - - @enm10k + - @enm10k - [CHANGE] connect メッセージの定義を見直す - - connectionId の型を String? から String に変更する - - sdp_error を削除する - - @enm10k + - connectionId の型を String? から String に変更する + - sdp_error を削除する + - @enm10k - [UPDATE] スポットライト接続時に spotlight_focus_rid / spotlight_unfocus_rid を指定できるようにする - - @enm10k + - @enm10k - [UPDATE] offer に mid が含まれる場合は、 mid を利用して sender を設定する - - @enm10k + - @enm10k - [UPDATE] libwebrtc を 92.4515.9.1 に上げる - - @enm10k + - @enm10k - [UPDATE] 依存ライブラリーのバージョンを上げる - - `com.android.tools.build:gradle` を 4.2.2 に上げる - - @enm10k + - `com.android.tools.build:gradle` を 4.2.2 に上げる + - @enm10k - [UPDATE] JCenter への参照を取り除く - - @enm10k + - @enm10k - [UPDATE] AES-GCM を有効にする - - @miosakuma + - @miosakuma - [ADD] データチャネルシグナリングに対応する - - data_channel_signlaing, ignore_disconnect_websocket パラメータ設定を追加する - - onDataChannel コールバックを実装する - - 各 label に対応するデータチャネル関係のコールバックを実装する - - WebSocket 側の `type:switched` 受信の処理を追加する - - @shino + - data_channel_signlaing, ignore_disconnect_websocket パラメータ設定を追加する + - onDataChannel コールバックを実装する + - 各 label に対応するデータチャネル関係のコールバックを実装する + - WebSocket 側の `type:switched` 受信の処理を追加する + - @shino - [FIX] 終了前にシグナリング Disconnect メッセージ送信を追加する - - 状態により WebSocket, DataChannel どちらかで送信する - - @shino + - 状態により WebSocket, DataChannel どちらかで送信する + - @shino - [FIX] offer に data_channels が含まれない場合に対応する - - @shino + - @shino - [FIX] 接続 / 切断を検知する処理を改善する - - 修正前は IceConnectionState を参照していたが、 PeerConnectionState を参照するように修正する - - SoraErrorReason の以下の値を参照するコードは修正が必要となる - - ICE_FAILURE => PEER_CONNECTION_FAILED - - ICE_CLOSED_BY_SERVER => PEER_CONNECTION_CLOSED - - ICE_DISCONNECTED => PEER_CONNECTION_DISCONNECTED - - @enm10k + - 修正前は IceConnectionState を参照していたが、 PeerConnectionState を参照するように修正する + - SoraErrorReason の以下の値を参照するコードは修正が必要となる + - ICE_FAILURE => PEER_CONNECTION_FAILED + - ICE_CLOSED_BY_SERVER => PEER_CONNECTION_CLOSED + - ICE_DISCONNECTED => PEER_CONNECTION_DISCONNECTED + - @enm10k - [FIX] NotificationMessage に turnTransportType を追加する - - @enm10k + - @enm10k - [FIX] SoraSpotlightOption から simulcastRid を削除する - - スポットライトでは simulcast_rid を指定しても動作しない - - @enm10k + - スポットライトでは simulcast_rid を指定しても動作しない + - @enm10k - [FIX] 接続成功時のコールバックが複数回実行されないように修正する - - 修正前は、 PeerConnectionState が CONNECTED に遷移する度に PeerChannel.Listener.onConnect が実行される可能性があった - - 初回のみコールバックが実行されるように修正する - - @enm10k + - 修正前は、 PeerConnectionState が CONNECTED に遷移する度に PeerChannel.Listener.onConnect が実行される可能性があった + - 初回のみコールバックが実行されるように修正する + - @enm10k ## 2021.1.1 -- [FIX] Sora への接続時に simulcast_rid を指定するとエラーになる現象を修正する - - @enm10k - [CHANGE] enum class SimulcastRid の定義を `jp.shiguredo.sora.sdk.channel.signaling.message` から `jp.shiguredo.sora.sdk.channel.option.SoraVideoOption` に移動する - - @enm10k + - @enm10k +- [FIX] Sora への接続時に simulcast_rid を指定するとエラーになる現象を修正する + - @enm10k ## 2021.1 @@ -218,6 +257,10 @@ ## 2020.3 +- [CHANGE] 古いロール (`upstream`, `downstream`) を削除する + - @szktty +- [CHANGE] `SoraAudioOption.audioSource` のデフォルト値を `VOICE_COMMUNICATION` に変更する + - @szktty - [UPDATE] libwebrtc を 83.4103.12.2 に上げる - @szktty - [UPDATE] `com.android.tools.build:gradle` を 4.0.0 に上げる @@ -226,10 +269,6 @@ - @szktty - [ADD] 新しいロール (`sendonly`, `recvonly`, `sendrecv`) に対応する - @szktty -- [CHANGE] 古いロール (`upstream`, `downstream`) を削除する - - @szktty -- [CHANGE] `SoraAudioOption.audioSource` のデフォルト値を `VOICE_COMMUNICATION` に変更する - - @szktty ## 2020.2 @@ -278,475 +317,474 @@ ### UPDATE - `minSdkVersion` を 21 に上げる - - `com.squareup.okhttp3:okhttp` 4.2.2 が `minSdkVersion` 21 以上にのみ対応するため - - @szktty + - `com.squareup.okhttp3:okhttp` 4.2.2 が `minSdkVersion` 21 以上にのみ対応するため + - @szktty - libwebrtc を 78.8.0 に上げる - - @szktty + - @szktty - Android Studio 3.5.1 に対応する - - @szktty + - @szktty - Kotlin を 1.3.50 に上げる - - @szktty + - @szktty - Dokka を 0.10.0 に上げる - - @szktty + - @szktty - `com.android.tools.build:gradle` を 3.5.2 に上げる - - @szktty + - @szktty - `com.squareup.okhttp3:okhttp` を 4.2.2 に上げる - - @szktty + - @szktty - `com.google.code.gson:gson` を 2.8.6 に上げる - - @szktty + - @szktty - `org.robolectric:robolectric` を 4.3.1 に上げる - - @szktty + - @szktty - AudioDeviceManager 生成時のパラメータをオプション `SoraAudioOption` に追加する - - `audioSource`: `android.media.MediaRecorder.AudioSource` のいずれか - - `useStereoInput`: boolean - - `useStereoOutput`: boolean - - @shino + - `audioSource`: `android.media.MediaRecorder.AudioSource` のいずれか + - `useStereoInput`: boolean + - `useStereoOutput`: boolean + - @shino ### ADD - シグナリング connect メッセージに `sdk_type`, `sdk_version` と `user_agent` を追加する - - @shino + - @shino - シグナリング connect メッセージに `audio.opus_params` を追加する - - @shino + - @shino - 1:N サイマルキャストの視聴に対応する - - @shino + - @shino ### CHANGE - 時雨堂ビルドの libwebrtc ライブラリ名称を変更する - - 旧: `sora-webrtc-android` 、 新: `shiguredo-webrtc-android` - - `transitive = true` で `sora-android-sdk` に依存している場合はアプリ側の変更は不要 - - @shino + - 旧: `sora-webrtc-android` 、 新: `shiguredo-webrtc-android` + - `transitive = true` で `sora-android-sdk` に依存している場合はアプリ側の変更は不要 + - @shino - シグナリング connect メッセージから `simulcast_rid` を削除する - - @shino + - @shino ### FIX - 視聴のみかつ H.264 を指定した場合に接続できない現象を修正する - - @szktty + - @szktty ## 1.9.0 ### UPDATE - libwebrtc を 75.16.0 に上げる - - @shino + - @shino - Android Studio 3.4.2 に対応する - - @shino + - @shino - Kotlin を 1.3.41 に上げる - - @shino + - @shino - `com.squareup.okhttp3:okhttp` を 3.14.2 に上げる - - @shino + - @shino - `io.reactivex.rxjava2:rxjava` を 2.2.10 に上げる - - @shino + - @shino - `androidx.test:core` を 1.2.0 に上げる - - @shino + - @shino - `org.robolectric:robolectric` を 4.3 に上げる - - @shino + - @shino ### ADD - `SoraMediaOption` に `audioBitrate` 設定を追加する - - @shino + - @shino - `SoraMediaOption` に `audioOption: SoraAudioOption` を追加する - - @shino + - @shino - `SoraAudioOption` に libwebrtc 独自の音声処理設定のキーを追加する - - media constraints キーとの対応は以下の通り: - - `ECHO_CANCELLATION_CONSTRAINT`: `"googEchoCancellation"` 設定のキー - - `AUTO_GAIN_CONTROL_CONSTRAINT`: `"googAutoGainControl"` 設定のキー - - `HIGH_PASS_FILTER_CONSTRAINT`: `"googHighpassFilter"` 設定のキー - - `NOISE_SUPPRESSION_CONSTRAINT`: `"googNoiseSuppression""` 設定のキー - - @shino + - media constraints キーとの対応は以下の通り: + - `ECHO_CANCELLATION_CONSTRAINT`: `"googEchoCancellation"` 設定のキー + - `AUTO_GAIN_CONTROL_CONSTRAINT`: `"googAutoGainControl"` 設定のキー + - `HIGH_PASS_FILTER_CONSTRAINT`: `"googHighpassFilter"` 設定のキー + - `NOISE_SUPPRESSION_CONSTRAINT`: `"googNoiseSuppression""` 設定のキー + - @shino - `SoraAudioOption` に音声処理に関するインターフェースをを追加する - - AudioDeviceModule インスタンスの設定、デフォルトは null で `JavaAudioDeviceModule` を内部で生成する - - ハードウェアの AEC (acoustic echo canceler) の利用有無、デフォルトでは可能な場合利用する - - ハードウェアの NS (noise suppressor) の利用有無、デフォルトでは可能な場合利用する - - libwebrtc 独自の音声処理の無効化設定、デフォルトはすべて有効。 - - `audioProcessingEchoCancellation`: `"googEchoCancellation"` に対応 - - `audioProcessingAutoGainControl`: `"googAutoGainControl"` に対応 - - `audioProcessingHighpassFilter`: `"googHighpassFilter"` に対応 - - `audioProcessingNoiseSuppression`: `"googNoiseSuppression""` に対応 - - これらの設定の組み合わせ方によっては、端末依存でマイクからの音声が取れないことがあるため、 + - AudioDeviceModule インスタンスの設定、デフォルトは null で `JavaAudioDeviceModule` を内部で生成する + - ハードウェアの AEC (acoustic echo canceler) の利用有無、デフォルトでは可能な場合利用する + - ハードウェアの NS (noise suppressor) の利用有無、デフォルトでは可能な場合利用する + - libwebrtc 独自の音声処理の無効化設定、デフォルトはすべて有効。 + - `audioProcessingEchoCancellation`: `"googEchoCancellation"` に対応 + - `audioProcessingAutoGainControl`: `"googAutoGainControl"` に対応 + - `audioProcessingHighpassFilter`: `"googHighpassFilter"` に対応 + - `audioProcessingNoiseSuppression`: `"googNoiseSuppression""` に対応 + - これらの設定の組み合わせ方によっては、端末依存でマイクからの音声が取れないことがあるため、 設定を決める際には実端末での動作確認が必要 - - @shino + - @shino - `SoraErrorReason` に音声の録音(audio record)、音声トラック(audio track)のエラーを追加する - - @shino + - @shino - `SoraMediaChannel.Lister` のコールバックに `onError(SoraErrorReason, String)` を追加する - - デフォルトで何もしない実装のため、ソースコード上の変更は不要 - - このバージョンでは `JavaAudioDeviceModule` の audio record, audio track 関連のエラーが + - デフォルトで何もしない実装のため、ソースコード上の変更は不要 + - このバージョンでは `JavaAudioDeviceModule` の audio record, audio track 関連のエラーが このコールバックを通して通知される - - @shino + - @shino - rid-based simulcast に部分的に対応する - - 現状では、ソフトウェアエンコーダの配信のみで動作する - - 映像コーデックは VP8 のみの対応する - - fixed resolution と一緒に使うとクラッシュ(SEGV)することが分かっている - - 関連してそうな issue: 10713 - Transceiver/encodings based simulcast does not work in desktop sharing - - https://bugs.chromium.org/p/webrtc/issues/detail?id=10713 - - closed になっているため、libwebrtc の最新版では修正されている可能性あり - - @shino + - 現状では、ソフトウェアエンコーダの配信のみで動作する + - 映像コーデックは VP8 のみの対応する + - fixed resolution と一緒に使うとクラッシュ(SEGV)することが分かっている + - 関連してそうな issue: 10713 - Transceiver/encodings based simulcast does not work in desktop sharing + - + - closed になっているため、libwebrtc の最新版では修正されている可能性あり + - @shino - getStats を定期的に実行し統計を取得する API を追加する - - @shino + - @shino ### CHANGE - `org.webrtc.PeerConnectionFactory` に明示的に `JavaAudioDeviceModule` を渡すように変更する - - libwebrtc にて `org.webrtc.LegacyAudioDeviceModule` が無くなり、明示的に audio device module を + - 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 - - @shino + - 7452 - Move Android audio code to webrtc/sdk/android - webrtc - Monorail + - + - Use JavaAudioDeviceModule as default (Ib99adc50) · Gerrit Code Review + - + - @shino - `org.webrtc.audio.JavaAudioDeviceModule` の `HardwareAcousticEchoCanceler`, `HardwareNoiseSuppressor` をデフォルトで有効にする - - 無効化したい場合には、個別に `SoraAudioOption` で設定し `SoraMediaOption` 経由で渡せる - - @shino + - 無効化したい場合には、個別に `SoraAudioOption` で設定し `SoraMediaOption` 経由で渡せる + - @shino - audio source 作成時のデフォルト `MediaConstraint` で、audio processing の無効化をなくす - - 無効化したい場合には、個別に `SoraAudioOption` で設定し `SoraMediaOption` 経由で渡せる - - @shino - + - 無効化したい場合には、個別に `SoraAudioOption` で設定し `SoraMediaOption` 経由で渡せる + - @shino ## 1.8.1 ### UPDATE - libwebrtc を 73.10.1 に上げる - - @shino + - @shino - encoder/decoder の対応コーデックのログ出力コメントを追加する - - @shino + - @shino - Kotlin を 1.3.30 に上げる - - @shino + - @shino - Android Studio 3.4.0 に対応する - - @shino + - @shino - `SoraMediaOption` に `VideoEncoderFactory`、`VideoDecoderFactory` を指定するオプションを追加する - - [プレビュー版] - - @shino + - [プレビュー版] + - @shino - `SoraMediaChannel` のコンストラクタに `@JvmOverloads` を追加し、Java からオーバーロードされて 見えるよう変更する - - これにより第 6 引数のタイムアウト値を省略したコンストラクタを呼び出せるようになる - - @shino + - これにより第 6 引数のタイムアウト値を省略したコンストラクタを呼び出せるようになる + - @shino - シグナリング connect メッセージの metadata を文字列だけでなく任意の型を受け付けるよう変更する - - 値は gson で変換できる必要がある - - 文字列化された JSON を受け取った場合には、1.8.0 までと同様に、そのまま文字列値として取扱う - - @shino + - 値は gson で変換できる必要がある + - 文字列化された JSON を受け取った場合には、1.8.0 までと同様に、そのまま文字列値として取扱う + - @shino - シグナリング connect メッセージに `client_id` フィールドを追加する - - Sora 19.04 より前のバージョンでは、このフィールドを文字列に設定するとエラーになる - - @shino + - Sora 19.04 より前のバージョンでは、このフィールドを文字列に設定するとエラーになる + - @shino - シグナリング connect メッセージの `signaling_notify_metadata` を `SoraMediaChannel` コンストラクタから 指定できるようにする - - 値は gson で変換できる必要がある - - オプション引数のため、これまでのコードでは指定なしで動作する - - Java で書かれたアプリケーションでは `SoraMediaChannel` のコンストラクタで `signalingNotifyMetadata` を + - 値は gson で変換できる必要がある + - オプション引数のため、これまでのコードでは指定なしで動作する + - Java で書かれたアプリケーションでは `SoraMediaChannel` のコンストラクタで `signalingNotifyMetadata` を を指定するには `clientId` を渡す必要がある。アプリケーションとして指定しない場合には null を渡すことで シグナリング connect メッセージには `client_id` が含まれない。 - - @shino + - @shino - シグナリングパラメータのフィールド、型を Sora 19.04 に合わせ更新する - - 型定義は https://sora.shiguredo.jp/doc/SIGNALING_TYPE.html を参照 - - @shino + - 型定義は を参照 + - @shino - `gradle.properties.example` に Robolectric の設定 `android.enableUnitTestBinaryResources=true` を追加する - - @shino + - @shino - Sora 19.04.0 での `connection_id` 導入に伴い、ローカルトラック判定を `connection_id` で行うよう変更する - - 以前のバージョンでも動作するよう、offer に `connection_id` がない場合はこれまでどおり `client_id` を使う - - @shino + - 以前のバージョンでも動作するよう、offer に `connection_id` がない場合はこれまでどおり `client_id` を使う + - @shino - シグナリング通知機能の network.status に対応する - - @shino + - @shino - `com.squareup.okhttp3:okhttp` を 3.14.1 に上げる - - @shino + - @shino - `io.reactivex.rxjava2:rxandroid` を 2.1.1 に上げる - - @shino + - @shino - `io.reactivex.rxjava2:rxjava` を 2.2.8 に上げる - - @shino + - @shino ### CHANGE - `kotlin-stdlib-jdk7` 依存を `kotlin-stdlib` に変更する - - `minSdkVersion` が 16 であるため - - @shino + - `minSdkVersion` が 16 であるため + - @shino ### ADD - `CameraCapturerFactory` に解像度維持を優先するオプションを追加した - - @shino + - @shino ## 1.8.0 ### UPDATE - libwebrtc を 71.16.0 に上げる - - @shino + - @shino - Kotlin を 1.3.20 に上げる - - @shino + - @shino - libwebrtc の M72 をスキップする - - バグによりビルドは出来るが動作しないため - - そのバグは M73 branch では修正済み: https://webrtc-review.googlesource.com/c/112283 - - @shino + - バグによりビルドは出来るが動作しないため + - そのバグは M73 branch では修正済み: + - @shino - `com.squareup.okhttp3:okhttp` を 3.12.1 に上げる - - @shino + - @shino - `io.reactivex.rxjava2:rxjava` を 2.2.6 に上げる - - @shino + - @shino - Android Studio 3.3 に対応する - - @shino + - @shino - `com.github.dcendents:android-maven-gradle-plugin` を 2.1 に上げる - - @shino + - @shino - WebRTC 1.0 spec に一部追従する - - offerToReceiveAudio/offerToReceiveVideo から Transceiver API に変更する。 - - onTrack, onRemoveTrack は libwebrtc android sdk で対応されていないため見送った。 - - @shino + - offerToReceiveAudio/offerToReceiveVideo から Transceiver API に変更する。 + - onTrack, onRemoveTrack は libwebrtc android sdk で対応されていないため見送った。 + - @shino ### CHANGE - SDP semantics のデフォルト値を Unified Plan に変更する - - upstream のシグナリングで audio や video が false の場合でも、他の配信者の + - upstream のシグナリングで audio や video が false の場合でも、他の配信者の audio や video のトラックを受信する SDP が Sora から offer されるように変更される。 - - Plan B のときには audio false のときには audio track が SDP に含まれず、 + - Plan B のときには audio false のときには audio track が SDP に含まれず、 video が false のときには video のトラックが含まれていなかった。 これは Plan B の制限による挙動であった。 - - @shino + - @shino ## 1.7.1 ### UPDATE - dokka を 0.9.17 に上げる - - 不要な generated クラスの HTML が出力されなくなった - - sora-android-sdk-doc の api doc はすでに 0.9.17 生成版で更新済み - - @shino + - 不要な generated クラスの HTML が出力されなくなった + - sora-android-sdk-doc の api doc はすでに 0.9.17 生成版で更新済み + - @shino - Kotlin を 1.2.71 に上げる - - @shino + - @shino - `com.google.code.gson:gson` を 2.8.5 に上げる - - @shino + - @shino - `com.squareup.okhttp3:okhttp` を 3.11.0 に上げる - - @shino + - @shino - `io.reactivex.rxjava2:rxandroid` を 2.1.0 に上げる - - @shino + - @shino - `io.reactivex.rxjava2:rxjava` を 2.2.2 に上げる - - @shino + - @shino - `io.reactivex.rxjava2:rxkotlin` を 2.3.0 に上げる - - @shino + - @shino - Android Studio 3.2.1 に対応する - - @shino + - @shino - libwebrtc を 70.14.0 に上げる - - @shino + - @shino ### ADD - Unified Plan に試験的に対応する - - @shino + - @shino ### FIX - Sora サーバで turn が無効の場合にシグナリングに失敗する問題を修正する - - @shino + - @shino ## 1.7.0 ### UPDATE - Android Studio 3.1.4 に対応する - - @shino + - @shino - libwebrtc を 68.10.1.1 に上げる - - @shino + - @shino ### ADD - webrtc-buildのバージョンと webrtc git のハッシュのログを追加した - - @shino + - @shino ### CHANGE - SoraSerivceUtil.isRunning を削除した - - Oreo で `ActivityManager#getRunningSerivces` が deprecated になったため - - @shino + - Oreo で `ActivityManager#getRunningSerivces` が deprecated になったため + - @shino ## 1.6.0 ### UPDATE - Android Studio 3.1.3 に対応する - - @shino + - @shino - Kotlin を 1.2.51 に上げる - - @shino + - @shino - PeerConnectionFactory を builder から作るよう修正する - - @shino + - @shino - libwebrtc を 67.28.0.1 に上げる - - @shino + - @shino ### ADD - 時雨堂ビルドの libwebrtc AAR を jitpack.io 上にホストする - - @shino + - @shino - jitpack.io 化に伴い libwebrtc バージョンを 66.8.1.1 とする - - バイナリとしては 66.8.1 と同一 - - @shino + - バイナリとしては 66.8.1 と同一 + - @shino - connect オプションの spotlight に対応する - - @shino + - @shino - 映像の解像度の選択肢を増やした - - @shino + - @shino - SoraMediaOption に enableCpuOveruseDetection を追加する - - @shino + - @shino - SoraMediaOption に sdpSemantics を追加する - - ただし動作確認は Plan-B のみ - - @shino + - ただし動作確認は Plan-B のみ + - @shino - SoraMediaOption に tcpCandidatePolicy を追加する - - もともと内部的に用いていたオプションの格上げ - - デフォルト値はこれまでと同様に ENABLED - - @shino + - もともと内部的に用いていたオプションの格上げ + - デフォルト値はこれまでと同様に ENABLED + - @shino - `NotificationMessage` に `clientId` を追加する - - どちらも必須 - - @shino + - どちらも必須 + - @shino - `NotificationMessage` に `audio`, `video`, `metadata`, `metadataList`, `channelId`, `spotlightId`, `fixed` を追加する - - すべてオプション(nullable) - - @shino + - すべてオプション(nullable) + - @shino - `SoraMediaChannel` にシグナリング通知機能のメッセージ受信コールバックを追加する - - @shino + - @shino ### CHANGE - MediaStream#label() の代わりに id を使うよう変更する - - @shino + - @shino - `NotificationMessage` の `role`, `connectionTime`, `numberOfConnections`, `numberOfUpstreamConnections`, `numberOfDownstreamConnections` フィールドをオプション(nullable)に変更する - - 型チェックとして下位互換性を壊す変更 - - これらのフィールドを参照しているソースコードは修正の必要がある - - @shino + - 型チェックとして下位互換性を壊す変更 + - これらのフィールドを参照しているソースコードは修正の必要がある + - @shino - スナップショット機能を削除した - - @shino + - @shino ### FIX - 自分のストリーム判断に配信ストリームがある場合のみの条件があったが、マルチストリームの場合という 条件に置き換える - - single stream (pub, sub) およびマルチストリームではこの変更は影響なし - - スポットライトのみ影響があり、視聴モードでも自分の `clientId` が MSID のストリームについて + - single stream (pub, sub) およびマルチストリームではこの変更は影響なし + - スポットライトのみ影響があり、視聴モードでも自分の `clientId` が MSID のストリームについて `onAddRemotestream` イベントを発火させないようになる - - @shino + - @shino ## 1.5.4 ### UPDATE - PeerConnectionFactory.createPeerConnection/3 deprecated に対応する - - @shino + - @shino ## 1.5.3 ### UPDATE - libwebrtc を 66.8.1 に上げる - - @shino + - @shino - Kotlin を 1.2.31 に上げる - - @shino + - @shino ## 1.5.2 ### UPDATE - libwebrtc を 64.5.0 に上げる - - @shino + - @shino - deprecated warning を潰す - - @shino + - @shino - Signaling connect 時に client offer の SDP を載せる - - @shino + - @shino - Kotlin 1.2.30 に上げる - - @shino + - @shino - libjingle のデバッグログ有効化フラグを追加した - - @shino + - @shino - Signaling が 1000 以外 で close した時に warning ログを出すよう変更する - - @shino + - @shino ### FIX - PeerConnectionFactory 生成を UI thread 上で行うよう修正する - - @shino + - @shino ## 1.5.1 ### ADD - Kotlin doc comment ををいくつかの定義に追加する - - @shino + - @shino ## 1.5.0 ### ADD - Sora のプッシュ API のメッセージを SoraMediaChannel.Listener に伝える機能を追加する - - @shino + - @shino ## 1.4.1 ### UPDATE - 依存ライブラリのバージョンを上げる - - @shino + - @shino ## 1.4.0 ### CHANGE - AAR に release classifier が付かないようにする - - @shino + - @shino ### UPDATE - Android Studio 3.0 に対応する - - gradle: 4.1 - - android-maven-gradle-plugin: 2.0 - - @shino + - gradle: 4.1 + - android-maven-gradle-plugin: 2.0 + - @shino - Kotlin 1.2.10 に上げる - - @shino + - @shino ## 1.3.1 ### UPDATE - libwebrtc を 63.13.0 に上げる - - @shino + - @shino - Kotlin 1.1.51 に上げる - - @shino + - @shino - CircleCI でのビルドを設定した - - @shino + - @shino ## 1.3.0 ### FIX - 自身が down を持たない場合に multistream が有効にならない現象を修正する - - @shino + - @shino - 自身が up を持たない場合にリモートストリームが通知されない現象を修正する - - @shino + - @shino ## 1.2.0 ### UPDATE - libwebrtc を 61.5.0 に上げる - - @shino + - @shino ## 1.1.0 ### UPDATE - 依存ライブラリのバージョンを上げる - - @shino + - @shino ### ADD - sources jar を生成する - - @shino + - @shino - libwebrtc.aar ダウンロードを gradle task 化する - - @shino + - @shino - JitPack に対応する - - @shino + - @shino ### CHANGE - libwebrtc.aar を sora-android-sdk の release AAR に含める - - @shino + - @shino ## 1.0.0 - 最初のリリース - - @shino + - @shino diff --git a/README.md b/README.md index 91c69ff8..87070dd6 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Sora Android SDK [![Release](https://jitpack.io/v/shiguredo/sora-android-sdk.svg)](https://jitpack.io/#shiguredo/sora-android-sdk) -[![libwebrtc](https://img.shields.io/badge/libwebrtc-103.5060-blue.svg)](https://chromium.googlesource.com/external/webrtc/+/branch-heads/5060) +[![libwebrtc](https://img.shields.io/badge/libwebrtc-105.5195-blue.svg)](https://chromium.googlesource.com/external/webrtc/+/branch-heads/5195) [![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/shiguredo/sora-android-sdk.svg)](https://github.com/shiguredo/sora-android-sdk.svg) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) @@ -22,7 +22,7 @@ Please read https://github.com/shiguredo/oss before use. - Android 5 以降 (エミュレーターでの動作は保証しません) - Android Studio 2021.2.1 以降 -- WebRTC SFU Sora 2022.1 以降 +- WebRTC SFU Sora 2022.1.1 以降 ## サンプル diff --git a/build.gradle b/build.gradle index e06dbd30..d1256298 100644 --- a/build.gradle +++ b/build.gradle @@ -3,10 +3,10 @@ apply plugin: "org.ajoberstar.grgit" apply plugin: 'org.jetbrains.dokka' buildscript { - ext.kotlin_version = '1.6.10' - ext.libwebrtc_version = '103.5060.4.0' + ext.kotlin_version = '1.7.10' + ext.libwebrtc_version = '105.5195.0.0' - ext.dokka_version = '1.6.10' + ext.dokka_version = '1.7.10' repositories { google() @@ -15,14 +15,14 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.0.4' + classpath 'com.android.tools.build:gradle:7.2.2' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}" - classpath 'org.ajoberstar.grgit:grgit-gradle:4.1.1' + classpath 'org.ajoberstar.grgit:grgit-gradle:5.0.0' classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}" - classpath "com.github.ben-manes:gradle-versions-plugin:0.41.0" - classpath "org.jlleitschuh.gradle:ktlint-gradle:10.2.1" + classpath "com.github.ben-manes:gradle-versions-plugin:0.42.0" + classpath "org.jlleitschuh.gradle:ktlint-gradle:10.3.0" } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2e6e5897..ae04661e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/sora-android-sdk/build.gradle b/sora-android-sdk/build.gradle index 59564d64..f896c6d2 100644 --- a/sora-android-sdk/build.gradle +++ b/sora-android-sdk/build.gradle @@ -7,11 +7,11 @@ apply plugin: 'org.jlleitschuh.gradle.ktlint' group = 'com.github.shiguredo' android { - compileSdkVersion 30 + compileSdkVersion 32 defaultConfig { minSdkVersion 21 - targetSdkVersion 30 + targetSdkVersion 32 buildConfigField("String", "VERSION_NAME", "\"${grgit.describe()}\"") buildConfigField("String", "REVISION", "\"${grgit.head().abbreviatedId}\"") @@ -71,7 +71,7 @@ dokkaHtml.configure { } ktlint { - version = "0.43.2" + version = "0.45.2" android = false outputToConsole = true reporters { @@ -86,9 +86,9 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-reflect:${kotlin_version}" // required by "signaling" part - implementation 'com.google.code.gson:gson:2.8.9' - implementation 'com.squareup.okhttp3:okhttp:4.9.3' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' + implementation 'com.google.code.gson:gson:2.9.1' + implementation 'com.squareup.okhttp3:okhttp:4.10.0' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4' // required by "rtc" part implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' @@ -97,7 +97,7 @@ dependencies { testImplementation 'junit:junit:4.13.2' testImplementation 'androidx.test:core:1.4.0' - testImplementation('org.robolectric:robolectric:4.7.3') { + testImplementation('org.robolectric:robolectric:4.8.1') { exclude group: 'com.google.auto.service', module: 'auto-service' } testImplementation "org.jetbrains.kotlin:kotlin-test-junit:${kotlin_version}" diff --git a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/camera/CameraCapturerFactory.kt b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/camera/CameraCapturerFactory.kt index 6965a48b..368e92b4 100644 --- a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/camera/CameraCapturerFactory.kt +++ b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/camera/CameraCapturerFactory.kt @@ -72,7 +72,7 @@ class CameraCapturerFactory { private fun createCapturer(enumerator: CameraEnumerator, frontFacingFirst: Boolean): CameraVideoCapturer? { var capturer: CameraVideoCapturer? = null enumerator.deviceNames.forEach { - deviceName -> + deviceName -> if (capturer == null) { capturer = findDeviceCamera(enumerator, deviceName, frontFacingFirst) } @@ -81,7 +81,7 @@ class CameraCapturerFactory { return capturer } enumerator.deviceNames.forEach { - deviceName -> + deviceName -> if (capturer == null) { capturer = findDeviceCamera(enumerator, deviceName, !frontFacingFirst) } diff --git a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/SoraMediaChannel.kt b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/SoraMediaChannel.kt index c5a13ef2..270d9641 100644 --- a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/SoraMediaChannel.kt +++ b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/SoraMediaChannel.kt @@ -663,7 +663,8 @@ class SoraMediaChannel @JvmOverloads constructor( |signalingMetadata = ${this.signalingMetadata} |clientId = ${this.clientId} |bundleId = ${this.bundleId} - |signalingNotifyMetadata = ${this.signalingNotifyMetadata}""".trimMargin() + |signalingNotifyMetadata = ${this.signalingNotifyMetadata} + """.trimMargin() ) if (closing) { @@ -819,7 +820,7 @@ class SoraMediaChannel @JvmOverloads constructor( }, onError = { val msg = "[channel:$role] failure in handleInitialOffer: ${it.message}" - SoraLogger.w(TAG, msg) + SoraLogger.w(TAG, msg, it) disconnect(SoraDisconnectReason.SIGNALING_FAILURE) } ) @@ -967,7 +968,7 @@ class SoraMediaChannel @JvmOverloads constructor( } private fun sendDisconnectIfNeeded(disconnectReason: SoraDisconnectReason) { - val state = peer?.connectionState() ?: null + val state = peer?.connectionState() SoraLogger.d( TAG, "[channel:$role] sendDisconnectIfNeeded switched=$switchedToDataChannel, " + diff --git a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/PeerChannel.kt b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/PeerChannel.kt index efa79133..12c726cc 100644 --- a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/PeerChannel.kt +++ b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/PeerChannel.kt @@ -116,10 +116,8 @@ class PeerChannelImpl( private val localAudioManager = componentFactory.createAudioManager() private val localVideoManager = componentFactory.createVideoManager() - private var localStream: MediaStream? = null - private var videoSender: RtpSender? = null - private var audioSender: RtpSender? = null + private val localStreamId: String = UUID.randomUUID().toString() // offer.data_channels の {label:..., compress:...} から compress が true の label リストを作る private var compressLabels: List = emptyList() @@ -316,17 +314,26 @@ class PeerChannelImpl( } return@flatMap createAnswer() }.flatMap { - answer -> + answer -> return@flatMap setLocalDescription(answer) } } + private fun setTrack(mid: String, track: MediaStreamTrack): RtpSender { + val transceiver = this.conn?.transceivers?.find { it.mid == mid } + val sender = transceiver!!.sender + transceiver!!.direction = RtpTransceiver.RtpTransceiverDirection.SEND_ONLY + sender!!.streams = listOf(localStreamId) + sender!!.setTrack(track, false) + SoraLogger.d(TAG, "set ${track.kind()} sender: mid=$mid, transceiver=$transceiver") + return sender + } + override fun handleInitialRemoteOffer( offer: String, mid: Map?, encodings: List? ): Single { - val offerSDP = SessionDescription(SessionDescription.Type.OFFER, offer) offerEncodings = encodings @@ -337,51 +344,29 @@ class PeerChannelImpl( // libwebrtc のバグにより simulcast の場合 setRD -> addTrack の順序を取る必要がある。 // simulcast can not reuse transceiver when setRemoteDescription is called after addTrack // https://bugs.chromium.org/p/chromium/issues/detail?id=944821 - val mediaStreamLabels = listOf(localStream!!.id) - - val audioMid = mid?.get("audio") - if (audioMid != null) { - val transceiver = this.conn?.transceivers?.find { it.mid == audioMid } - transceiver?.direction = RtpTransceiver.RtpTransceiverDirection.SEND_ONLY - SoraLogger.d(TAG, "set audio sender: mid=$audioMid, transceiver=$transceiver") - audioSender = transceiver?.sender - audioSender?.streams = listOf(localStream!!.id) - - localStream!!.audioTracks.firstOrNull()?.let { - SoraLogger.d(TAG, "set audio track: track=$it, enabled=${it.enabled()}") - audioSender?.setTrack(it, false) - } - } else { - audioSender = localStream!!.audioTracks.firstOrNull()?.let { - conn?.addTrack(it, mediaStreamLabels) - } - } - val videoMid = mid?.get("video") - if (videoMid != null) { - val transceiver = this.conn?.transceivers?.find { it.mid == videoMid } - transceiver?.direction = RtpTransceiver.RtpTransceiverDirection.SEND_ONLY - SoraLogger.d(TAG, "set video sender: mid=$mid, transceiver=$transceiver ") - videoSender = transceiver?.sender - videoSender?.streams = listOf(localStream!!.id) - - localStream!!.videoTracks.firstOrNull()?.let { - SoraLogger.d(TAG, "set video track: track=$it, enabled=${it.enabled()}") - videoSender?.setTrack(it, false) + // 問題が発生したら reactivex の onError で捕まえられるので、 force unwrap している + // setTrack 内も同様 + mid?.get("audio")?.let { mid -> + localAudioManager.track?.let { track -> + setTrack(mid, track) } - } else { - videoSender = localStream!!.videoTracks.firstOrNull()?.let { - conn?.addTrack(it, mediaStreamLabels) + } ?: SoraLogger.d(TAG, "mid for audio not found") + + mid?.get("video")?.let { mid -> + localVideoManager?.track?.let { track -> + videoSender = setTrack(mid, track) } - } + } ?: SoraLogger.d(TAG, "mid for video not found") if (mediaOption.simulcastEnabled && mediaOption.videoUpstreamEnabled) { videoSender?.let { updateSenderOfferEncodings(it) } } + SoraLogger.d(TAG, "createAnswer") return@flatMap createAnswer() }.flatMap { - answer -> + answer -> SoraLogger.d(TAG, "setLocalDescription") return@flatMap setLocalDescription(answer) } @@ -489,22 +474,23 @@ class PeerChannelImpl( dependencies ) + val localStream = factory!!.createLocalMediaStream(localStreamId) + SoraLogger.d(TAG, "local managers' initTrack: audio") localAudioManager.initTrack(factory!!, mediaOption.audioOption) + localAudioManager.track?.let { + localStream.addTrack(it) + } SoraLogger.d(TAG, "local managers' initTrack: video => ${mediaOption.videoUpstreamContext}") - localVideoManager.initTrack(factory!!, mediaOption.videoUpstreamContext, appContext) - - SoraLogger.d(TAG, "setup local media stream") - val streamId = UUID.randomUUID().toString() - localStream = factory!!.createLocalMediaStream(streamId) + localVideoManager?.initTrack(factory!!, mediaOption.videoUpstreamContext, appContext) + localVideoManager?.track?.let { + localStream.addTrack(it) + } - localAudioManager.attachTrackToStream(localStream!!) - localVideoManager.attachTrackToStream(localStream!!) - SoraLogger.d(TAG, "attached video sender => $videoSender") + SoraLogger.d(TAG, "localStream.audioTracks.size = ${localStream.audioTracks.size}") + SoraLogger.d(TAG, "localStream.videoTracks.size = ${localStream.videoTracks.size}") - SoraLogger.d(TAG, "localStream.audioTracks.size = ${localStream!!.audioTracks.size}") - SoraLogger.d(TAG, "localStream.videoTracks.size = ${localStream!!.videoTracks.size}") listener?.onAddLocalStream(localStream!!) } @@ -572,7 +558,8 @@ class PeerChannelImpl( SoraLogger.d( TAG, """createAnswer:onCreateSuccess: ${sdp!!.type} - |${sdp.description}""".trimMargin() + |${sdp.description} + """.trimMargin() ) it.onSuccess(sdp) } @@ -653,7 +640,7 @@ class PeerChannelImpl( conn?.dispose() conn = null localAudioManager.dispose() - localVideoManager.dispose() + localVideoManager?.dispose() SoraLogger.d(TAG, "dispose peer connection factory") factory?.dispose() factory = null diff --git a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCComponentFactory.kt b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCComponentFactory.kt index a7b1054f..ad98405a 100644 --- a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCComponentFactory.kt +++ b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCComponentFactory.kt @@ -9,8 +9,6 @@ import jp.shiguredo.sora.sdk.util.SoraLogger import org.webrtc.DefaultVideoDecoderFactory import org.webrtc.MediaConstraints import org.webrtc.PeerConnectionFactory -import org.webrtc.SoftwareVideoDecoderFactory -import org.webrtc.SoftwareVideoEncoderFactory import org.webrtc.audio.AudioDeviceModule import org.webrtc.audio.JavaAudioDeviceModule @@ -55,8 +53,10 @@ class RTCComponentFactory( resolutionAdjustment = mediaOption.hardwareVideoEncoderResolutionAdjustment, ) else -> - // context が指定されていなければソフトウェアエンコーダーを使用する - SoftwareVideoEncoderFactory() + SoraDefaultVideoEncoderFactory( + null, + resolutionAdjustment = mediaOption.hardwareVideoEncoderResolutionAdjustment, + ) } SoraLogger.d(TAG, "videoDecoderFactory => ${mediaOption.videoDecoderFactory}") @@ -67,7 +67,7 @@ class RTCComponentFactory( mediaOption.videoDownstreamContext != null -> DefaultVideoDecoderFactory(mediaOption.videoDownstreamContext) else -> - SoftwareVideoDecoderFactory() + DefaultVideoDecoderFactory(null) } SoraLogger.d(TAG, "decoderFactory => $decoderFactory") @@ -104,12 +104,12 @@ class RTCComponentFactory( return constraints } - fun createVideoManager(): RTCLocalVideoManager { - val videoManager = mediaOption.videoCapturer?.let { - RTCLocalVideoManagerImpl(it) - } ?: RTCNullLocalVideoManager() - SoraLogger.d(TAG, "videoManager created: $videoManager") - return videoManager + fun createVideoManager(): RTCLocalVideoManager? { + return mediaOption.videoCapturer?.let { + val videoManager = RTCLocalVideoManager(it) + SoraLogger.d(TAG, "videoManager created: $videoManager") + videoManager + } } fun createAudioManager(): RTCLocalAudioManager { diff --git a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCLocalAudioManager.kt b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCLocalAudioManager.kt index 0ba96e3c..508a09e8 100644 --- a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCLocalAudioManager.kt +++ b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCLocalAudioManager.kt @@ -5,7 +5,6 @@ import jp.shiguredo.sora.sdk.util.SoraLogger import org.webrtc.AudioSource import org.webrtc.AudioTrack import org.webrtc.MediaConstraints -import org.webrtc.MediaStream import org.webrtc.PeerConnectionFactory import java.util.UUID @@ -18,7 +17,7 @@ class RTCLocalAudioManager( } private var source: AudioSource? = null - private var track: AudioTrack? = null + var track: AudioTrack? = null fun initTrack(factory: PeerConnectionFactory, audioOption: SoraAudioOption) { SoraLogger.d(TAG, "initTrack: send=$send") @@ -28,7 +27,7 @@ class RTCLocalAudioManager( SoraLogger.d(TAG, "audio source created: $source") val trackId = UUID.randomUUID().toString() track = factory.createAudioTrack(trackId, source) - track!!.setEnabled(true) + track?.setEnabled(true) SoraLogger.d(TAG, "audio track created: $track") } } @@ -58,12 +57,6 @@ class RTCLocalAudioManager( return constraints } - fun attachTrackToStream(stream: MediaStream) { - if (send) { - track?.let { stream.addTrack(it) } - } - } - fun dispose() { SoraLogger.d(TAG, "dispose") source?.dispose() diff --git a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCLocalVideoManager.kt b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCLocalVideoManager.kt index b29f7e88..a9cae503 100644 --- a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCLocalVideoManager.kt +++ b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/rtc/RTCLocalVideoManager.kt @@ -3,7 +3,6 @@ package jp.shiguredo.sora.sdk.channel.rtc import android.content.Context import jp.shiguredo.sora.sdk.util.SoraLogger import org.webrtc.EglBase -import org.webrtc.MediaStream import org.webrtc.PeerConnectionFactory import org.webrtc.SurfaceTextureHelper import org.webrtc.VideoCapturer @@ -11,38 +10,17 @@ import org.webrtc.VideoSource import org.webrtc.VideoTrack import java.util.UUID -interface RTCLocalVideoManager { - fun initTrack( - factory: PeerConnectionFactory, - eglContext: EglBase.Context?, - appContext: Context - ) - fun attachTrackToStream(stream: MediaStream) - fun dispose() -} - -// just for Null-Object-Pattern -class RTCNullLocalVideoManager : RTCLocalVideoManager { - override fun initTrack( - factory: PeerConnectionFactory, - eglContext: EglBase.Context?, - appContext: Context - ) {} - override fun attachTrackToStream(stream: MediaStream) {} - override fun dispose() {} -} - -class RTCLocalVideoManagerImpl(private val capturer: VideoCapturer) : RTCLocalVideoManager { +class RTCLocalVideoManager(private val capturer: VideoCapturer) { companion object { - private val TAG = RTCLocalVideoManagerImpl::class.simpleName + private val TAG = RTCLocalVideoManager::class.simpleName } var source: VideoSource? = null var track: VideoTrack? = null var surfaceTextureHelper: SurfaceTextureHelper? = null - override fun initTrack(factory: PeerConnectionFactory, eglContext: EglBase.Context?, appContext: Context) { + fun initTrack(factory: PeerConnectionFactory, eglContext: EglBase.Context?, appContext: Context) { SoraLogger.d(TAG, "initTrack isScreencast=${capturer.isScreencast}") surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", eglContext) @@ -51,16 +29,11 @@ class RTCLocalVideoManagerImpl(private val capturer: VideoCapturer) : RTCLocalVi val trackId = UUID.randomUUID().toString() track = factory.createVideoTrack(trackId, source) - track!!.setEnabled(true) + track?.setEnabled(true) SoraLogger.d(TAG, "created track => $trackId, $track") } - override fun attachTrackToStream(stream: MediaStream) { - SoraLogger.d(TAG, "attachTrackToStream") - track?.let { stream.addTrack(it) } - } - - override fun dispose() { + fun dispose() { SoraLogger.d(TAG, "dispose") SoraLogger.d(TAG, "dispose surfaceTextureHelper") surfaceTextureHelper?.dispose() diff --git a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/signaling/SignalingChannel.kt b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/signaling/SignalingChannel.kt index cf85d8c3..c793e395 100644 --- a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/signaling/SignalingChannel.kt +++ b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/channel/signaling/SignalingChannel.kt @@ -273,7 +273,8 @@ class SignalingChannelImpl @JvmOverloads constructor( SoraLogger.d( TAG, """[signaling:$role] <- offer - |${offerMessage.sdp}""".trimMargin() + |${offerMessage.sdp} + """.trimMargin() ) var endpoint = "" @@ -440,7 +441,9 @@ class SignalingChannelImpl @JvmOverloads constructor( } ?: closeWithError("failed to parse 'type' from message") } } catch (e: Exception) { - SoraLogger.w(TAG, e.toString()) + // 不正なメッセージを受信した場合、シグナリングの異常とみなして Sora との接続を切断する + SoraLogger.e(TAG, "failed to handle a WebSocket message", e) + disconnect(SoraDisconnectReason.SIGNALING_FAILURE) } } diff --git a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/codec/SimulcastVideoEncoderFactoryWrapper.kt b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/codec/SimulcastVideoEncoderFactoryWrapper.kt index 7ce27d4d..ea97e37a 100644 --- a/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/codec/SimulcastVideoEncoderFactoryWrapper.kt +++ b/sora-android-sdk/src/main/kotlin/jp/shiguredo/sora/sdk/codec/SimulcastVideoEncoderFactoryWrapper.kt @@ -55,7 +55,7 @@ internal class SimulcastVideoEncoderFactoryWrapper( | automaticResizeOn=${settings.automaticResizeOn} | numberOfSimulcastStreams=${settings.numberOfSimulcastStreams} | lossNotification=${settings.capabilities.lossNotification} - """.trimMargin() + """.trimMargin() ) return@Callable encoder.initEncode(settings, callback) }