Todos os produtos
Search
Central de documentação

ApsaraVideo Live:Configurar e controlar vídeo

Última atualização: Jun 30, 2026

Configure a captura de vídeo, a codificação, o controle da câmera, a pré-visualização, o espelhamento e a renderização com o ARTC SDK.

Recursos

Durante uma chamada de vídeo ou transmissão interativa, configure a resolução de captura, a resolução de codificação, a taxa de quadros, a taxa de bits, o modo de espelhamento e o modo de renderização.

  • Resolução:

    • Resolução de captura: resolução do vídeo proveniente de um dispositivo de captura, como uma câmera.

    • Resolução de codificação: resolução do vídeo codificado.

  • Taxa de bits: número de bits transmitidos por segundo (bps).

  • Taxa de quadros: número de quadros exibidos por segundo (fps).

Configurações adequadas de resolução, taxa de quadros e taxa de bits melhoram a qualidade do vídeo. Os modos de espelhamento e renderização controlam a exibição do vídeo.

Código de exemplo

Uso básico de vídeo para Android: Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/VideoBasicUsage/VideoBasicUsageActivity.java.

Uso básico de vídeo para iOS: iOS/ARTCExample/BasicUsage/VideoBasicUsage/VideoBasicUsageVC.swift.

Uso básico de vídeo para Harmony: Harmony/ARTCExample/entry/src/main/ets/pages/basicusage/VideoBasicUsage.ets.

Pré-requisitos

Antes de definir as configurações de vídeo:

Implementação

1. Defina configuração de captura da câmera

Use setCameraCapturerConfiguration para definir a direção da câmera e a taxa de quadros de captura.

Nota
  • Chame este método antes de iniciar a câmera, por exemplo, antes de chamar startPreview ou joinChannel (que inicia a câmera automaticamente).

  • Chamar enableLocalVideo(false) para desativar a captura da câmera libera os recursos da câmera. Em seguida, redefina a configuração.

image

Definição do método:

