すべてのプロダクト
Search
ドキュメントセンター

ApsaraVideo Live:ビデオ操作と構成

最終更新日:Mar 26, 2026

API を呼び出してビデオエンコーディングのプロパティを設定する方法について説明します。

特徴

ビデオ通話またはインタラクティブストリーム中、キャプチャ解像度、エンコード解像度、フレームレート、ビットレート、ミラー表示モード、レンダリングモードなどのビデオ設定を構成できます。

  • 解像度:

    • キャプチャ解像度:カメラなどのキャプチャデバイスから取得されるビデオの解像度。

    • エンコード解像度:エンコードされたビデオの解像度。

  • ビットレート:1 秒あたりに送信されるビット数(bps)。

  • フレームレート:1 秒あたりに表示されるフレーム数(fps)。

適切なビデオ解像度、フレームレート、ビットレートを設定することで、ユーザー体験が向上します。適切なミラー表示モードおよびレンダリングモードを選択することで、ビデオの表示スタイルをカスタマイズできます。

サンプルコード

Android 向け基本ビデオ使用例Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/VideoBasicUsage/VideoBasicUsageActivity.java

iOS 向け基本ビデオ使用例iOS/ARTCExample/BasicUsage/VideoBasicUsage/VideoBasicUsageVC.swift

Harmony 向け基本ビデオ使用例Harmony/ARTCExample/entry/src/main/ets/pages/basicusage/VideoBasicUsage.ets

前提条件

ビデオ設定を構成する前に、以下の要件を満たしていることを確認してください。

実装

1. カメラキャプチャ構成の設定

ARTC では、setCameraCapturerConfiguration メソッドを使用して、カメラ方向およびキャプチャフレームレートを含むカメラキャプチャ構成を設定できます。

説明
  • このメソッドは、カメラを起動する前(例:startPreview または joinChannel(自動的にカメラを起動)を呼び出す前)に呼び出してください。

  • enableLocalVideo(false) を呼び出してカメラキャプチャを無効化すると、カメラリソースが解放されます。その後、構成を再設定できます。

image

このメソッドの定義は以下のとおりです。

/**
 * @brief キャプチャの優先設定を指定します。
 * @param cameraCapturerConfiguration カメラキャプチャ設定。
 *      - preference:
 *        - {@link AliRtcCaptureOutputPreference#ALIRTC_CAPTURER_OUTPUT_PREFERENCE_PREVIEW} プレビュー優先。ビデオプレビューの品質を優先します。
 *        - {@link AliRtcCaptureOutputPreference#ALIRTC_CAPTURER_OUTPUT_PREFERENCE_PERFORMANCE} パフォーマンス優先。公開ストリームの解像度に近い解像度を選択することで、デバイスのパフォーマンスを優先します。
 *        - {@link AliRtcCaptureOutputPreference#ALIRTC_CAPTURER_OUTPUT_PREFERENCE_AUTO} 自動。SDK がキャプチャ解像度を自動調整します。
 *      - cameraDirection: カメラの方向。前面または背面カメラを指定できます。
 * @return
 * - 0: 成功。
 * - 0 以外の値: 失敗。
 * @note このメソッドは、カメラを起動する前(例:{@link #startPreview} または {@link #joinChannel} を呼び出す前)に呼び出す必要があります。
 */
public abstract int setCameraCapturerConfiguration(AliEngineCameraCapturerConfiguration cameraCapturerConfiguration);

以下の表に、パラメーターを示します。

パラメーター

説明

preference

AliRtcCaptureOutputPreference

キャプチャの優先設定。

  • CAPTURER_OUTPUT_PREFERENCE_AUTO: SDK が設定を自動調整します。

  • CAPTURER_OUTPUT_PREFERENCE_PERFORMANCE: パフォーマンス優先。SDK がエンコードパラメーターに最も適合するキャプチャ設定を選択します。

  • CAPTURER_OUTPUT_PREFERENCE_PREVIEW: プレビュー優先。SDK がプレビュー品質を最優先する高品質なカメラ入力パラメーターを選択します。

cameraDirection

AliRtcCameraDirection

カメラの方向(前面または背面)。

fps

int

キャプチャフレームレート。

デフォルト値:-1(SDK がエンコード構成から fps を使用することを意味します。SDK の内部デフォルト値は 15 です)。

cameraCaptureProfile

AliRtcCameraCaptureProfile

ビデオキャプチャ解像度。

  • デフォルト:エンコーダー設定に準拠。

  • 1080p。

textureEncode

int

(Android 専用)テクスチャエンコーディングを有効にするかどうかを指定します。

cameraTextureCapture

int

(Android 専用)カメラのテクスチャキャプチャを有効にするかどうかを指定します。

サンプルコード:

Android

AliRtcEngine.AliEngineCameraCapturerConfiguration config = new AliRtcEngine.AliEngineCameraCapturerConfiguration();
config.preference = AliRtcEngine.AliRtcCaptureOutputPreference.ALIRTC_CAPTURER_OUTPUT_PREFERENCE_AUTO;
config.cameraCaptureProfile = AliRtcEngine.AliRtcCameraCaptureProfile.ALIRTC_CAMERA_CAPTURER_PROFILE_DEFAULT;
config.cameraDirection = AliRtcEngine.AliRtcCameraDirection.CAMERA_FRONT;
config.fps = 30;
mAliRtcEngine.setCameraCapturerConfiguration(config);

iOS

