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 :
Vous devez disposer d'un compte Alibaba Cloud avec une application ARTC (Créer une application). L'App ID et l'App Key sont disponibles dans la console ApsaraVideo Live.
Le SDK ARTC doit être intégré et les appels audio et vidéo de base doivent être implémentés. Consultez les rubriques Téléchargement/Intégration du SDK et Implémenter un appel audio et 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.
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.
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 |
|
|
La préférence de capture.
|
|
|
|
L'orientation de la caméra (avant ou arrière). |
|
|
|
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). |
|
|
La résolution de capture vidéo.
|
|
|
|
int |
(Android uniquement) Indique si l'encodage de texture doit être activé. |
|
|
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
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.
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 |
|
|
La résolution vidéo. Par défaut : 640x480. Maximum : 1920x1080. |
|
|
|
int |
La fréquence d'images d'encodage vidéo. Par défaut : 15. Maximum : 30. |
|
|
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. |
|
|
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. |
|
|
boolean |
Indique s'il faut forcer la génération stricte d'images clés à l'intervalle défini. Par défaut :
|
|
|
Le mode miroir pour la vidéo encodée. Remarque
Vous pouvez également utiliser la méthode |
|
|
|
Le mode d'orientation de la vidéo encodée.
|
|
|
|
L'angle de rotation de la vidéo encodée. Les valeurs valides sont 0, 90, 180 et 270. |
|
|
|
Le type de codec.
|
|
|
|
Le format d'encodage vidéo. Formats pris en charge : système par défaut, H.264 et H.265. |
|
|
|
int |
Indique s'il faut forcer une image I avant d'envoyer un message SEI. Valeurs valides : |
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 |
|
|
|
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 |
|
|
4,1. Activer ou désactiver la vidéo locale
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
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
setLocalViewConfigpour 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
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 |
|
|
L'effet miroir est désactivé pour l'aperçu et l'encodage. |
|
|
Active l'effet miroir pour l'aperçu et l'encodage (par défaut). |
|
|
Active l'effet miroir uniquement pour l'aperçu. |
|
|
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 |
|
|
|
La vue d'affichage (obligatoire). |
|
|
|
Le mode de rendu.
|
|
|
|
Le mode miroir.
|
|
|
|
Le mode de rotation. Valeurs valides : 0, 90, 180 et 270 degrés. |
|
|
|
La couleur d'arrière-plan au format hexadécimal RVB, par exemple 0x000000. |
|
|
|
(Android uniquement) L'ID de texture, utilisé pour afficher une texture OpenGL ES tierce. |
|
|
|
(Android uniquement) La largeur de la texture. |
|
|
|
(Android uniquement) La hauteur de la texture. |
|
|
|
(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);
}
});