/**
 * @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);

Parâmetros:

Parâmetro

Tipo

Descrição

preference

AliRtcCaptureOutputPreference

Preferência de captura.

  • CAPTURER_OUTPUT_PREFERENCE_AUTO: O SDK ajusta as configurações automaticamente.

  • CAPTURER_OUTPUT_PREFERENCE_PERFORMANCE: Prioridade de desempenho. O SDK seleciona configurações de captura que melhor correspondem aos parâmetros de codificação.

  • CAPTURER_OUTPUT_PREFERENCE_PREVIEW: Prioridade de pré-visualização. O SDK seleciona parâmetros de entrada da câmera de alta qualidade para priorizar a pré-visualização.

cameraDirection

AliRtcCameraDirection

Direção da câmera (frontal ou traseira).

fps

int

Taxa de quadros de captura.

Valor padrão: -1. O SDK usa o fps da configuração de codificação (o padrão interno do SDK é 15).

cameraCaptureProfile

AliRtcCameraCaptureProfile

Resolução de captura de vídeo.

  • Padrão: Segue as configurações do codificador.

  • 1080p.

textureEncode

int

(Apenas Android) Indica se deve ativar a codificação de textura.

cameraTextureCapture

int

(Apenas Android) Indica se deve ativar a captura de textura para a câmera.

Código de exemplo:

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. Defina configuração do codificador de vídeo

image

Use setVideoEncoderConfiguration para definir a resolução de vídeo, a taxa de quadros, a taxa de bits e o intervalo de quadros-chave.

Nota

Chame setVideoEncoderConfiguration antes ou depois de entrar em um canal. Se for chamado apenas uma vez por chamada, faça-o antes de entrar.

Parâmetros:

Parâmetro

Tipo

Descrição

dimensions

AliRtcVideoDimensions

Resolução de vídeo. Padrão: 640x480. Máximo: 1920x1080.

frameRate

int

Taxa de quadros de codificação de vídeo. Padrão: 15. Máximo: 30.

bitrate

int

Taxa de bits de vídeo em kbps. Padrão: 512. Defina como 0 para cálculo automático com base na resolução e na taxa de quadros.

Se a taxa de bits estiver fora do intervalo recomendado, o SDK a ajustará automaticamente. Os intervalos recomendados estão nos comentários do código de exemplo.

keyFrameInterval

int

Intervalo de quadros-chave em milissegundos. Padrão: 0 (controlado pelo SDK).

Nota

Este parâmetro é necessário para transmissão interativa e interoperabilidade com mini programas.

forceStrictKeyFrameInterval

boolean

Indica se deve forçar a geração estrita de quadros-chave no intervalo definido. Padrão: false.

  • false: O codificador responde a solicitações de quadro-chave, por exemplo, quando outro usuário entra no canal. O intervalo de quadros-chave pode não corresponder estritamente ao valor definido.

  • true: O codificador não responde a outras solicitações de quadro-chave e gera estritamente quadros-chave no intervalo definido. Isso pode aumentar o tempo até o primeiro quadro para os assinantes.

mirrorMode

AliRtcVideoEncoderMirrorMode

Modo de espelhamento para o vídeo codificado.

Nota

Você também pode usar o método setVideoMirrorMode para definir o modo de espelhamento.

orientationMode

AliRtcVideoEncoderOrientationMode

Modo de orientação do vídeo codificado.

  • Adaptive: A orientação do vídeo de saída corresponde à do vídeo capturado.

  • FixedLandscape: Orientação paisagem fixa.

  • FixedPortrait: Orientação retrato fixa.

rotationMode

AliRtcRotationMode

Ângulo de rotação do vídeo codificado. Valores válidos: 0, 90, 180 e 270.

codecType

AliRtcVideoCodecType

Tipo de codec.

  • default: Usa a configuração padrão do dispositivo.

  • software: Usa codificação via software.

  • hardware: Usa codificação via hardware.

  • hardwareTexture: Usa codificação de textura via hardware.

encodeCodecType

AliRtcVideoEncodeCodecType

Formato de codificação de vídeo. Formatos suportados: padrão do sistema, H.264 e H.265.

seiForceFrontIFrame

int

Indica se deve forçar um I-frame antes de enviar uma mensagem SEI.

Valores válidos: -1 (padrão, equivalente a 1), 0 (não forçar) e 1 (forçar).

Código de exemplo:

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. Alternar câmeras

O SDK usa a câmera frontal por padrão. Chame setCameraCaptureConfiguration antes de iniciar a captura para especificar uma câmera diferente ou switchCamera para alternar durante a execução.

/**
 * @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();

Código de exemplo:

Android

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

iOS

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

Harmony

this.rtcEngine.switchCamera();

4. Controlar a câmera

Duas APIs controlam a câmera: muteLocalCamera e enableLocalVideo.

API

muteLocalCamera

enableLocalVideo

Funcionamento

Envia quadros pretos em vez de vídeo.

Interrompe a captura da câmera e libera os recursos do dispositivo.

Comportamento

A pré-visualização local permanece ativa, mas os usuários remotos veem uma tela preta.

A pré-visualização local e o vídeo remoto congelam no último quadro.

Características

  • Mantém o fluxo de vídeo sem interrupção para usuários remotos.

  • Alternância rápida com baixa latência. Ideal para alternar vídeo frequentemente.

  • Libera recursos da câmera.

  • Alternância mais lenta com maior latência. Ideal para períodos prolongados com a câmera desligada, como chamadas apenas de áudio.

4,1. Silenciar ou reativar vídeo local

image

muteLocalCamera mantém o pipeline de captura, codificação e transmissão de vídeo ativo, mas envia quadros pretos para usuários remotos. A pré-visualização local não é afetada.

/**
 * @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

Silencie ou reative o fluxo de vídeo:

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

Ouça o callback remoto:

@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

Silencie ou reative o fluxo de vídeo:

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

Ouça o callback remoto:

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

Harmony

Silencie ou reative o fluxo de vídeo:

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

Ouça o callback remoto:

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

macOS

Silencie ou reative o fluxo de vídeo:

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

Ouça o callback remoto:

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

Windows

Silencie ou reative o fluxo de vídeo:

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

Ouça o callback remoto:

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. Ative ou desative captura de vídeo

image

enableLocalVideo controla a câmera. Desativá-lo interrompe a captura e a transmissão, liberando o dispositivo.

/**
 * @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

Ative ou desative a captura de vídeo:

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

Ouça o callback remoto:

@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

Ative ou desative a captura de vídeo:

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

Ouça o callback remoto:

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

Harmony

Ative ou desative a captura de vídeo:

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

    }
  }
}

Ouça o callback remoto:

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

macOS

Ative ou desative a captura de vídeo:

[self.engine enableLocalVideo:isOpen];

Ouça o callback remoto:

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

Windows

Ative ou desative a captura de vídeo:

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

Ouça o callback remoto:

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. Iniciar ou parar pré-visualização

Use startPreview e stopPreview para controlar a pré-visualização local.

Nota:

  • Você deve chamar setLocalViewConfig para definir uma visualização de renderização antes de iniciar a pré-visualização.

  • Por padrão, o SDK inicia a pré-visualização ao entrar em um canal. Se precisar iniciar a pré-visualização antes de entrar no canal, chame startPreview.

  • Após parar a pré-visualização, a visualização local congela no último quadro.

Sequência de chamadas de API

image

Código de exemplo:

Android

Inicie a pré-visualização:

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

Pare a pré-visualização:

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

iOS

Inicie a pré-visualização:

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

Pare a pré-visualização:

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

Harmony

Inicie a pré-visualização:

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

Pare a pré-visualização:

this.rtcEngine.stopPreview();

Mac

Inicie a pré-visualização:

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

Pare a pré-visualização:

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

Windows

Inicie a pré-visualização:

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

Pare a pré-visualização:

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

6. Defina o modo de espelhamento

setVideoMirrorMode controla o espelhamento para a pré-visualização local e o fluxo publicado. Chame-o durante a execução em chamadas de vídeo ou transmissões ao vivo.

/**
 * @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);

Modos de espelhamento:

Valor do Enum

Descrição

AliRtcVideoPipelineMirrorModeNoMirror

Espelhamento desativado tanto para pré-visualização quanto para codificação.

AliRtcVideoPipelineMirrorModeBothMirror

Ativa o espelhamento tanto para a pré-visualização quanto para a codificação (padrão).

AliRtcVideoPipelineMirrorModeOnlyPreviewMirror

Ativa o espelhamento apenas para a pré-visualização.

AliRtcVideoPipelineMirrorModeOnlyPublishMirror

Ativa o espelhamento apenas para o fluxo publicado.

Código de exemplo:

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. Defina a visualização de renderização

Chame setLocalViewConfig ou setRemoteViewConfig para definir uma visualização de renderização antes de exibir o vídeo.

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

Parâmetros de AliRtcVideoCanvas:

Parâmetro

Tipo

Descrição

view

View

Visualização de exibição (obrigatório).

renderMode

AliRtcRenderMode

Modo de renderização.

  • Auto: O SDK seleciona automaticamente o modo de renderização.

  • Stretch: Estica o vídeo para preencher a visualização. Se as proporções do vídeo e da visualização forem diferentes, o vídeo será distorcido.

  • Fill: Escala o vídeo proporcionalmente para caber na visualização. Se as proporções do vídeo e da visualização forem diferentes, o SDK adiciona barras pretas ao espaço restante.

  • Clip: Escala o vídeo proporcionalmente para preencher a visualização. Se as proporções do vídeo e da visualização forem diferentes, o SDK corta o vídeo para ajustar.

mirrorMode

AliRtcRenderMirrorMode

Modo de espelhamento.

  • Ativa o espelhamento apenas para a pré-visualização local da câmera frontal.

  • Ativa o espelhamento para todas as visualizações de vídeo (local e remota).

  • Desativa todo o espelhamento.

rotationMode

AliRtcRotationMode

Modo de rotação. Valores válidos: 0, 90, 180 e 270 graus.

backgroundColor

int

Cor de fundo no formato RGB hexadecimal, por exemplo, 0x000000.

textureId

int

(Apenas Android) ID da textura, usado para exibir uma textura OpenGL ES de terceiros.

textureWidth

int

(Apenas Android) Largura da textura.

textureHeight

int

(Apenas Android) Altura da textura.

sharedContext

long

(Apenas Android) Contexto OpenGL ES compartilhado para a textura.

Código de exemplo:

7,1. Defina a visualização de renderização local

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. Defina a visualização de renderização remota

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