Tous les produits
Search
Centre de documentation

ApsaraVideo Live:Configurer et contrôler la vidéo

Dernière mise à jour :Aug 19, 2026

Configurez la capture vidéo, l'encodage, le contrôle de la caméra, la prévisualisation, le mode miroir et le rendu via le SDK ARTC.

Fonctionnalités

Lors d'un appel vidéo ou d'une diffusion interactive, vous pouvez configurer la résolution de capture, la résolution d'encodage, la fréquence d'images, le débit binaire, le mode miroir et le mode de rendu.

  • Résolution :

    • Résolution de capture : il s'agit de la résolution de la vidéo issue d'un dispositif de capture, tel qu'une caméra.

    • Résolution d'encodage: il s'agit de la résolution de la vidéo après encodage.

  • Débit binaire : nombre de bits transmis par seconde (bps).

  • Fréquence d'images : nombre d'images affichées par seconde (fps).

Des paramètres appropriés pour la résolution, la fréquence d'images et le débit binaire améliorent la qualité vidéo. Les modes miroir et de rendu contrôlent quant à eux la manière dont la vidéo est affichée.

Exemples de code

Utilisation vidéo de base pour Android : Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/VideoBasicUsage/VideoBasicUsageActivity.java.

Utilisation vidéo de base pour iOS : iOS/ARTCExample/BasicUsage/VideoBasicUsage/VideoBasicUsageVC.swift.

Utilisation vidéo de base pour Harmony : Harmony/ARTCExample/entry/src/main/ets/pages/basicusage/VideoBasicUsage.ets.

Prérequis

Avant de configurer les paramètres vidéo :

Implémentation

1. Définir la configuration de capture de la caméra

Utilisez la méthode setCameraCapturerConfiguration pour définir l'orientation de la caméra et la fréquence d'images de capture.

Remarque
  • Appelez cette méthode avant de démarrer la caméra, par exemple avant d'appeler startPreview ou joinChannel (qui démarre automatiquement la caméra).

  • L'appel de enableLocalVideo(false) pour désactiver la capture caméra libère les ressources associées. Vous pouvez alors réinitialiser la configuration.

image

La méthode est définie comme suit :

/**
 * @brief Sets the capture preference.
 * @param cameraCapturerConfiguration The camera capture settings.
 *      - preference:
 *        - {@link AliRtcCaptureOutputPreference#ALIRTC_CAPTURER_OUTPUT_PREFERENCE_PREVIEW} Preview priority. Prioritizes video preview quality.
 *        - {@link AliRtcCaptureOutputPreference#ALIRTC_CAPTURER_OUTPUT_PREFERENCE_PERFORMANCE} Performance priority. Prioritizes device performance by selecting a resolution close to that of the published stream.
 *        - {@link AliRtcCaptureOutputPreference#ALIRTC_CAPTURER_OUTPUT_PREFERENCE_AUTO} Auto. The SDK automatically adjusts the capture resolution.
 *      - cameraDirection: The camera direction. You can set it to the front or rear camera.
 * @return
 * - 0: Success.
 * - A non-zero value: Failure.
 * @note You must call this method before you start the camera, for example, before you call {@link #startPreview} or {@link #joinChannel}.
 */
public abstract int setCameraCapturerConfiguration(AliEngineCameraCapturerConfiguration cameraCapturerConfiguration);

Paramètres :

Parameter

Type

Description

preference

AliRtcCaptureOutputPreference

La préférence de capture.

  • CAPTURER_OUTPUT_PREFERENCE_AUTO : le SDK ajuste automatiquement les paramètres.

  • CAPTURER_OUTPUT_PREFERENCE_PERFORMANCE : priorité aux performances. Le SDK sélectionne les paramètres de capture qui correspondent le mieux aux paramètres d'encodage.

  • CAPTURER_OUTPUT_PREFERENCE_PREVIEW : priorité à la prévisualisation. Le SDK sélectionne des paramètres d'entrée de caméra de haute qualité pour privilégier la prévisualisation.

