全部產品
Search
文件中心

ApsaraVideo Live:視頻常用操作和配置

更新時間:Jan 22, 2026

本文將為您介紹如何通過調用API設定視頻編碼屬性。

功能介紹

在進行視訊通話或直播時,開發人員可以根據需要設定視頻相關配置,如視頻採集、編碼解析度、視訊框架率、碼率、鏡像模式、視圖模式等。

  • 解析度:

    • 採集解析度:指網路攝影機等採集裝置提供的畫面解析度。

    • 編碼解析度指經過編碼處理的畫面的解析度。

  • 碼率:指每秒傳輸的位元(bit)數,單位為 bps(bit per second)。

  • 幀率:單位時間內視頻顯示幀數的量度單位,測量單位為“每秒顯示幀數”(Frame Per Second,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} 自動調整採集解析度
 *      - 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:效能優先,根據編碼參數設定最接近的配置。

  • CAPTURER_OUTPUT_PREFERENCE_PREVIEW:優先保證預覽,選擇較高的網路攝影機輸入參數。

cameraDirection

AliRtcCameraDirection

相機方向(前置/後置)。

fps

int

採集幀率。

預設值為-1,表示使用編碼配置的 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);

2.設定視頻編碼配置

image

ARTC 提供setVideoEncoderConfiguration介面用於配置視頻編碼屬性,包含視頻解析度、幀率、碼率、主要畫面格間隔等影響視頻品質的參數設定。開發人員可以通過設定視頻編碼屬性,控制視頻流在不同網路條件下的展示方式。

說明

setVideoEncoderConfiguration在加入頻道前後均可設定,如果在一次通話過程中僅需要設定一次,推薦在加入頻道前設定。

相關配置如下:

參數名

類型

描述

dimensions

AliRtcVideoDimensions

視頻解析度,視頻解析度,預設值640x480,最大值1920x1080。

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:自適應,與採集視頻保持一致。

  • FixedLandscapre:固定橫屏。

  • FixedPortrait:固定豎屏。

rotationMode

AliRtcRotationMode

視頻旋轉角度(0/90/180/270)。

codecType

AliRtcVideoCodecType

轉碼器類型。

  • default:使用裝置預設設定。

  • software:軟體編碼。

  • hardware:硬體解碼。

  • hardwareTexture:硬體紋理編碼。

encodeCodecType

AliRtcVideoEncodeCodecType

視頻編碼格式(系統預設/ H264/H265)。

seiForceFrontIFrame

int

SEI發送前強制I幀。

-1表示使用預設值,0表示不強制,1表示強制(預設值)。

介面調用樣本如下:

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);

3.切換相機方向

Android 和 iOS 裝置通常具有前置和後置網路攝影機。SDK 預設使用自拍,如果需要修改,請調用setCameraCaptureConfiguration介面在開啟網路攝影機前進行設定。如果已經開啟網路攝影機,需要切換網路攝影機則可以調用switchCamera介面。

/**
 * @brief 切換前後網路攝影機
 * @return
 * - 0: 成功
 * - 非0: 失敗
 * @note 只有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 提供兩個介面,muteLocalCameraenableLocalVideo

介面

muteLocalCamera

enableLocalVideo

實現原理

發送資料替換為黑幀。

直接停止網路攝影機硬體採集,釋放相關資源。

關閉網路攝影機現象

本地預覽正常顯示,遠端使用者黑屏。

本地預覽和遠端均停留在最後一幀。

特點

  • 保持視頻流串連:接收端不會感知到視頻中斷。

  • 快速切換:無需頻繁啟停網路攝影機硬體,響應延遲低。適合需要動態啟停網路攝影機情境。

  • 釋放網路攝影機資源,

  • 切換較慢:需要開啟/關閉網路攝影機,響應有延時。 適合長期關閉網路攝影機情境,例如純音頻情境。

4.1. 停止或恢複視頻資料發送

image

ARTC 提供muteLocalCamera介面實現禁視頻功能,在保留視頻採集/編碼/傳輸通道啟動並執行前提下,向遠端發送全黑視訊框架(本地預覽保持正常畫面)。介面定義如下:

/**
 * 是否將停止本地視頻資料發送
 * @param mute     true表示視頻資料發送黑幀;false表示恢複正常
 * @param track    只支援{@link AliRtcVideoTrack#AliRtcVideoTrackCamera}
 * @return
 * - 0: 成功
 * - 非0: 失敗
 * @note 發送黑色的視訊框架。本地正常預覽。採集、編碼、發送模組仍然工作,只是視頻內容被替換為黑色幀
 */