let cameraCaptureConfig: AliRtcCameraCapturerConfiguration = AliRtcCameraCapturerConfiguration()
cameraCaptureConfig.preference = .auto
cameraCaptureConfig.cameraCaptureProfile = .profileDefault
cameraCaptureConfig.cameraDirection = .front
cameraCaptureConfig.fps = 30
engine.setCameraCapturerConfiguration(cameraCaptureConfig)

Harmony

const cameraConfig = new AliRtcCameraCaptureConfiguration();
cameraConfig.preference = AliRtcCaptureOutputPreference.AliRtcCaptureOutputPreferenceAuto;
cameraConfig.cameraDirection = AliRtcCameraDirection.AliRtcCameraDirectionFront;
cameraConfig.cameraCaptureProfile = AliRtcCameraCaptureProfile.AliRtcCameraCaptureProfileDefault;
cameraConfig.fps = 30;
this.rtcEngine?.setCameraCaptureConfiguration(cameraConfig);

macOS

AliRtcCameraCapturerConfiguration *configuration = [[AliRtcCameraCapturerConfiguration alloc] init];
configuration.preference = (AliRtcCaptureOutputPreference)outputBox.indexOfSelectedItem;
configuration.cameraCaptureProfile = AliRtcCameraCaptureProfileDefault;
configuration.fps = 15;
[self.engine setCameraCapturerConfiguration:configuration];

Windows

AliEngineCameraCapturerConfiguration config ;
config.preference = AliEngineCaptureOutputPreferencePerformance;
config.cameraCaptureProfile = AliEngineCameraCaptureProfileDefault;
config.fps = 30;
mAliRtcEngine->setCameraCapturerConfiguration(config);

2. ビデオエンコーダー構成の設定

image

ARTC では、setVideoEncoderConfiguration メソッドを使用して、ビデオ解像度、フレームレート、ビットレート、キーフレーム間隔などのビデオエンコーディングプロパティを設定できます。これらのプロパティにより、さまざまなネットワーク条件下でのビデオ品質を管理できます。

説明

setVideoEncoderConfiguration は、チャンネル参加前または参加後に呼び出すことができます。1 回の通話で構成を 1 度だけ設定する場合は、チャンネル参加前にこのメソッドを呼び出すことを推奨します。

以下の表に、パラメーターを示します。

パラメーター

説明

dimensions

AliRtcVideoDimensions

ビデオ解像度。デフォルト値:640×480。最大値:1920×1080。

frameRate

int

ビデオエンコードフレームレート。デフォルト値:15。最大値:30。

bitrate

int

ビデオビットレート(kbps)。デフォルト値は 512 です。このパラメーターを 0 に設定すると、SDK がビデオ解像度およびフレームレートに基づいて適切なビットレートを自動計算します。

指定したビットレートが、指定された解像度およびフレームレートに対する推奨範囲外の場合、SDK はそれを有効な値に自動調整します。推奨ビットレート範囲については、サンプルコード内のコメントをご参照ください。

keyFrameInterval

int

キーフレーム間隔(ミリ秒単位)。デフォルト値は 0 で、SDK がキーフレーム間隔を制御することを意味します。

説明

このパラメーターは、インタラクティブストリームおよびミニプログラムとの相互運用性に必須です。

forceStrictKeyFrameInterval

boolean

エンコーダーが設定された間隔でキーフレームを厳密に生成するかどうかを指定します。デフォルト値は false です。

  • false: エンコーダーはキーフレーム要求(例:他のユーザーがチャンネルに参加した場合など)に応答します。キーフレーム間隔は、設定値と厳密に一致しない場合があります。

  • true: エンコーダーは他のキーフレーム要求には応答せず、設定された間隔で厳密にキーフレームを生成します。これにより、サブスクライバーの初回フレーム表示までの時間が長くなる可能性があります。

mirrorMode

AliRtcVideoEncoderMirrorMode

エンコードされたビデオのミラー表示モード。

説明

ミラー表示モードの設定には、setVideoMirrorMode メソッドも使用できます。

orientationMode

AliRtcVideoEncoderOrientationMode

エンコードされたビデオの向きモード。

  • Adaptive: 出力ビデオの向きがキャプチャされたビデオの向きと一致します。

  • FixedLandscape: 固定の横向き表示。

  • FixedPortrait: 固定の縦向き表示。

rotationMode

AliRtcRotationMode

エンコードされたビデオの回転角度。有効値は 0、90、180、270 です。

codecType

AliRtcVideoCodecType

コーデックタイプ。

  • default: デバイスのデフォルト設定を使用します。

  • software: ソフトウェアエンコーディングを使用します。

  • hardware: ハードウェアエンコーディングを使用します。

  • hardwareTexture: ハードウェアテクスチャエンコーディングを使用します。

encodeCodecType

AliRtcVideoEncodeCodecType

ビデオエンコード形式。サポートされる形式:システムデフォルト、H.264、H.265。

seiForceFrontIFrame

int

Supplemental Enhancement Information(SEI)メッセージ送信前に I フレームを強制的に挿入するかどうかを指定します。

有効値: -1(デフォルト。 1 と同等)、 0(強制しない)、 1(強制する)。

API 呼び出しの例:

Android