cameraDirection

AliRtcCameraDirection

L'orientation de la caméra (avant ou arrière).

fps

int

La fréquence d'images de capture.

Valeur par défaut : -1, ce qui signifie que le SDK utilise la fréquence d'images issue de la configuration d'encodage (la valeur interne par défaut du SDK est 15).

cameraCaptureProfile

AliRtcCameraCaptureProfile

La résolution de capture vidéo.

  • Par défaut : suit les paramètres de l'encodeur.

  • 1080p.

textureEncode

int

(Android uniquement) Indique si l'encodage de texture doit être activé.

cameraTextureCapture

int

(Android uniquement) Indique si la capture de texture de la caméra doit être activée.

Exemple de code :

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. Définir la configuration de l'encodeur vidéo

image

Utilisez la méthode setVideoEncoderConfiguration pour définir la résolution vidéo, la fréquence d'images, le débit binaire et l'intervalle entre les images clés.

Remarque

Appelez setVideoEncoderConfiguration avant ou après avoir rejoint un canal. Si vous ne l'appelez qu'une seule fois par appel, faites-le avant de rejoindre le canal.

Paramètres :

Parameter

Type

Description

dimensions

AliRtcVideoDimensions

La résolution vidéo. Par défaut : 640x480. Maximum : 1920x1080.

frameRate

int

La fréquence d'images d'encodage vidéo. Par défaut : 15. Maximum : 30.

bitrate

int

Le débit binaire vidéo en kbps. Par défaut : 512. Définissez la valeur sur 0 pour un calcul automatique basé sur la résolution et la fréquence d'images.

Si le débit binaire sort de la plage recommandée, le SDK l'ajuste automatiquement. Les plages recommandées figurent dans les commentaires du code exemple.

keyFrameInterval

int

L'intervalle entre les images clés en millisecondes. Par défaut : 0 (contrôlé par le SDK).

Remarque

Ce paramètre est requis pour la diffusion interactive et pour l'interopérabilité avec un mini-programme.

forceStrictKeyFrameInterval

boolean

Indique s'il faut forcer la génération stricte d'images clés à l'intervalle défini. Par défaut : false.

  • false : l'encodeur répond aux demandes d'images clés, par exemple lorsqu'un autre utilisateur rejoint le canal. L'intervalle entre les images clés peut ne pas correspondre strictement à la valeur définie.

  • true : l'encodeur ne répond pas aux autres demandes d'images clés et génère strictement des images clés à l'intervalle défini. Cela peut augmenter le temps nécessaire pour afficher la première image pour les abonnés.

mirrorMode

AliRtcVideoEncoderMirrorMode

Le mode miroir pour la vidéo encodée.

Remarque

Vous pouvez également utiliser la méthode setVideoMirrorMode pour définir le mode miroir.

orientationMode

AliRtcVideoEncoderOrientationMode

Le mode d'orientation de la vidéo encodée.

  • Adaptive : l'orientation de la vidéo de sortie correspond à celle de la vidéo capturée.

  • FixedLandscape : orientation paysage fixe.

  • FixedPortrait : orientation portrait fixe.

rotationMode

AliRtcRotationMode

L'angle de rotation de la vidéo encodée. Les valeurs valides sont 0, 90, 180 et 270.

codecType

AliRtcVideoCodecType

Le type de codec.

  • default : utilise le paramètre par défaut de l'appareil.

  • software : utilise l'encodage logiciel.

  • hardware : utilise l'encodage matériel.

  • hardwareTexture : utilise l'encodage de texture matériel.

encodeCodecType

AliRtcVideoEncodeCodecType

Le format d'encodage vidéo. Formats pris en charge : système par défaut, H.264 et H.265.

seiForceFrontIFrame

int

Indique s'il faut forcer une image I avant d'envoyer un message SEI.

Valeurs valides : -1 (par défaut, équivalent à 1), 0 (ne pas forcer) et 1 (forcer).

Exemple de code :

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;
// Call the RTC engine to set the configuration.
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. Changer de caméra

