O ARTC SDK oferece APIs para gerenciar dispositivos de captura de vídeo em diversas plataformas, incluindo controle de zoom da câmera, exposição, foco e flash.
Visão geral dos recursos
O ARTC SDK proporciona controle abrangente sobre os dispositivos de captura de vídeo. Em plataformas como iOS e Android, é possível ajustar parâmetros da câmera, como zoom, exposição e foco manual ou automático, para melhorar a qualidade da captura de vídeo.
Código de exemplo
Gerenciamento de dispositivo de captura de vídeo para Android: Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/CameraCommonControl/CameraActivity.java.
Gerenciamento de dispositivo de captura de vídeo para iOS: iOS/ARTCExample/BasicUsage/CameraCommonSetting/CameraCommonControlVC.swift.
Gerenciamento de dispositivo de captura de vídeo para Harmony: Harmony/ARTCExample/entry/src/main/ets/pages/basicusage/CameraPage.ets.
Pré-requisitos
Possua uma conta Alibaba Cloud e tenha criado um aplicativo de Comunicação em Tempo Real (RTC). Para mais informações, consulte Criar um aplicativo. Obtenha um AppID e uma AppKey no console do ApsaraVideo Live.
-
Integração do SDK e implementação de recursos básicos:
Integre o ARTC SDK ao seu projeto e implemente os recursos básicos de Comunicação em Tempo Real (RTC). Para mais detalhes, veja Integrar o SDK e Implementar uma chamada de áudio e vídeo.
Inicie a câmera, por exemplo, iniciando uma pré-visualização com
startPreviewou entrando em um canal comjoinChannel.
Implementação
Defina o zoom da câmera
O ARTC SDK permite controlar o zoom da câmera.
Referência da API
/**
* @brief Sets the camera zoom.
* @param zoom The zoom factor. The value ranges from 1 to the maximum zoom value supported by the camera.
* @return
* - 0: Success.
* - A non-zero value: Failure.
* @note This API is available only on iOS and Android.
*/
public abstract int setCameraZoom(float zoom);
/**
* @brief Gets the maximum zoom factor of the camera.
* @return The maximum zoom factor of the camera.
*/
public abstract float GetCameraMaxZoomFactor();
/**
* @brief Gets the current zoom factor of the camera.
* @return The current zoom factor of the camera.
*/
public abstract float GetCurrentZoom();
Exemplos
Android
// Get zoom information.
private void initZoomSeekBar() {
if (mAliRtcEngine != null) {
zoomSeekBar.setEnabled(true);
// Get the maximum zoom value.
float maxZoom = mAliRtcEngine.GetCameraMaxZoomFactor();
float currZoom = mAliRtcEngine.GetCurrentZoom();
// Set the SeekBar range (from 1.0 to maxZoom, with a step of 0.1).
if(maxZoom >= 1.0) {
int maxProgress = (int)((maxZoom - 1) * 10);
zoomSeekBar.setMax(maxProgress);
int currProgress = (int)((currZoom - 1) * 10);
zoomSeekBar.setProgress(currProgress);
} else{
zoomSeekBar.setEnabled(false);
}
}
}
// Set the zoom.
zoomSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(mAliRtcEngine != null) {
float newZoom = (float)((i+10) / 10.0);
mAliRtcEngine.setCameraZoom(newZoom);
zoomTextView.setText(String.format("%.1f", newZoom));
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
iOS
// Get zoom information.
self.cameraZoomSlider.isEnabled = true
let maxZoom = rtcEngine.getCameraMaxZoomFactor()
let currZoom = rtcEngine.getCurrentZoom()
"Get maxZoom=\(maxZoom), currZoom=\(currZoom)".printLog()
self.cameraZoomSlider.minimumValue = 1.0
if maxZoom > 1.0 {
self.cameraZoomSlider.maximumValue = maxZoom
} else {
self.cameraZoomSlider.isEnabled = false
}
if currZoom >= 1.0 && currZoom <= maxZoom {
self.cameraZoomSlider.value = currZoom
self.cameraZoomValueLabel.text = String(format: "%.1f", self.cameraZoomSlider.value)
}
else {
self.cameraZoomSlider.value = self.cameraZoomSlider.minimumValue
self.cameraZoomValueLabel.text = "\(self.cameraZoomSlider.minimumValue)"
}
// Set the zoom.
@IBOutlet weak var cameraZoomSlider: UISlider!
@IBOutlet weak var cameraZoomValueLabel: UILabel!
@IBAction func onCameraZoomChanged(_ sender: UISlider) {
let currValue = sender.value
self.cameraZoomValueLabel.text = String(format: "%.1f", currValue)
self.rtcEngine?.setCameraZoom(currValue)
}
Harmony
private handleZoomChange(value: number): void {
if (!this.rtcEngine) {
return;
}
// Calculate the zoom value based on the progress: zoom = 1.0 + (value / 10.0).
const newZoom = 1.0 + (value / 10.0);
// Clamp the zoom value between 1.0 and 10.0.
const clampedZoom = Math.max(1.0, Math.min(10.0, newZoom));
this.rtcEngine.setCameraZoom(clampedZoom);
this.zoomValue = clampedZoom.toFixed(1);
console.info(`Set zoom: ${clampedZoom}`);
}
Defina a exposição da câmera
Com o ARTC SDK, você ajusta a exposição da câmera para controlar o brilho da imagem.
Referência da API
/**
* @brief Sets the camera exposure.
* @param exposure The exposure value.
* @return
* - 0: Success.
* - A non-zero value: Failure.
*/
public abstract int SetExposure(float exposure);
/**
* @brief Gets the current camera exposure.
* @return The current camera exposure.
*/
public abstract float GetCurrentExposure();
/**
* @brief Gets the minimum camera exposure.
* @return The minimum camera exposure.
*/
public abstract float GetMinExposure();
/**
* @brief Gets the maximum camera exposure.
* @return The maximum camera exposure.
*/
public abstract float GetMaxExposure();
Exemplos
Android
// Get exposure information.
private void initExposureSeekBar() {
if (mAliRtcEngine != null) {
exposureSeekBar.setEnabled(true);
// Get the maximum exposure value.
float maxExposure = mAliRtcEngine.GetMaxExposure();
// Get the minimum exposure value.
float minExposure = mAliRtcEngine.GetMinExposure();
float currExposure = mAliRtcEngine.GetCurrentExposure();
if(maxExposure > minExposure) {
// Reset the SeekBar range.
int maxProgress = (int)((maxExposure - minExposure) * 10);
exposureSeekBar.setMax(maxProgress);
int currProgress = (int)((currExposure - minExposure) * 10);
exposureSeekBar.setProgress(currProgress);
} else {
exposureSeekBar.setEnabled(false);
}
}
}
// Set the exposure.
exposureSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(mAliRtcEngine != null) {
float minExposure = mAliRtcEngine.GetMinExposure();
float newExposure = minExposure + (float)(i / 10.0);
mAliRtcEngine.SetExposure(newExposure);
exposureTextView.setText(String.format("% .1f", newExposure));
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
iOS
// Get device exposure information.
self.cameraExposureSlider.isEnabled = true
let minExposure = rtcEngine.getMinExposure()
let maxExposure = rtcEngine.getMaxExposure()
let currExposure = rtcEngine.getCurrentExposure()
"Get minExposure=\(minExposure), maxExposure=\(maxExposure), currExposure=\(currExposure)".printLog()
if maxExposure > minExposure {
self.cameraExposureSlider.minimumValue = minExposure
self.cameraExposureSlider.maximumValue = maxExposure
} else {
self.cameraExposureSlider.isEnabled = false
}
if currExposure >= minExposure && currExposure <= maxExposure {
self.cameraExposureSlider.value = currExposure
self.cameraExposureValueLabel.text = String(format: "%.1f", self.cameraExposureSlider.value)
}
else {
self.cameraExposureSlider.value = self.cameraExposureSlider.minimumValue
self.cameraExposureValueLabel.text = "\(self.cameraExposureSlider.minimumValue)"
}
// Set the exposure.
@IBOutlet weak var cameraExposureValueLabel: UILabel!
@IBOutlet weak var cameraExposureSlider: UISlider!
@IBAction func onCameraExposureChanged(_ sender: UISlider) {
let currValue = sender.value
self.cameraExposureValueLabel.text = String(format: "%.1f", currValue)
self.rtcEngine?.setExposure(currValue)
}
Harmony
// Handle exposure change.
private handleExposureChange(value: number): void {
if (!this.rtcEngine) {
return;
}
// Conversion formula: exposure value = progress value / 10.
const actualValue = value / 10.0;
// Clamp the exposure value between -12.0 and 12.0.
const clampedExposure = Math.max(-12.0, Math.min(12.0, actualValue));
// Update the state.
this.exposureSliderValue = value;
this.exposureValue = this.formatExposureValue(clampedExposure);
// Call the RTC engine to set the exposure compensation.
try {
this.rtcEngine.setExposure(clampedExposure);
console.info(`Set exposure compensation: ${clampedExposure}`);
} catch (error) {
console.error('Failed to set exposure compensation:', error);
}
}
Defina manualmente o ponto de exposição
O ARTC SDK possibilita definir um ponto de exposição manualmente. Quando o usuário toca em um local na tela, a câmera ajusta a exposição com base nas condições de iluminação daquela área.
Antes de definir um ponto de exposição, chame
isCameraExposurePointSupportedpara verificar se o dispositivo oferece suporte a esse recurso.As coordenadas devem ser valores normalizados.
Referência da API
/**
* @brief Checks whether the camera supports setting a manual exposure point.
* @return
* - true: Supported.
* - false: Not supported.
* @note This API is available only on iOS and Android and is used to check if an exposure point can be set for the current camera.
*/
public abstract boolean isCameraExposurePointSupported();
/**
* @brief Sets the camera exposure point.
* @param x The normalized x-coordinate. The value ranges from 0 to 1.
* @param y The normalized y-coordinate. The value ranges from 0 to 1.
* @return
* - 0: Success.
* - A non-zero value: Failure.
* @note This API is available only on iOS and Android. After you call this method, the camera performs a one-time exposure adjustment at the specified point and maintains that exposure value.
*/
public abstract int setCameraExposurePoint(float x, float y);
Exemplos
Android
// Manually set the exposure point.
mLocalViewGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(@NonNull MotionEvent e) {
// Handle double-tap.
// ...
return true;
}
@Override
public boolean onSingleTapConfirmed(@NonNull MotionEvent e) {
// Handle single-tap.
if(mAliRtcEngine != null && mAliRtcEngine.isCameraExposurePointSupported()) {
float[] normalizedCoords = getNormalizedCoordinates(e.getX(), e.getY());
if (normalizedCoords[0] != -1 && normalizedCoords[1] != -1) {
mAliRtcEngine.setCameraExposurePoint(normalizedCoords[0], normalizedCoords[1]);
mCameraExposurePointX.setText(String.format("%.2f", normalizedCoords[0]));
mCameraExposurePointY.setText(String.format("%.2f", normalizedCoords[1]));
}
}
return true;
}
});
iOS
@objc func handleSeatViewTap(_ gesture: UITapGestureRecognizer) {
guard let localSeatView = self.localPreviewSeatView else {
return
}
guard let rtcEngine = self.rtcEngine, rtcEngine.isCameraExposurePointSupported() else { return }
let tapPoint = gesture.location(in: localSeatView)
// Convert the tap coordinates to normalized coordinates (0-1 range) of the video frame.
let normalizedX = tapPoint.x / localSeatView.bounds.width
let normalizedY = tapPoint.y / localSeatView.bounds.height
rtcEngine.setCameraExposurePoint(CGPoint(x: normalizedX, y: normalizedY))
self.cameraExposurePointXTextField.text = String(format: "%.2f", normalizedX)
self.cameraExposurePointYTextField.text = String(format: "%.2f", normalizedY)
}
Harmony
private handleSingleTap(touchX: number, touchY: number): void {
if (!this.rtcEngine) {
return;
}
// Get normalized coordinates.
const normalizedCoords = this.getNormalizedCoordinates(touchX, touchY);
if (normalizedCoords[0] !== -1 && normalizedCoords[1] !== -1) {
this.rtcEngine.setCameraExposurePoint(normalizedCoords[0], normalizedCoords[1]);
this.exposurePointX = normalizedCoords[0].toFixed(2);
this.exposurePointY = normalizedCoords[1].toFixed(2);
console.info('Set exposure point:', this.exposurePointX, this.exposurePointY);
}
}
Defina manualmente o ponto de foco
O ARTC SDK permite definir um ponto de foco manual da câmera. Esse funcionamento é semelhante ao recurso de ponto de exposição, mas ajusta a posição do foco da câmera. Antes de usar este recurso, chame isCameraFocusPointSupported para verificar o suporte do dispositivo.
Após definir manualmente um ponto de foco, o foco torna-se estático. Ele não rastreia continuamente a área nem se ajusta dinamicamente conforme o objeto se move. Para rastreamento dinâmico, considere usar o recurso de foco automático em rostos.
Referência da API
/**
* @brief Checks whether the camera supports manual focus.
* @return
* - true: Supported.
* - false: Not supported.
* @note This API is available only on iOS and Android and is used to check if a focus point can be set for the current camera.
*/
public abstract boolean isCameraFocusPointSupported();
/**
* @brief Sets the manual focus point for the camera.
* @param x The x-coordinate value (normalized).
* @param y The y-coordinate value (normalized).
* @return
* - 0: Success.
* - A non-zero value: Failure.
* @note This API is available only on iOS and Android. After you call this method, the camera performs a one-time focus adjustment at the specified point and maintains that focus value.
*/
public abstract int setCameraFocusPoint(float x, float y);
Exemplos
Os exemplos a seguir mostram como definir o ponto de exposição com um toque simples e o ponto de foco com um toque duplo.
Android
mLocalViewGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(@NonNull MotionEvent e) {
// Handle double-tap.
if(mAliRtcEngine != null && mAliRtcEngine.isCameraFocusPointSupported()) {
float[] normalizedCoords = getNormalizedCoordinates(e.getX(), e.getY());
if (normalizedCoords[0] != -1 && normalizedCoords[1] != -1) {
mAliRtcEngine.setCameraFocusPoint(normalizedCoords[0], normalizedCoords[1]);
mCameraFocusPointX.setText(String.format("%.2f", normalizedCoords[0]));
mCameraFocusPointY.setText(String.format("%.2f", normalizedCoords[1]));
}
}
return true;
}
@Override
public boolean onSingleTapConfirmed(@NonNull MotionEvent e) {
// Handle single-tap.
// ...
return true;
}
});
iOS
@objc func handleSeatViewDoubleTap(_ gesture: UITapGestureRecognizer) {
guard let localSeatView = self.localPreviewSeatView else {
return
}
guard let rtcEngine = self.rtcEngine, rtcEngine.isCameraFocusPointSupported() else { return }
let tapPoint = gesture.location(in: localSeatView)
// Convert the tap coordinates to normalized coordinates (0-1 range) of the video frame.
let normalizedX = tapPoint.x / localSeatView.bounds.width
let normalizedY = tapPoint.y / localSeatView.bounds.height
rtcEngine.setCameraFocus(CGPoint(x: normalizedX, y: normalizedY))
self.cameraFocusPointXTextField.text = String(format: "%.2f", normalizedX)
self.cameraFocusPointYTextField.text = String(format: "%.2f", normalizedY)
}
Harmony
private handleDoubleTap(touchX: number, touchY: number): void {
if (!this.rtcEngine) {
return;
}
// Get normalized coordinates.
const normalizedCoords = this.getNormalizedCoordinates(touchX, touchY);
if (normalizedCoords[0] !== -1 && normalizedCoords[1] !== -1) {
this.rtcEngine.setCameraFocusPoint(normalizedCoords[0], normalizedCoords[1]);
this.focusPointX = normalizedCoords[0].toFixed(2);
this.focusPointY = normalizedCoords[1].toFixed(2);
console.info('Set focus point:', this.focusPointX, this.focusPointY);
}
}
Foco automático em rostos
O ARTC SDK fornece uma API para ativar o foco automático em rostos. Em dispositivos compatíveis, a câmera detecta automaticamente rostos no quadro de vídeo e ajusta o foco para mantê-los nítidos.
Casos de uso: Reconhecimento facial, otimização de retratos e melhoria da qualidade visual em chamadas de vídeo.
Antes de começar, chame isCameraAutoFocusFaceModeSupported para verificar se o dispositivo atual oferece suporte a este recurso.
Referência da API
/**
* @brief Checks whether the camera supports the auto-focus on faces feature.
* @return
* - true: Supported.
* - false: Not supported.
* @note This API is available only on iOS and Android. It returns false if the camera is off.
* If the camera is on and supports both face detection and auto-focus, it returns true.
*/
public abstract boolean isCameraAutoFocusFaceModeSupported();
/**
* @brief Enables or disables the auto-focus on faces feature.
* @param enable
* - true: Enable.
* - false: Disable.
* @return
* - true: Success.
* - false: Failure.
* @note This API is available only on iOS and Android. If {@link AliRtcEngine#isCameraAutoFocusFaceModeSupported} returns true
* and you set enable to true, the camera continuously focuses on the detected faces.
*/
public abstract boolean setCameraAutoFocusFaceModeEnabled(boolean enable);
Exemplos
Android
if (mAliRtcEngine.isCameraAutoFocusFaceModeSupported()) {
mAliRtcEngine.setCameraAutoFocusFaceModeEnabled(isChecked);
}
iOS
@IBAction func onCameraAudoFocusSwitch(_ sender: UISwitch) {
if ((self.rtcEngine?.isCameraAutoFocusFaceModeSupported()) != nil) {
self.rtcEngine?.setCameraAutoFocusFaceModeEnabled(sender.isOn)
}
}
Ative ou desative o flash
O ARTC SDK permite ligar ou desligar o flash da câmera, o que é útil em condições de pouca luz ou para outras necessidades específicas de iluminação.
Este recurso está disponível apenas no iOS e Android e requer um flash de hardware.
O flash geralmente está disponível apenas para a câmera traseira. Câmeras frontais normalmente não possuem flash físico. Embora alguns dispositivos simulem um efeito de flash usando a tela, esta API não controla essa função.
Referência da API
/**
* @brief Turns the camera flashlight on or off.
* @param flash Specifies whether to turn on the flashlight.
* @return
* - 0: Success.
* - A non-zero value: Failure.
* @note This API is available only on iOS and Android. Typically, only the rear camera has a flashlight.
*/
public abstract int setCameraFlash(boolean flash);
Exemplos
Android
mCameraFlashSwitch = findViewById(R.id.camera_flash_switch);
mCameraFlashSwitch.setEnabled(false);
mCameraFlashSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (mAliRtcEngine != null) {
mAliRtcEngine.setCameraFlash(isChecked);
}
});
iOS
@IBOutlet weak var cameraFlashSwitch: UISwitch!
@IBAction func onCameraFlashSwitch(_ sender: UISwitch) {
if self.rtcEngine?.getCurrentCameraDirection() == .back {
self.rtcEngine?.setCameraFlash(sender.isOn)
}
}
Harmony
private handleFlashChange(value: boolean): void {
if (!this.rtcEngine) {
return;
}
this.rtcEngine.setCameraFlash(value);
}