AliRtcEngine.AliRtcVideoEncoderConfiguration aliRtcVideoEncoderConfiguration = new AliRtcEngine.AliRtcVideoEncoderConfiguration();
aliRtcVideoEncoderConfiguration.dimensions = new AliRtcEngine.AliRtcVideoDimensions(720, 1280);
aliRtcVideoEncoderConfiguration.frameRate = 20;
aliRtcVideoEncoderConfiguration.bitrate = 1200;
aliRtcVideoEncoderConfiguration.keyFrameInterval = 2000;
aliRtcVideoEncoderConfiguration.orientationMode = AliRtcVideoEncoderOrientationModeAdaptive;
mAliRtcEngine.setVideoEncoderConfiguration(aliRtcVideoEncoderConfiguration);

iOS

let config = AliRtcVideoEncoderConfiguration()
config.dimensions = CGSize(width: 720, height: 1280)
config.frameRate = 20
config.bitrate = 1200
config.keyFrameInterval = 2000
config.orientationMode = AliRtcVideoEncoderOrientationMode.adaptive
engine.setVideoEncoderConfiguration(config)

Harmony

const encoderConfig = new AliRtcVideoEncoderConfiguration();
const dimensions = new AliRtcVideoDimensions();
dimensions.width = 720;
dimensions.height = 1280;
encoderConfig.dimensions = dimensions;
encoderConfig.bitrate = 1200;
encoderConfig.frameRate = 20;
encoderConfig.orientationMode = AliRtcVideoEncoderOrientationMode.AliRtcVideoEncoderOrientationModeAdaptive;
encoderConfig.rotationMode = AliRtcRotationMode.AliRtcRotationMode_0;
// RTC エンジンを呼び出して構成を設定します。
this.rtcEngine?.setVideoEncoderConfiguration(encoderConfig);

macOS

AliRtcVideoEncoderConfiguration *config = [[AliRtcVideoEncoderConfiguration alloc] init];

config.dimensions = CGSizeMake(720, 1280);
config.frameRate = 20;
config.bitrate = 1200;
config.keyFrameInterval = 2000;
config.orientationMode = AliRtcVideoEncoderOrientationModeAdaptive;

[self.engine setVideoEncoderConfiguration:config];

Windows

AliEngineVideoEncoderConfiguration aliRtcVideoEncoderConfiguration ;
aliRtcVideoEncoderConfiguration.dimensions = AliRtcVideoDimensions(720, 1280);
aliRtcVideoEncoderConfiguration.frameRate = AliEngineFrameRateFps20;
aliRtcVideoEncoderConfiguration.bitrate = 1200;
aliRtcVideoEncoderConfiguration.keyFrameInterval = 2000;
aliRtcVideoEncoderConfiguration.orientationMode = AliEngineVideoEncoderOrientationModeAdaptive;
mAliRtcEngine->SetVideoEncoderConfiguration(aliRtcVideoEncoderConfiguration);

3. カメラの切り替え

デフォルトでは、SDK はデバイスの前面カメラを使用します。初期カメラとして別のカメラを指定するには、ビデオキャプチャを開始する前に setCameraCaptureConfiguration API を呼び出します。すでにキャプチャがアクティブな場合は、switchCamera API を呼び出して前面カメラと背面カメラを切り替えることができます。

/**
 * @brief 前面カメラと背面カメラを切り替えます。
 * @return
 * - `0`: 成功
 * - 0 以外: 失敗
 * @note この API は iOS および Android のみで利用可能です。
 */
public abstract int switchCamera();

使用例:

Android

mSwitchCameraBtn.setOnClickListener(v -> {
    if(mAliRtcEngine != null) {
        mAliRtcEngine.switchCamera();
    }
});

iOS

@IBAction func onCameraDirectionChanged(_ sender: UISegmentedControl) {
    rtcEngine?.switchCamera()
}

Harmony

this.rtcEngine.switchCamera();

4. カメラの制御

音声・ビデオ通話中にカメラを制御するには、ARTC が提供する muteLocalCamera および enableLocalVideo の 2 つの API を使用します。

API

muteLocalCamera

enableLocalVideo

動作

ビデオストリームを黒フレームで置き換えます。

カメラハードウェアによるビデオキャプチャを停止し、そのリソースを解放します。

動作内容

ローカルプレビューは引き続き有効ですが、リモートユーザーには黒画面が表示されます。

ローカルプレビューおよびリモートビデオは、最後にキャプチャされたフレームでフリーズします。

特徴

  • ビデオストリーム接続を維持します。リモートユーザーはビデオ中断を経験しません。

  • 高速な切り替えと低レイテンシーのレスポンス。頻繁にビデオ状態を切り替える必要があるシナリオに最適です。

  • カメラリソースを解放します。

  • 比較的遅い切り替えと高いレスポンスレイテンシー。音声のみの通話など、長期間カメラを無効化するシナリオに最適です。

4.1. ローカルビデオのミュート/アンミュート

image

muteLocalCamera API を使用してビデオミュートを実行できます。この API は、ビデオキャプチャ、エンコーディング、および送信パイプラインをアクティブに保ちながら、リモートユーザーに黒フレームを送信します。ローカルプレビューには影響しません。

/**
 * @brief ローカルビデオストリームをミュートまたはアンミュートします。
 * @param mute true: 黒フレームを送信します。false: 通常のビデオフレームの送信を再開します。
 * @param track ミュート対象のビデオトラック。{@link AliRtcVideoTrack#AliRtcVideoTrackCamera} のみサポートされています。
 * @return
 * - 0: 成功。
 * - 0 以外の値: 失敗。
 * @note このメソッドは黒フレームを送信しますが、ローカルプレビューには影響しません。ビデオキャプチャパイプラインは引き続き実行されます。
 */