public abstract int muteLocalCamera(boolean mute, AliRtcVideoTrack track);
/**
 * @brief 對端使用者發送視頻黑幀資料發送通知
 * @param uid 執行muteVideo的使用者ID
 * @param isMute
 * - true: 推流黑幀
 * - false: 正常推流
 * @note 該介面用於對端使用者發送視頻黑幀資料時的回調
 */
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(false, for: AliRtcVideoTrack.camera)
    } else {
        rtcEngine?.muteLocalCamera(true, 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(`使用者${uid}的視頻已${isMute ? '靜音' : '取消靜音'}`);
});

4.2. 開關相機採集

image

通過 enableLocalVideo 介面實現全域性控制本地視頻採集裝置(如網路攝影機)的啟停狀態,直接影響視頻資料流的產生與傳輸。

/**
 * @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: 關閉相機流採集
 * @note 該介面用於對端使用者關閉相機流採集時的回調
 */
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, isMute : boolean) => {
  console.info(`使用者${uid}的視頻已${isMute ? '禁用' : '啟用'}`);
});

5. 開啟或關閉預覽

ARTC 提供startPreviewstopPreview介面來控制本地預覽的啟停。

注意:

  • 預覽前需要調用setLocalViewConfig為本地預覽畫面設定渲染視圖。

  • SDK 加入頻道預設會開啟預覽,如果需要在入會前開啟預覽可以提前調用startPreview

  • 調用關閉預覽後,本端預覽畫面會停留在最後一幀。

開啟預覽。

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(); // Handle potential exceptions
                }
            }
        }
        // 開始預覽
        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?.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();

6. 設定鏡像模式

ARTC 提供setVideoMirrorMode介面控制本地視頻的預覽畫面鏡像與推流畫面鏡像行為,支援運行時動態調整,適用於音視訊通話、直播等情境。

/**
 * @brief 設定預覽和推流鏡像能力
 * @param mirrorMode 設定鏡像的模式
 * @return
 * - 0: 設定成功
 * - <0: 設定失敗
 *  - AliRtcErrInner: SDK內部狀態錯誤,需檢查是否建立SDK執行個體成功
 *
 * @note
 * - 此介面在入會前和入會後均可以動態設定,SDK內部會選項組,並在可以操作預覽及編碼的時候對視頻進行操作;
 * - 使用此介面的優先順序會高於setLocalViewConfig&setVideoEncoderConfiguration
 * - 此介面與setLocalViewConfiguration&setVideoEncoderConfiguration裡面的mirror重合,建議只有一個方式
 */
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);

7. 設定渲染視圖

在顯示本地預覽和遠端使用者畫面前,需要調用setLocalViewConfigsetRemoteViewConig 介面為待顯示畫面設定渲染視圖。

// 設定本地預覽顯示視圖
public abstract int setLocalViewConfig(AliRtcVideoCanvas viewConfig, AliRtcVideoTrack track);
// 設定遠端置頂使用者顯示視圖
public abstract int setRemoteViewConfig(AliRtcVideoCanvas canvas, String uid, AliRtcVideoTrack track);

AliRtcVideoCanvas 常用配置如下:

參數

類型

說明

view

View

顯示視圖(必需)。

renderMode

AliRtcRenderMode

渲染模式。

  • Auto:自動模式。

  • Stretch:展開平鋪模式,如果外部輸入的視頻寬高比和推流設定的寬高比不一致時,將輸入視頻展開到推流設定的比例,畫面會變形。

  • Fill:填充黑邊模式,如果外部輸入的視頻寬高比和推流設定的寬高比不一致時,將輸入視頻上下或者左右填充黑邊。

  • Clip:裁剪模式,如果外部輸入的視頻寬高比和推流設定的寬高比不一致時,將輸入視頻寬或者高進行裁剪,畫面內容會丟失。

mirrorMode

AliRtcRenderMirrorMode

鏡像模式。

  • 只有自拍鏡像。

  • 全部鏡像。

  • 全部不鏡像。

rotationMode

AliRtcRotationMode

旋轉模式(0/90/180/270)。

backgroundColor

int

背景顏色,格式為RGB的Hex,例如0x000000。

textureId

int

(僅 Android)支援第三方OpenGL ES紋理顯示,紋理ID。

textureWidth

int

(僅 Android)支援第三方OpenGL ES紋理顯示,紋理寬。

textureHeight

int

(僅 Android)支援第三方OpenGL ES紋理顯示,紋理高。

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()

Windows

AliEngineVideoCanvas canvas;
/* windows 視窗控制代碼 */
canvas.view = mHWnd;
mAliRtcEngine.setLocalViewConfig(canvas, AliEngineVideoTrackCamera);

Harmony

// 建立或重用canvas
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)
    }
}

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(`遠端音視頻流可用: userId=${userId}, videoTrack=${videoTrack}`);

  // 根據視頻流類型,調用setRemoteViewConfig配置遠端視圖
  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);
  }
});