Le SDK utilise la caméra frontale par défaut. Appelez setCameraCaptureConfiguration avant de démarrer la capture pour spécifier une autre caméra, ou utilisez switchCamera pour changer de caméra pendant l'exécution.

/**
 * @brief Switches between the front and rear cameras.
 * @return
 * - `0`: Success
 * - Non-zero: Failure
 * @note This API is available on iOS and Android only.
 */
public abstract int switchCamera();

Exemple de code :

Android

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

iOS

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

Harmony

this.rtcEngine.switchCamera();

4. Contrôler la caméra

Deux API permettent de contrôler la caméra : muteLocalCamera et enableLocalVideo.

API

muteLocalCamera

enableLocalVideo

Fonctionnement

Envoie des images noires au lieu de la vidéo.

Arrête la capture de la caméra et libère les ressources de l'appareil.

Comportement

La prévisualisation locale reste active, mais les utilisateurs distants voient un écran noir.

La prévisualisation locale et la vidéo distante se figent sur la dernière image.

Caractéristiques

  • Maintient le flux vidéo. Aucune interruption pour les utilisateurs distants.

  • Changement rapide avec une faible latence. Idéal pour activer et désactiver fréquemment la vidéo.

  • Libère les ressources de la caméra.

  • Changement plus lent avec une latence plus élevée. Idéal pour les périodes prolongées sans caméra, comme lors des appels audio uniquement.

4,1. Activer ou désactiver la vidéo locale

image

La méthode muteLocalCamera maintient actif le pipeline de capture, d'encodage et de transmission vidéo, mais envoie des images noires aux utilisateurs distants. La prévisualisation locale n'est pas affectée.

/**
 * @brief Mutes or unmutes the local video stream.
 * @param mute true: Sends black frames. false: Resumes sending normal video frames.
 * @param track The video track to mute. Only {@link AliRtcVideoTrack#AliRtcVideoTrackCamera} is supported.
 * @return
 * - 0: Success.
 * - A non-zero value: Failure.
 * @note This method sends black frames while the local preview remains unaffected. The video capture pipeline continues to run.
 */
public abstract int muteLocalCamera(boolean mute, AliRtcVideoTrack track);
/**
 * @brief Occurs when a remote user mutes or unmutes their video stream.
 * @param uid The ID of the user who called muteLocalCamera.
 * @param isMute
 * - true: The user is sending black frames.
 * - false: The user is sending normal video frames.
 */
public void onUserVideoMuted(String uid ,boolean isMute){}

Android

Activer ou désactiver le flux vidéo :

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

Écouter le rappel distant :

@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

Activer ou désactiver le flux vidéo :

@IBAction func onVideoMuteSwitched(_ sender: UISwitch) {
    if sender.isOn {
        // Send black frames.
        rtcEngine?.muteLocalCamera(true, for: AliRtcVideoTrack.camera)
    } else {
        // Resume sending normal video frames.
        rtcEngine?.muteLocalCamera(false, for: AliRtcVideoTrack.camera)
    }
}

Écouter le rappel distant :

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

Harmony

Activer ou désactiver le flux vidéo :

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

Écouter le rappel distant :

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

macOS

Activer ou désactiver le flux vidéo :

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

Écouter le rappel distant :

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

Windows

Activer ou désactiver le flux vidéo :

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

Écouter le rappel distant :

void CTutorialDlg::OnUserVideoMuted(const char* uid, bool isMute)
{
    // Find the corresponding user view to update its status.
	PartUserDlg *partUserView = mRemotePartDlgs[uid];
	if (nullptr != partUserView)
	{
		partUserView->muteStream = isMute;
		updateRemoteParticipants();
	}
}

4,2. Activer ou désactiver la capture vidéo

image

enableLocalVideo gère la caméra. La désactivation de cette fonction arrête la capture et la transmission, ce qui libère le périphérique.