public abstract int muteLocalCamera(boolean mute, AliRtcVideoTrack track);
/**
 * @brief リモートユーザーがビデオストリームをミュートまたはアンミュートしたときに発生します。
 * @param uid muteLocalCamera を呼び出したユーザーの ID。
 * @param isMute
 * - true: ユーザーが黒フレームを送信しています。
 * - false: ユーザーが通常のビデオフレームを送信しています。
 */
public void onUserVideoMuted(String uid ,boolean isMute){}

Android

ビデオストリームのミュート/アンミュート:

if(!isMutedCamera) {
    mAliRtcEngine.muteLocalCamera(true, AliRtcEngine.AliRtcVideoTrack.AliRtcVideoTrackCamera);
    mPublishVideoBtn.setText(R.string.resume_pub_video);
    isMutedCamera = true;
} else {
    mAliRtcEngine.muteLocalCamera(false, AliRtcEngine.AliRtcVideoTrack.AliRtcVideoTrackCamera);
    mPublishVideoBtn.setText(R.string.stop_pub_video);
    isMutedCamera = false;
}

リモートコールバックの受信:

@Override
public void onUserVideoMuted(String uid ,boolean isMute){
    handler.post(new Runnable() {
        @Override
        public void run() {
            ToastHelper.showToast(VideoBasicUsageActivity.this, "remote user uid:" + uid + " camera mute:" + isMute, Toast.LENGTH_SHORT);
        }
    });
}

iOS

ビデオストリームのミュート/アンミュート:

@IBAction func onVideoMuteSwitched(_ sender: UISwitch) {
    if sender.isOn {
        // 黒フレームを送信します。
        rtcEngine?.muteLocalCamera(true, for: AliRtcVideoTrack.camera)
    } else {
        // 通常のビデオフレームの送信を再開します。
        rtcEngine?.muteLocalCamera(false, for: AliRtcVideoTrack.camera)
    }
}

リモートコールバックの受信:

extension VideoBasicUsageVC: AliRtcEngineDelegate {
    func onUserVideoMuted(_ uid: String, videoMuted isMute: Bool) {
        "onUserVideoMuted: user id \(uid) video muted: \(isMute)".printLog()
    }
}

Harmony

ビデオストリームのミュート/アンミュート:

private toggleVideoSending(): void {
  if (this.rtcEngine) {
    if (!this.isMutedCamera) {
      this.rtcEngine.muteLocalCamera(true, AliRtcVideoTrack.AliRtcVideoTrackCamera);
      this.isMutedCamera = true;
    } else {
      this.rtcEngine.muteLocalCamera(false, AliRtcVideoTrack.AliRtcVideoTrackCamera);
      this.isMutedCamera = false;
    }
  }
}

リモートコールバックの受信:

listener.onUserVideoMuted((uid : string, isMute : boolean) => {
  console.info(`User ${uid}'s video has been ${isMute ? 'muted' : 'unmuted'}`);
});

macOS

ビデオストリームのミュート/アンミュート:

[self.engine muteLocalCamera:self.muteLocalCamera forTrack:AliRtcVideoTrackCamera];

リモートコールバックの受信:

- (void)onUserVideoMuted:(NSString *_Nullable)uid videoMuted:(BOOL)isMute {
    NSLog(@"uid=%@ mute:%d", uid, isMute );
}

Windows

ビデオストリームのミュート/アンミュート:

if ( mMuteLocalCamera == TRUE) {
    mAliRtcEngine->MuteLocalCamera(TRUE, AliRtcVideoTrackCamera);
} else {
    mAliRtcEngine->MuteLocalCamera(FALSE, AliRtcVideoTrackCamera); 
}

リモートコールバックの受信:

void CTutorialDlg::OnUserVideoMuted(const char* uid, bool isMute)
{
    // 対応するユーザー表示を検索してステータスを更新します。
	PartUserDlg *partUserView = mRemotePartDlgs[uid];
	if (nullptr != partUserView)
	{
		partUserView->muteStream = isMute;
		updateRemoteParticipants();
	}
}

4.2. ビデオキャプチャの有効化/無効化

image

enableLocalVideo API は、カメラなどのローカルビデオキャプチャデバイスを制御します。無効化すると、ビデオキャプチャおよび送信が停止され、デバイスが解放されます。

/**
 * @brief ローカル動画のキャプチャを有効化または無効化します。
 * @param enabled
 * - true: ローカル動画のキャプチャを有効化します。
 * - false: ローカル動画のキャプチャを無効化します。
 * @return
 * - 0: 成功。
 * - < 0: 失敗。
 * @note この機能はデフォルトで有効です。リモートユーザーの動画キャプチャ状態の変更を通知されるために、{@link AliRtcEngineNotify#onUserVideoEnabled} コールバックをリッスンしてください。
 */
public abstract int enableLocalVideo(boolean enabled);
/**
 * @brief リモートユーザーがローカル動画のキャプチャを有効化または無効化したときに発生します。
 * @param uid enableLocalVideo を呼び出したユーザーの ID。
 * @param isEnable
 * - true: ユーザーがローカル動画のキャプチャを有効化しました。
 * - false: ユーザーがローカル動画のキャプチャを無効化しました。
 */
public void onUserVideoEnabled(String uid, boolean isEnable){}

Android

ビデオキャプチャの有効化/無効化:

mCameraSwitchBtn = findViewById(R.id.camera_control_btn);
mCameraSwitchBtn.setOnClickListener(v -> {
    if(mAliRtcEngine != null) {
        if(isEnableCamera) {
            mAliRtcEngine.enableLocalVideo(false);
            isEnableCamera = false;
            mCameraSwitchBtn.setText(R.string.camera_on);
        } else {
            mAliRtcEngine.enableLocalVideo(true);
            isEnableCamera = true;
            mCameraSwitchBtn.setText(R.string.camera_off);
        }
    }
});

リモートコールバックの受信:

@Override
public void onUserVideoEnabled(String uid, boolean isEnable) {
    handler.post(new Runnable() {
        @Override
        public void run() {
            ToastHelper.showToast(VideoBasicUsageActivity.this, "remote user uid:" + uid + " camera enable:" + isEnable, Toast.LENGTH_SHORT);
        }
    });
}

iOS

ビデオキャプチャの有効化/無効化:

@IBAction func onCameraSwitch(_ sender: UISwitch) {
    if sender.isOn {
        rtcEngine?.enableLocalVideo(true)
    } else {
        rtcEngine?.enableLocalVideo(false)
    }
    updateCaptureUIVisibility()
}

リモートコールバックの受信:

extension VideoBasicUsageVC: AliRtcEngineDelegate {
    func onUserVideoEnabled(_ uid: String?, videoEnabled isEnable: Bool) {
        "onUserVideoEnabled: user id \(uid ?? "invalid uid") video enable: \(isEnable)".printLog()
    }
}

Harmony

ビデオキャプチャの有効化/無効化:

private toggleCamera(): void {
  if (this.rtcEngine) {
    if (this.isEnableCamera) {
      this.rtcEngine.enableLocalVideo(false);
      this.isEnableCamera = false;
    } else {
      this.rtcEngine.enableLocalVideo(true);
      this.isEnableCamera = true;

    }
  }
}

リモートコールバックの受信:

listener.onUserVideoEnabled((uid : string, isEnable : boolean) => {
  console.info(`User ${uid}'s video has been ${isEnable ? 'enabled' : 'disabled'}`);
});

macOS

ビデオキャプチャの有効化/無効化:

[self.engine enableLocalVideo:isOpen];

リモートコールバックの受信:

- (void)onUserVideoEnabled:(NSString *_Nullable)uid videoEnabled:(BOOL)isEnable) {
    NSLog(@"uid=%@ enabled:%d", uid, isEnable );
}

Windows

ビデオキャプチャの有効化/無効化:

mbLocalVideo = !mbLocalVideo;
mAliRtcEngine->EnableLocalVideo(mbLocalVideo);

リモートコールバックの受信:

void CTutorialDlg::OnUserVideoEnabled(const char* uid, bool isEnable) {
    // 対応するユーザー表示を検索してステータスを更新します。
	PartUserDlg *partUserView = mRemotePartDlgs[uid];
	if (nullptr != partUserView)
	{
		partUserView->enableVideo = isEnable;
		updateRemoteParticipants();
	}
}

5. プレビューの開始/停止

ARTC では、startPreview および stopPreview API を使用して、ローカルプレビューの開始または停止を行えます。

注意:

  • プレビューを開始する前に、setLocalViewConfig を呼び出してレンダリングビューを設定する必要があります。

  • デフォルトでは、SDK はチャンネルに参加した際にプレビューを開始します。チャンネル参加前にプレビューを開始する必要がある場合は、startPreview を呼び出します。

  • プレビューを停止した後、ローカルビューは最後のフレームでフリーズします。

API 呼び出しシーケンス

image

以下にコード例を示します。

Android

プレビューの開始:

private void startPreview() {
    if (mAliRtcEngine != null) {
        ViewGroup.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

        // ローカルビューを設定します。
        if (mLocalVideoCanvas == null) {
            mLocalVideoCanvas = new AliRtcEngine.AliRtcVideoCanvas();
            SurfaceView localSurfaceView = mAliRtcEngine.createRenderSurfaceView(VideoBasicUsageActivity.this);
            if (localSurfaceView != null) {
                localSurfaceView.setZOrderOnTop(true);
                localSurfaceView.setZOrderMediaOverlay(true);
                fl_local.addView(localSurfaceView, layoutParams);
                mLocalVideoCanvas.view = localSurfaceView;
                try {
                    mAliRtcEngine.setLocalViewConfig(mLocalVideoCanvas, AliRtcVideoTrackCamera);
                } catch (Exception e) {
                    e.printStackTrace(); // 例外処理
                }
            }
        }
        // プレビューを開始します。
        mAliRtcEngine.startPreview();
    }
}

プレビューの停止:

mAliRtcEngine.stopPreview();
mAliRtcEngine.setLocalViewConfig(null, AliRtcVideoTrackCamera);
mAliRtcEngine.leaveChannel();
mAliRtcEngine.destroy();
mAliRtcEngine = null;

iOS

プレビューの開始:

func startPreview() {
    let seatView = self.createSeatView(uid: self.userId)
    
    let canvas = AliVideoCanvas()
    canvas.view = seatView.canvasView
    canvas.renderMode = .auto
    canvas.mirrorMode = .onlyFrontCameraPreviewEnabled
    canvas.rotationMode = ._0
    
    self.rtcEngine?.setLocalViewConfig(canvas, for: AliRtcVideoTrack.camera)
    self.rtcEngine?.startPreview()
}

プレビューの停止:

self.rtcEngine?.stopPreview()
self.rtcEngine?.setLocalViewConfig(nil, for: AliRtcVideoTrack.camera)
self.rtcEngine?.leaveChannel()
AliRtcEngine.destroy()
self.rtcEngine = nil

Harmony

プレビューの開始:

if (!this.aliRtcVideoCanvas) {
  this.aliRtcVideoCanvas = new AliRtcVideoCanvas();
}

this.aliRtcVideoCanvas.surfaceId = this.localSurfaceId;
this.aliRtcVideoCanvas.renderMode = AliRtcRenderMode.AliRtcRenderModeAuto;
this.aliRtcVideoCanvas.mirrorMode = AliRtcRenderMirrorMode.AliRtcRenderMirrorModeAllMirror;

this.rtcEngine.setLocalViewConfig(
  this.aliRtcVideoCanvas,
  this.componentController,
  AliRtcVideoTrack.AliRtcVideoTrackCamera
);

this.rtcEngine.startPreview();

プレビューの停止:

this.rtcEngine.stopPreview();

Mac

プレビューの開始:

NSView * newView = [self createSeatView:uid];

AliVideoCanvas *canvas = [[AliVideoCanvas alloc] init];
canvas.renderMode = AliRtcRenderModeAuto;
canvas.view = newView;
canvas.mirrorMode = AliRtcRenderMirrorModeAllDisabled;
canvas.rotation = AliRtcRotationMode_0;

[self.engine setLocalViewConfig:canvas forTrack:AliRtcVideoTrackCamera];
[self.engine startPreview];

プレビューの停止:

[self.engine stopPreview];
[self.engine setLocalViewConfig:nil, AliRtcVideoTrackCamera];
[self.engine leaveChannel];
[self.engine destroy];
_engine = nil ;

Windows

プレビューの開始:

AliEngineVideoCanvas canvas;
canvas.renderMode = AliEngineRenderModeAuto;
canvas.rotation = AliEngineRotationMode_0;
canvas.displayView = hLocalWnd;
mAliRtcEngine->SetLocalViewConfig(canvas, AliEngineVideoTrackCamera);
mAliRtcEngine->StartPreview();

プレビューの停止:

mAliRtcEngine->StopPreview();
mAliRtcEngine->SetLocalViewConfig(nullptr, AliEngineVideoTrackCamera);
mAliRtcEngine->LeaveChannel();
mAliRtcEngine->Destroy();
mAliRtcEngine = nullptr;

6. ミラー表示モードの設定

setVideoMirrorMode メソッドは、ローカルビデオプレビューと公開ストリームのミラーリングを制御します。このメソッドはランタイムで呼び出すことができ、ビデオ通話やライブストリーミングに適しています。

/**
 * @brief ローカルビデオプレビューと公開されたストリームのミラーモードを設定します。
 * @param mirrorMode 設定するミラーモード。
 * @return
 * - 0: 成功。
 * - <0: 失敗。
 *  - AliRtcErrInner: SDK 内部で状態エラーが発生しました。 SDK インスタンスが正常に作成されたことを確認してください。
 *
 * @note
 * - このメソッドを呼び出して、チャンネルに参加する前または後に、ランタイム時にミラーモードを変更できます。 SDK は状態を記録し、プレビューとエンコーディングがアクティブなときに設定を適用します。
 * - このメソッドは、`setLocalViewConfig` および `setVideoEncoderConfiguration` で設定されたミラー設定をオーバーライドします。
 * - このメソッドの設定は `setLocalViewConfig` および `setVideoEncoderConfiguration` の設定と重複します。 ミラーリングを設定するには、いずれか 1 つのメソッドのみを使用してください。
 */
public abstract int setVideoMirrorMode(AliRtcVideoPipelineMirrorMode mirrorMode);

以下の表に、ミラー表示モードを示します。

列挙値

説明

AliRtcVideoPipelineMirrorModeNoMirror

プレビューおよびエンコーディングの両方に対してミラー表示を無効化します。

AliRtcVideoPipelineMirrorModeBothMirror

プレビューおよびエンコーディングの両方に対してミラー表示を有効化します(デフォルト)。

AliRtcVideoPipelineMirrorModeOnlyPreviewMirror

プレビューのみに対してミラー表示を有効化します。

AliRtcVideoPipelineMirrorModeOnlyPublishMirror

公開ストリームのみに対してミラー表示を有効化します。

サンプルコード:

Android

mMirrorSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
        if(mAliRtcEngine != null) {
            AliRtcEngine.AliRtcVideoPipelineMirrorMode mirrorMode = AliRtcEngine.AliRtcVideoPipelineMirrorMode.values()[position];
            mAliRtcEngine.setVideoMirrorMode(mirrorMode);
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> adapterView) {

    }
});

iOS

let mirrorMode: AliRtcVideoPipelineMirrorMode = {
    switch row {
    case 0: return .bothMirror
    case 1: return .noMirror
    case 2: return .onlyPreviewMirror
    case 3: return .onlyPublishMirror
    default: return .bothMirror
    }
}()
self.rtcEngine?.setVideoMirrorMode(mirrorMode)

Harmony

const mirrorMode = AliRtcVideoPipelineMirrorMode.AliRtcVideoPipelineMirrorModeBothMirror;
this.rtcEngine.setVideoMirrorMode(mirrorMode);

macOS

[self.engine setVideoMirrorMode:AliRtcVideoPipelineMirrorModeOnlyPreviewMirror];

