映像の送受信と描画

映像を送受信する

カメラの映像を取得する

カメラの映像を取得するには、SDK 内部でカメラを管理する方法と、アプリケーション側でカメラを管理する方法の2通りがあります。

SDK 内部で CameraVideoCapturer を管理する

SoraMediaOption.enableVideoUpstream(eglContext, cameraConfig) を使用すると、SDK 内部で CameraVideoCapturer を生成・管理できます。

この方法ではアプリケーション側で CameraVideoCapturer を生成する必要はなく、カメラキャプチャの開始と停止は SDK が自動的に行います。Sora への接続時にキャプチャが開始され、切断時に停止されます。

また、 initialVideoHardMutetrue に設定した場合は、接続時にカメラキャプチャを開始せず、 SoraMediaChannel.setVideoHardMute(false) を呼び出したタイミングからキャプチャを開始します。

val mediaOption = SoraMediaOption()
val cameraConfig = SoraMediaOption.SoraCameraConfig(
    width = 640,
    height = 480,
    frameRate = 30,
    frontFacingFirst = true,
    initialVideoHardMute = false
)
mediaOption.enableVideoUpstream(eglContext, cameraConfig)

SoraCameraConfig のパラメータは次の通りです:

  • width

    • 映像の幅。デフォルト値は 640 です。

  • height

    • 映像の高さ。デフォルト値は 480 です。

  • frameRate

    • フレームレート。デフォルト値は 30 です。

  • frontFacingFirst

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

  • initialVideoHardMute

    • true であれば Sora 接続開始時に映像をハードミュート(カメラを停止)した状態で開始します。デフォルト値は false です。

アプリケーション側でカメラを管理する

カメラの映像を取得するキャプチャラー (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 です。

生成したキャプチャラーを SDK に設定する

生成した CameraVideoCapturer を SDK に設定するには、 SoraMediaOption.enableVideoUpstream(capturer, eglContext) を使用します。

この方法で CameraVideoCapturer を SDK に設定した場合、カメラキャプチャの開始と停止はアプリケーション側で行う必要があります。

fun enableVideoUpstream(
    capturer: VideoCapturer,
    eglContext: EglBase.Context?,
    cameraConfig: SoraCameraConfig? = null,
) {}
  • capturer: 生成した VideoCapturer オブジェクト

  • eglContext: EGL コンテキスト

  • cameraConfig: カメラの設定。SoraMediaChannel.setVideoHardMute はこの設定を利用します。当該 API を使用する場合は必ず設定してください。

以下は SoraCameraConfig を設定しない enableVideoUpstream の使用例です。

class MainActivity : AppCompatActivity() {

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

    val mediaOption = SoraMediaOption()
    mediaOption.enableVideoUpstream(capturer!!, eglContext)
    ...
  }

}

映像を描画する

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

UI コンポーネント

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

レイアウト

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

次に例を示します:

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

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

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

初期化と終了処理

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

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

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

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

class MyActivity : AppCompatActivity() {

    private val egl: EglBase? = null

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

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

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

動画の左右を反転する

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

localRenderer.setMirror(true)

キャプチャーの操作

SDK 内部でカメラを管理する場合

SDK 内部でカメラを管理している場合(SoraMediaOption.enableVideoUpstreamSoraCameraConfig を渡した場合)の操作方法です。

キャプチャーを開始・停止する

SoraMediaChannel.setVideoHardMute(muted) を呼びます。 引数に true を指定するとキャプチャーを停止(ハードミュート)し、false を指定すると開始(ハードミュート解除)します。

このメソッドの詳細は 映像のハードミュート をご確認ください。

カメラを切り替える

SoraMediaChannel.switchCamera(handler) を呼びます。

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

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

アプリケーション側でカメラを管理する場合

アプリケーション側でカメラを管理する の方法で CameraVideoCapturer を生成した場合の操作方法です。 CameraVideoCapturer のメソッドを直接呼び出して操作します。

キャプチャーを開始・停止する

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

カメラを切り替える

CameraVideoCapturer.switchCamera() を呼びます。

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

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

© Copyright 2018-2025, Shiguredo Inc. Created using Sphinx 9.1.0