/**
 * @brief Enables or disables local video capture.
 * @param enabled
 * - true: Enables local video capture.
 * - false: Disables local video capture.
 * @return
 * - 0: Success.
 * - < 0: Failure.
 * @note This feature is enabled by default. Listen for the {@link AliRtcEngineNotify#onUserVideoEnabled} callback to be notified of changes to a remote user's video capture status.
 */
public abstract int enableLocalVideo(boolean enabled);
/**
 * @brief Occurs when a remote user enables or disables their local video capture.
 * @param uid The ID of the user who called enableLocalVideo.
 * @param isEnable
 * - true: The user enabled local video capture.
 * - false: The user disabled local video capture.
 */
public void onUserVideoEnabled(String uid, boolean isEnable){}

Android

Activez ou désactivez la capture vidéo :

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

Écoutez le rappel distant :

@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

Activez ou désactivez la capture vidéo :

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

Écoutez le rappel distant :

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

Harmony

Activez ou désactivez la capture vidéo :

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

    }
  }
}

Écoutez le rappel distant :

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

macOS

Activez ou désactivez la capture vidéo :

[self.engine enableLocalVideo:isOpen];

Écoutez le rappel distant :

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

Windows

Activez ou désactivez la capture vidéo :

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

Écoutez le rappel distant :

void CTutorialDlg::OnUserVideoEnabled(const char* uid, bool isEnable) {
    // Find the corresponding user view to update its status.
	PartUserDlg *partUserView = mRemotePartDlgs[uid];
	if (nullptr != partUserView)
	{
		partUserView->enableVideo = isEnable;
		updateRemoteParticipants();
	}
}

5. Démarrer ou arrêter l'aperçu

Utilisez startPreview et stopPreview pour contrôler l'aperçu local.

Remarque :

  • Vous devez appeler setLocalViewConfig pour définir une vue de rendu avant de démarrer l'aperçu.

  • Par défaut, le SDK démarre l'aperçu lorsque vous rejoignez un canal. Si vous devez démarrer l'aperçu avant de rejoindre le canal, appelez startPreview.

  • Après l'arrêt de l'aperçu, la vue locale se fige sur la dernière image.

Séquence d'appel d'API

image

Exemple de code :

Android

Démarrez l'aperçu :

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

        // Set the local view.
        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
                }
            }
        }
        // Start the preview.
        mAliRtcEngine.startPreview();
    }
}

Arrêtez l'aperçu :

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

iOS

Démarrez l'aperçu :

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

Arrêtez l'aperçu :

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

Harmony

Démarrez l'aperçu :

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

Arrêtez l'aperçu :

this.rtcEngine.stopPreview();

Mac

Démarrez l'aperçu :

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

Arrêtez l'aperçu :

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

Windows

Démarrez l'aperçu :

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

Arrêtez l'aperçu :

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

6. Définir le mode miroir

setVideoMirrorMode contrôle l'effet miroir pour l'aperçu local et le flux publié. Appelez cette méthode lors de l'exécution pendant les appels vidéo ou la diffusion en direct.

/**
 * @brief Sets the mirror mode for the local video preview and the published stream.
 * @param mirrorMode The mirror mode to set.
 * @return
 * - 0: Success.
 * - <0: Failure.
 *  - AliRtcErrInner: An internal SDK state error occurred. Verify that the SDK instance was created successfully.
 *
 * @note
 * - You can call this method to change the mirror mode at runtime, either before or after you join a channel. The SDK records the state and applies the setting when the preview and encoding are active.
 * - This method overrides the mirror settings configured in `setLocalViewConfig` and `setVideoEncoderConfiguration`.
 * - This method's settings duplicate those in `setLocalViewConfig` and `setVideoEncoderConfiguration`. Use only one method to configure mirroring.
 */
public abstract int setVideoMirrorMode(AliRtcVideoPipelineMirrorMode mirrorMode);

Modes miroir :

Valeur Enum

Description

AliRtcVideoPipelineMirrorModeNoMirror

L'effet miroir est désactivé pour l'aperçu et l'encodage.

AliRtcVideoPipelineMirrorModeBothMirror