Windows

mAliRtcEngine->setVideoMirrorMode(AliEngineVideoPipelineMirrorModeOnlyPreviewMirror);

7. レンダリングビューの設定

ローカルプレビューまたはリモートユーザーのビデオを表示する前に、setLocalViewConfig または setRemoteViewConfig API を呼び出してレンダリングビューを設定してください。

// ローカルプレビューのレンダリングビューを設定します。
public abstract int setLocalViewConfig(AliRtcVideoCanvas viewConfig, AliRtcVideoTrack track);
// 指定されたリモートユーザーのレンダリングビューを設定します。
public abstract int setRemoteViewConfig(AliRtcVideoCanvas canvas, String uid, AliRtcVideoTrack track);

一般的な AliRtcVideoCanvas 構成:

パラメーター

説明

view

View

表示ビュー(必須)。

renderMode

AliRtcRenderMode

レンダリングモード。

  • Auto: SDK がレンダリングモードを自動選択します。

  • Stretch: ビデオをビュー全体に引き伸ばします。ビデオとビューの縦横比が異なる場合、ビデオが歪みます。

  • Fill: ビデオを縦横比を維持したままビューに収まるようにスケーリングします。ビデオとビューの縦横比が異なる場合、SDK が残りの領域に黒枠を追加します。

  • Clip: ビデオを縦横比を維持したままビュー全体を埋めるようにスケーリングします。ビデオとビューの縦横比が異なる場合、SDK がビデオを切り取ってフィットさせます。

mirrorMode

AliRtcRenderMirrorMode

ミラー表示モード。

  • 前面カメラのローカルプレビューのみに対してミラー表示を有効化します。

  • すべてのビデオビュー(ローカルおよびリモート)に対してミラー表示を有効化します。

  • すべてのミラー表示を無効化します。

rotationMode

AliRtcRotationMode

回転モード。有効値:0、90、180、270 度。

backgroundColor

int

16 進数 RGB 形式の背景色(例:0x000000)。

textureId

int

(Android 専用)テクスチャ ID。サードパーティ製 OpenGL ES テクスチャの表示に使用されます。

textureWidth

int

(Android 専用)テクスチャの幅。

textureHeight

int

(Android 専用)テクスチャの高さ。

sharedContext

long

(Android 専用)テクスチャの共有 OpenGL ES コンテキスト。

サンプルコード:

7.1. ローカルレンダリングビューの設定

Android

mLocalVideoCanvas = new AliRtcEngine.AliRtcVideoCanvas();
// SurfaceView を取得および設定します。
SurfaceView localSurfaceView = mAliRtcEngine.createRenderSurfaceView(VideoChatActivity.this);
localSurfaceView.setZOrderOnTop(true);
localSurfaceView.setZOrderMediaOverlay(true);
FrameLayout fl_local = findViewById(R.id.fl_local);
fl_local.addView(localSurfaceView, layoutParams);
mLocalVideoCanvas.view = localSurfaceView;
// ローカルプレビュー表示ビューを設定します。
mAliRtcEngine.setLocalViewConfig(mLocalVideoCanvas, AliRtcVideoTrackCamera);
mAliRtcEngine.startPreview();

iOS

let videoView = self.createVideoView(uid: self.userId)

let canvas = AliVideoCanvas()
canvas.view = videoView.canvasView
canvas.renderMode = .auto
canvas.mirrorMode = .onlyFrontCameraPreviewEnabled
canvas.rotationMode = ._0

self.rtcEngine?.setLocalViewConfig(canvas, for: AliRtcVideoTrack.camera)
self.rtcEngine?.startPreview()

macOS

NSView * newView = [self createSeatView:uid];

AliVideoCanvas *canvas = [[AliVideoCanvas alloc] init];
canvas.renderMode = AliRtcRenderModeAuto;
canvas.view = newView;
canvas.mirrorMode = AliRtcRenderMirrorModeAllDisabled;
canvas.rotation = AliRtcRotationMode_0;

[self.engine setLocalViewConfig:canvas forTrack:AliRtcVideoTrackCamera];
[self.engine startPreview];

Windows

AliEngineVideoCanvas canvas;
/* ウィンドウハンドル */
canvas.view = mHWnd;
canvas.mirrorMode = AliEngineRenderMirrorModeAllNoMirror;
mAliRtcEngine->setLocalViewConfig(canvas, AliEngineVideoTrackCamera);

Harmony

// キャンバスを作成または再利用します。
if (!this.aliRtcVideoCanvas) {
  this.aliRtcVideoCanvas = new AliRtcVideoCanvas();
}

this.aliRtcVideoCanvas.surfaceId = this.localSurfaceId;
this.aliRtcVideoCanvas.renderMode = AliRtcRenderMode.AliRtcRenderModeAuto;
this.aliRtcVideoCanvas.mirrorMode = AliRtcRenderMirrorMode.AliRtcRenderMirrorModeAllMirror;

this.rtcEngine.setLocalViewConfig(
  this.aliRtcVideoCanvas,
  this.componentController,
  AliRtcVideoTrack.AliRtcVideoTrackCamera
);

this.rtcEngine.startPreview();

7.2. リモートレンダリングビューの設定

Android

