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

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

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

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

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

経緯

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

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

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

影響を受けるケース

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

移行方法

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

val option = SoraMediaOption().apply {
   // 明示的に multistream を false に設定する
   enableLegacyStream()
}

シグナリング の "type": "connect" メッセージの multistream を自動で true に設定する仕様を廃止

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

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

影響を受けるケース

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

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

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

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

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

移行方法

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

val option = SoraMediaOption().apply {
   // 明示的に multistream を true に設定する
   enableMultistream()
}

WebSocket が Sora から切断された際に受信したステータスコードが 1000 以外の場合でも onError を呼び出さないように変更

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

経緯

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

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

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

影響を受けるケース

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

移行方法

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

private val channelListener = object : SoraMediaChannel.Listener {

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

SoraMediaOption.videoCodec 未設定時の動作変更

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

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

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

影響を受けるケース

  • SoraMediaOption.videoCodec が未設定、かつ SoraMediaOption.videoVp9Params を設定している場合

移行方法

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

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

   videoVp9Params = object {
      var profile_id: Int = 0
   }
}

SoraMediaOption.audioCodec 未設定時の動作変更

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

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

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

影響を受けるケース

  • SoraMediaOption.audioCodec が未設定、かつ SoraMediaOption.audioOption.opusParams を設定している場合

移行方法

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

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

   audioOption = SoraAudioOption().apply {
      opusParams = OpusParams(
         stereo = true,
         useinbandfec = true,
      )
   }
}

onError(SoraMediaChannel, SoraErrorReason) を廃止

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

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

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

移行方法

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

private val channelListener = object : SoraMediaChannel.Listener {

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

   // この onError を実装してください。
   // 特に message がない場合は空文字列が渡されます
   override fun onError(mediaChannel: SoraMediaChannel, reason: SoraErrorReason, message: String) {
      // エラー処理や切断処理を記述する
   }
}

解像度維持方法の fixedResolution を廃止、 DegradationPreference を追加

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

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

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

移行方法

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

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

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

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

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

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

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

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

fun connect() {
   ...
   val mediaOption = SoraMediaOption().apply {
      ...
      // degradationPreference の指定を追加する例
      degradationPreference = SoraVideoOption.DegradationPreference.MAINTAIN_RESOLUTION
      ...
   }
}

Sora からの切断理由を取得できる onClose の追加

注釈

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

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

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

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

移行方法

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

private val channelListener = object : SoraMediaChannel.Listener {

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

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