Active l'effet miroir pour l'aperçu et l'encodage (par défaut).

AliRtcVideoPipelineMirrorModeOnlyPreviewMirror

Active l'effet miroir uniquement pour l'aperçu.

AliRtcVideoPipelineMirrorModeOnlyPublishMirror

Active l'effet miroir uniquement pour le flux publié.

Exemple de code :

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. Définir la vue de rendu

Appelez setLocalViewConfig ou setRemoteViewConfig pour définir une vue de rendu avant d'afficher la vidéo.

// Sets the render view for the local preview.
public abstract int setLocalViewConfig(AliRtcVideoCanvas viewConfig, AliRtcVideoTrack track);
// Sets the render view for a specified remote user.
public abstract int setRemoteViewConfig(AliRtcVideoCanvas canvas, String uid, AliRtcVideoTrack track);

Paramètres AliRtcVideoCanvas :

Paramètre

Type

Description

view

View

La vue d'affichage (obligatoire).

renderMode

AliRtcRenderMode

Le mode de rendu.

  • Auto : le SDK sélectionne automatiquement le mode de rendu.

  • Stretch : étire la vidéo pour remplir la vue. Si les rapports d'aspect de la vidéo et de la vue diffèrent, la vidéo est déformée.

  • Fill : met la vidéo à l'échelle proportionnellement pour s'adapter à la vue. Si les rapports d'aspect de la vidéo et de la vue diffèrent, le SDK ajoute des barres noires dans l'espace restant.

  • Clip : met la vidéo à l'échelle proportionnellement pour remplir la vue. Si les rapports d'aspect de la vidéo et de la vue diffèrent, le SDK recadre la vidéo pour qu'elle s'adapte.

mirrorMode

AliRtcRenderMirrorMode

Le mode miroir.

  • Active l'effet miroir uniquement pour l'aperçu local de la caméra frontale.

  • Active l'effet miroir pour toutes les vues vidéo (locales et distantes).

  • Désactive tous les effets miroir.

rotationMode

AliRtcRotationMode

Le mode de rotation. Valeurs valides : 0, 90, 180 et 270 degrés.

backgroundColor

int

La couleur d'arrière-plan au format hexadécimal RVB, par exemple 0x000000.

textureId

int

(Android uniquement) L'ID de texture, utilisé pour afficher une texture OpenGL ES tierce.

textureWidth

int

(Android uniquement) La largeur de la texture.

textureHeight

int

(Android uniquement) La hauteur de la texture.

sharedContext

long

(Android uniquement) Le contexte OpenGL ES partagé pour la texture.

Exemple de code :

7,1. Définir la vue de rendu locale

Android

mLocalVideoCanvas = new AliRtcEngine.AliRtcVideoCanvas();
// Get and set the 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;
// Set the local preview view.
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;
/* Window handle */
canvas.view = mHWnd;
canvas.mirrorMode = AliEngineRenderMirrorModeAllNoMirror;
mAliRtcEngine->setLocalViewConfig(canvas, AliEngineVideoTrackCamera);

Harmony

// Create or reuse the 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. Définir la vue de rendu distante

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()
    // Handles the availability of a remote user's stream.
    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

// Remote audio/video stream availability notification
listener.onRemoteTrackAvailableNotify((userId: string, audioTrack: AliRtcAudioTrack,
  videoTrack: AliRtcVideoTrack) => {
  console.info(`Remote audio/video stream available: userId=${userId}, videoTrack=${videoTrack}`);

  // Configure the remote view based on the video stream type.
  if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackCamera) {
    // Camera stream is available.
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackCamera);
    this.removeRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackScreen);
  } else if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackScreen) {
    // Screen sharing stream is available.
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackScreen);
    this.removeRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackCamera);
  } else if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackBoth) {
    // Dual streams are available (camera + screen sharing).
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackCamera);
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackScreen);
  } else if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackNo) {
    // No video stream.
    this.removeAllRemoteVideo(userId);
  }
});