@Override
public void onRemoteTrackAvailableNotify(String uid, AliRtcEngine.AliRtcAudioTrack audioTrack, AliRtcEngine.AliRtcVideoTrack videoTrack){
    handler.post(new Runnable() {
        @Override
        public void run() {
            if(videoTrack == AliRtcVideoTrackCamera) {
                SurfaceView surfaceView = mAliRtcEngine.createRenderSurfaceView(VideoChatActivity.this);
                surfaceView.setZOrderMediaOverlay(true);
                FrameLayout fl_remote = findViewById(R.id.fl_remote);
                if (fl_remote == null) {
                    return;
                }
                fl_remote.addView(surfaceView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
                AliRtcEngine.AliRtcVideoCanvas remoteVideoCanvas = new AliRtcEngine.AliRtcVideoCanvas();
                remoteVideoCanvas.view = surfaceView;
                mAliRtcEngine.setRemoteViewConfig(remoteVideoCanvas, uid, AliRtcVideoTrackCamera);
            } else if(videoTrack == AliRtcVideoTrackNo) {
                FrameLayout fl_remote = findViewById(R.id.fl_remote);
                fl_remote.removeAllViews();
                mAliRtcEngine.setRemoteViewConfig(null, uid, AliRtcVideoTrackCamera);
            }
        }
    });
}

iOS

func onRemoteTrackAvailableNotify(_ uid: String, audioTrack: AliRtcAudioTrack, videoTrack: AliRtcVideoTrack) {
    "onRemoteTrackAvailableNotify uid: \(uid) audioTrack: \(audioTrack)  videoTrack: \(videoTrack)".printLog()
    // リモートユーザーのストリームの可用性を処理します。
    if audioTrack != .no {
        let videoView = self.videoViewList.first { $0.uidLabel.text == uid }
        if videoView == nil {
            _ = self.createVideoView(uid: uid)
        }
    }
    if videoTrack != .no {
        var videoView = self.videoViewList.first { $0.uidLabel.text == uid }
        if videoView == nil {
            videoView = self.createVideoView(uid: uid)
        }

        let canvas = AliVideoCanvas()
        canvas.view = videoView!.canvasView
        canvas.renderMode = .auto
        canvas.mirrorMode = .onlyFrontCameraPreviewEnabled
        canvas.rotationMode = ._0
        self.rtcEngine?.setRemoteViewConfig(canvas, uid: uid, for: AliRtcVideoTrack.camera)
    }
    else {
        self.rtcEngine?.setRemoteViewConfig(nil, uid: uid, for: AliRtcVideoTrack.camera)
    }

    if audioTrack == .no && videoTrack == .no {
        self.removeVideoView(uid: uid)
        self.rtcEngine?.setRemoteViewConfig(nil, uid: uid, for: AliRtcVideoTrack.camera)
    }
}

macOS

- (void)onRemoteTrackAvailableNotify:(NSString *)uid audioTrack:(AliRtcAudioTrack)audioTrack videoTrack:(AliRtcVideoTrack)videoTrack {
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
            NSLog(@"Remote user stream information callback");
            
            __weak typeof(self)weakSelf = self;
            dispatch_async(dispatch_get_main_queue(), ^{
                __strong typeof(weakSelf)strongSelf = self;
                if (videoTrack == AliRtcVideoTrackNo) {
                    //                [self removeRemoteViewWithUid:uid];
                } else if(videoTrack == AliRtcVideoTrackCamera) {
                    [strongSelf addRemoteViewWithUid:uid videoTrack:AliRtcVideoTrackCamera];
                } else if(videoTrack == AliRtcVideoTrackScreen) {
                    [strongSelf addRemoteViewWithUid:uid videoTrack:AliRtcVideoTrackScreen];
                } else if(videoTrack == AliRtcVideoTrackBoth) {
                    [strongSelf addRemoteViewWithUid:uid videoTrack:AliRtcVideoTrackBoth];
                }
            });
        
    });

}

Windows

virtual void OnRemoteTrackAvailableNotify(const char *uid, AliEngineAudioTrack audioTrack, AliEngineVideoTrack videoTrack) {
    AliEngineVideoCanvas remote_canvas;
    if (videoTrack == AliEngineVideoTrackCamera
        || videoTrack == AliEngineVideoTrackBoth) {
        RECT rect;
        ::GetWindowRect(mHWnd, &rect);
        remote_canvas.displayView = remoteView;
        remote_canvas.renderMode = AliEngineRenderModeAuto;
        mAliRtcEngine->SetRemoteViewConfig(remote_canvas,uid,AliEngineVideoTrackCamera);
    } else {
        mAliRtcEngine->SetRemoteViewConfig(remote_canvas, uid, AliEngineVideoTrackCamera);
    }
}

Harmony

// リモート音声/ビデオストリームの可用性通知
listener.onRemoteTrackAvailableNotify((userId: string, audioTrack: AliRtcAudioTrack,
  videoTrack: AliRtcVideoTrack) => {
  console.info(`Remote audio/video stream available: userId=${userId}, videoTrack=${videoTrack}`);

  // ビデオストリームの種別に応じてリモートビューを構成します。
  if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackCamera) {
    // カメラストリームが利用可能です。
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackCamera);
    this.removeRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackScreen);
  } else if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackScreen) {
    // 画面共有ストリームが利用可能です。
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackScreen);
    this.removeRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackCamera);
  } else if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackBoth) {
    // デュアルストリームが利用可能です(カメラ+画面共有)。
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackCamera);
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackScreen);
  } else if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackNo) {
    // ビデオストリームがありません。
    this.removeAllRemoteVideo(userId);
  }
});