All Products
Search
Document Center

ApsaraVideo Live:Operasi dan konfigurasi video

Last Updated:Mar 26, 2026

Pelajari cara mengatur properti pengkodean video dengan memanggil API.

Fitur

Selama panggilan video atau streaming interaktif, Anda dapat mengonfigurasi pengaturan video seperti resolusi tangkapan, resolusi encoding, frame rate, bitrate, mode cermin, dan mode render.

  • Resolusi:

    • Capture resolution: Resolusi video dari perangkat tangkapan, seperti kamera.

    • Encoding resolution: Resolusi video yang telah dikodekan.

  • Bitrate: Jumlah bit yang ditransmisikan per detik (bps).

  • Frame rate: Jumlah frame yang ditampilkan per detik (fps).

Mengatur resolusi video, frame rate, dan bitrate yang sesuai memberikan pengalaman pengguna yang lebih baik. Memilih mode cermin dan render yang tepat memungkinkan Anda menyesuaikan gaya tampilan video.

Kode contoh

Penggunaan video dasar untuk Android: Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/VideoBasicUsage/VideoBasicUsageActivity.java.

Penggunaan video dasar untuk iOS: iOS/ARTCExample/BasicUsage/VideoBasicUsage/VideoBasicUsageVC.swift.

Penggunaan video dasar untuk Harmony: Harmony/ARTCExample/entry/src/main/ets/pages/basicusage/VideoBasicUsage.ets.

Prasyarat

Sebelum mengonfigurasi pengaturan video, pastikan Anda memenuhi persyaratan berikut:

Implementasi

1. Atur konfigurasi tangkapan kamera

ARTC menyediakan metode setCameraCapturerConfiguration untuk mengatur konfigurasi tangkapan kamera, termasuk arah kamera dan frame rate tangkapan.

Catatan
  • Panggil metode ini sebelum memulai kamera, misalnya sebelum memanggil startPreview atau joinChannel (yang secara otomatis memulai kamera).

  • Memanggil enableLocalVideo(false) untuk menonaktifkan tangkapan kamera akan melepaskan sumber daya kamera. Anda kemudian dapat mengatur ulang konfigurasinya.

image

Metode tersebut didefinisikan sebagai berikut:

/**
 * @brief Mengatur preferensi tangkapan.
 * @param cameraCapturerConfiguration Pengaturan tangkapan kamera.
 *      - preference:
 *        - {@link AliRtcCaptureOutputPreference#ALIRTC_CAPTURER_OUTPUT_PREFERENCE_PREVIEW} Prioritas pratinjau. Mengutamakan kualitas pratinjau video.
 *        - {@link AliRtcCaptureOutputPreference#ALIRTC_CAPTURER_OUTPUT_PREFERENCE_PERFORMANCE} Prioritas performa. Mengutamakan performa perangkat dengan memilih resolusi yang mendekati aliran yang dipublikasikan.
 *        - {@link AliRtcCaptureOutputPreference#ALIRTC_CAPTURER_OUTPUT_PREFERENCE_AUTO} Otomatis. SDK secara otomatis menyesuaikan resolusi tangkapan.
 *      - cameraDirection: Arah kamera. Anda dapat mengaturnya ke kamera depan atau belakang.
 * @return
 * - 0: Sukses.
 * - Nilai bukan nol: Gagal.
 * @note Anda harus memanggil metode ini sebelum memulai kamera, misalnya sebelum memanggil {@link #startPreview} atau {@link #joinChannel}.
 */
public abstract int setCameraCapturerConfiguration(AliEngineCameraCapturerConfiguration cameraCapturerConfiguration);

Tabel berikut menjelaskan parameter-parameter tersebut.

Parameter

Tipe

Deskripsi

preference

AliRtcCaptureOutputPreference

Preferensi tangkapan.

  • CAPTURER_OUTPUT_PREFERENCE_AUTO: SDK secara otomatis menyesuaikan pengaturan.

  • CAPTURER_OUTPUT_PREFERENCE_PERFORMANCE: Prioritas performa. SDK memilih pengaturan tangkapan yang paling sesuai dengan parameter encoding.

  • CAPTURER_OUTPUT_PREFERENCE_PREVIEW: Prioritas pratinjau. SDK memilih parameter input kamera berkualitas tinggi untuk mengutamakan pratinjau.

cameraDirection

AliRtcCameraDirection

Arah kamera (depan atau belakang).

fps

int

Frame rate tangkapan.

Nilai default: -1, yang berarti SDK menggunakan fps dari konfigurasi encoding (default internal SDK adalah 15).

cameraCaptureProfile

AliRtcCameraCaptureProfile

Resolusi tangkapan video.

  • Default: Mengikuti pengaturan encoder.

  • 1080p.

textureEncode

int

(Hanya Android) Menentukan apakah akan mengaktifkan encoding tekstur.

cameraTextureCapture

int

(Hanya Android) Menentukan apakah akan mengaktifkan tangkapan tekstur untuk kamera.

Kode contoh:

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. Atur konfigurasi encoder video

image

ARTC menyediakan metode setVideoEncoderConfiguration untuk mengatur properti pengkodean video, seperti resolusi video, frame rate, bitrate, dan interval keyframe. Properti-properti ini membantu mengelola kualitas video dalam berbagai kondisi jaringan.

Catatan

Anda dapat memanggil setVideoEncoderConfiguration sebelum atau setelah bergabung ke channel. Jika Anda hanya mengatur konfigurasi sekali per panggilan, kami menyarankan memanggil metode ini sebelum bergabung ke channel.

Tabel berikut menjelaskan parameter-parameter tersebut.

Parameter

Tipe

Deskripsi

dimensions

AliRtcVideoDimensions

Resolusi video. Default: 640x480. Maksimum: 1920x1080.

frameRate

int

Frame rate encoding video. Default: 15. Maksimum: 30.

bitrate

int

Bitrate video dalam kbps. Nilai default adalah 512. Jika Anda mengatur parameter ini ke 0, SDK secara otomatis menghitung bitrate yang sesuai berdasarkan resolusi dan frame rate video.

Jika bitrate yang ditentukan berada di luar rentang yang direkomendasikan untuk resolusi dan frame rate tertentu, SDK secara otomatis menyesuaikannya ke nilai yang valid. Untuk rentang bitrate yang direkomendasikan, lihat komentar dalam kode contoh.

keyFrameInterval

int

Interval keyframe, dalam milidetik. Nilai default adalah 0, yang berarti SDK mengontrol interval keyframe.

Catatan

Parameter ini diperlukan untuk streaming interaktif dan interoperabilitas dengan mini program.

forceStrictKeyFrameInterval

boolean

Menentukan apakah akan memaksa encoder untuk secara ketat menghasilkan keyframe pada interval yang ditetapkan. Default-nya adalah false.

  • false: Encoder merespons permintaan keyframe, misalnya ketika pengguna lain bergabung ke channel. Interval keyframe mungkin tidak secara ketat sesuai dengan nilai yang ditetapkan.

  • true: Encoder tidak merespons permintaan keyframe lain dan secara ketat menghasilkan keyframe pada interval yang ditetapkan. Hal ini dapat meningkatkan waktu hingga frame pertama muncul bagi subscriber.

mirrorMode

AliRtcVideoEncoderMirrorMode

Mode cermin untuk video yang dikodekan.

Catatan

Anda juga dapat menggunakan metode setVideoMirrorMode untuk mengatur mode cermin.

orientationMode

AliRtcVideoEncoderOrientationMode

Mode orientasi video yang dikodekan.

  • Adaptive: Orientasi video output sesuai dengan video yang ditangkap.

  • FixedLandscape: Orientasi landscape tetap.

  • FixedPortrait: Orientasi portrait tetap.

rotationMode

AliRtcRotationMode

Sudut rotasi video yang dikodekan. Nilai yang valid adalah 0, 90, 180, dan 270.

codecType

AliRtcVideoCodecType

Tipe codec.

  • default: Menggunakan pengaturan default perangkat.

  • software: Menggunakan encoding software.

  • hardware: Menggunakan encoding hardware.

  • hardwareTexture: Menggunakan encoding tekstur hardware.

encodeCodecType

AliRtcVideoEncodeCodecType

Format encoding video. Format yang didukung: default sistem, H.264, dan H.265.

seiForceFrontIFrame

int

Menentukan apakah akan memaksa I-frame sebelum mengirim pesan Supplemental Enhancement Information (SEI).

Nilai yang valid: -1 (default, setara dengan 1), 0 (tidak memaksa), dan 1 (memaksa).

Contoh pemanggilan API:

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;
// Panggil engine RTC untuk mengatur konfigurasi.
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. Beralih kamera

Secara default, SDK menggunakan kamera depan perangkat. Untuk menentukan kamera awal yang berbeda, panggil API setCameraCaptureConfiguration sebelum memulai tangkapan video. Jika tangkapan sudah aktif, panggil API switchCamera untuk beralih antara kamera depan dan belakang.

/**
 * @brief Beralih antara kamera depan dan belakang.
 * @return
 * - `0`: Sukses
 * - Bukan nol: Gagal
 * @note API ini hanya tersedia di iOS dan Android.
 */
public abstract int switchCamera();

Contoh penggunaan:

Android

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

iOS

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

Harmony

this.rtcEngine.switchCamera();

4. Kontrol kamera

Untuk mengontrol kamera selama panggilan audio/video, ARTC menyediakan dua API: muteLocalCamera dan enableLocalVideo.

API

muteLocalCamera

enableLocalVideo

Cara kerja

Mengganti aliran video dengan frame hitam.

Menghentikan perangkat keras kamera dari menangkap video dan melepaskan sumber dayanya.

Perilaku

Pratinjau lokal tetap aktif, tetapi pengguna remote melihat layar hitam.

Pratinjau lokal dan video remote membeku pada frame terakhir yang ditangkap.

Karakteristik

  • Mempertahankan koneksi aliran video. Pengguna remote tidak mengalami gangguan video.

  • Perpindahan cepat dengan latensi respons rendah. Ideal untuk skenario yang memerlukan pengaktifan/nonaktifan status video secara sering.

  • Melepaskan sumber daya kamera.

  • Perpindahan lebih lambat dengan latensi respons lebih tinggi. Ideal untuk skenario di mana kamera dinonaktifkan dalam periode yang lama, seperti dalam panggilan hanya audio.

4.1. Bisukan atau aktifkan kembali video lokal

image

Anda dapat menggunakan API muteLocalCamera untuk membisukan video. API ini menjaga pipeline tangkapan, encoding, dan transmisi video tetap aktif tetapi mengirim frame hitam ke pengguna remote. Pratinjau lokal tidak terpengaruh.

/**
 * @brief Membisukan atau mengaktifkan kembali aliran video lokal.
 * @param mute true: Mengirim frame hitam. false: Melanjutkan pengiriman frame video normal.
 * @param track Track video yang akan dibisukan. Hanya {@link AliRtcVideoTrack#AliRtcVideoTrackCamera} yang didukung.
 * @return
 * - 0: Sukses.
 * - Nilai bukan nol: Gagal.
 * @note Metode ini mengirim frame hitam sementara pratinjau lokal tetap tidak terpengaruh. Pipeline tangkapan video terus berjalan.
 */
public abstract int muteLocalCamera(boolean mute, AliRtcVideoTrack track);
/**
 * @brief Terjadi ketika pengguna remote membisukan atau mengaktifkan kembali aliran video mereka.
 * @param uid ID pengguna yang memanggil muteLocalCamera.
 * @param isMute
 * - true: Pengguna mengirim frame hitam.
 * - false: Pengguna mengirim frame video normal.
 */
public void onUserVideoMuted(String uid ,boolean isMute){}

Android

Bisukan atau aktifkan kembali aliran video:

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

Dengarkan callback remote:

@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

Bisukan atau aktifkan kembali aliran video:

@IBAction func onVideoMuteSwitched(_ sender: UISwitch) {
    if sender.isOn {
        // Mengirim frame hitam.
        rtcEngine?.muteLocalCamera(true, for: AliRtcVideoTrack.camera)
    } else {
        // Melanjutkan pengiriman frame video normal.
        rtcEngine?.muteLocalCamera(false, for: AliRtcVideoTrack.camera)
    }
}

Dengarkan callback remote:

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

Harmony

Bisukan atau aktifkan kembali aliran video:

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

Dengarkan callback remote:

listener.onUserVideoMuted((uid : string, isMute : boolean) => {
  console.info(`Video pengguna ${uid} telah ${isMute ? 'dibisukan' : 'diaktifkan kembali'}`);
});

macOS

Bisukan atau aktifkan kembali aliran video:

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

Dengarkan callback remote:

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

Windows

Bisukan atau aktifkan kembali aliran video:

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

Dengarkan callback remote:

void CTutorialDlg::OnUserVideoMuted(const char* uid, bool isMute)
{
    // Temukan tampilan pengguna yang sesuai untuk memperbarui statusnya.
	PartUserDlg *partUserView = mRemotePartDlgs[uid];
	if (nullptr != partUserView)
	{
		partUserView->muteStream = isMute;
		updateRemoteParticipants();
	}
}

4.2. Aktifkan atau nonaktifkan tangkapan video

image

API enableLocalVideo mengontrol perangkat tangkapan video lokal, seperti kamera. Menonaktifkannya akan menghentikan tangkapan dan transmisi video, serta melepaskan perangkat tersebut.

/**
 * @brief Mengaktifkan atau menonaktifkan tangkapan video lokal.
 * @param enabled
 * - true: Mengaktifkan tangkapan video lokal.
 * - false: Menonaktifkan tangkapan video lokal.
 * @return
 * - 0: Sukses.
 * - < 0: Gagal.
 * @note Fitur ini diaktifkan secara default. Dengarkan callback {@link AliRtcEngineNotify#onUserVideoEnabled} untuk diberi tahu tentang perubahan status tangkapan video pengguna remote.
 */
public abstract int enableLocalVideo(boolean enabled);
/**
 * @brief Terjadi ketika pengguna remote mengaktifkan atau menonaktifkan tangkapan video lokal mereka.
 * @param uid ID pengguna yang memanggil enableLocalVideo.
 * @param isEnable
 * - true: Pengguna mengaktifkan tangkapan video lokal.
 * - false: Pengguna menonaktifkan tangkapan video lokal.
 */
public void onUserVideoEnabled(String uid, boolean isEnable){}

Android

Aktifkan atau nonaktifkan tangkapan video:

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

Dengarkan callback remote:

@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

Aktifkan atau nonaktifkan tangkapan video:

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

Dengarkan callback remote:

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

Harmony

Aktifkan atau nonaktifkan tangkapan video:

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

    }
  }
}

Dengarkan callback remote:

listener.onUserVideoEnabled((uid : string, isEnable : boolean) => {
  console.info(`Video pengguna ${uid} telah ${isEnable ? 'diaktifkan' : 'dinonaktifkan'}`);
});

macOS

Aktifkan atau nonaktifkan tangkapan video:

[self.engine enableLocalVideo:isOpen];

Dengarkan callback remote:

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

Windows

Aktifkan atau nonaktifkan tangkapan video:

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

Dengarkan callback remote:

void CTutorialDlg::OnUserVideoEnabled(const char* uid, bool isEnable) {
    // Temukan tampilan pengguna yang sesuai untuk memperbarui statusnya.
	PartUserDlg *partUserView = mRemotePartDlgs[uid];
	if (nullptr != partUserView)
	{
		partUserView->enableVideo = isEnable;
		updateRemoteParticipants();
	}
}

5. Mulai atau hentikan pratinjau

ARTC menyediakan API startPreview dan stopPreview untuk memulai atau menghentikan pratinjau lokal.

Catatan:

  • Anda harus memanggil setLocalViewConfig untuk mengatur tampilan render sebelum memulai pratinjau.

  • Secara default, SDK memulai pratinjau saat Anda bergabung ke channel. Jika Anda perlu memulai pratinjau sebelum bergabung ke channel, panggil startPreview.

  • Setelah menghentikan pratinjau, tampilan lokal membeku pada frame terakhir.

Urutan pemanggilan API

image

Berikut adalah contoh kode:

Android

Mulai pratinjau:

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

        // Atur tampilan lokal.
        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(); // Tangani potensi pengecualian
                }
            }
        }
        // Mulai pratinjau.
        mAliRtcEngine.startPreview();
    }
}

Hentikan pratinjau:

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

iOS

Mulai pratinjau:

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

Hentikan pratinjau:

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

Harmony

Mulai pratinjau:

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

Hentikan pratinjau:

this.rtcEngine.stopPreview();

Mac

Mulai pratinjau:

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

Hentikan pratinjau:

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

Windows

Mulai pratinjau:

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

Hentikan pratinjau:

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

6. Atur mode cermin

Metode setVideoMirrorMode mengontrol pencerminan pratinjau video lokal dan aliran yang dipublikasikan. Anda dapat memanggil metode ini saat runtime, sehingga cocok untuk panggilan video dan streaming langsung.

/**
 * @brief Mengatur mode cermin untuk pratinjau video lokal dan aliran yang dipublikasikan.
 * @param mirrorMode Mode cermin yang akan diatur.
 * @return
 * - 0: Sukses.
 * - <0: Gagal.
 *  - AliRtcErrInner: Terjadi kesalahan status internal SDK. Pastikan instans SDK berhasil dibuat.
 *
 * @note
 * - Anda dapat memanggil metode ini untuk mengubah mode cermin saat runtime, baik sebelum maupun setelah bergabung ke channel. SDK mencatat status dan menerapkan pengaturan saat pratinjau dan encoding aktif.
 * - Metode ini menggantikan pengaturan cermin yang dikonfigurasi di `setLocalViewConfig` dan `setVideoEncoderConfiguration`.
 * - Pengaturan metode ini menduplikasi pengaturan di `setLocalViewConfig` dan `setVideoEncoderConfiguration`. Gunakan hanya satu metode untuk mengonfigurasi pencerminan.
 */
public abstract int setVideoMirrorMode(AliRtcVideoPipelineMirrorMode mirrorMode);

Tabel berikut menjelaskan mode-mode cermin.

Nilai enum

Deskripsi

AliRtcVideoPipelineMirrorModeNoMirror

Pencerminan dinonaktifkan untuk pratinjau dan encoding.

AliRtcVideoPipelineMirrorModeBothMirror

Mengaktifkan pencerminan untuk pratinjau dan encoding (default).

AliRtcVideoPipelineMirrorModeOnlyPreviewMirror

Mengaktifkan pencerminan hanya untuk pratinjau.

AliRtcVideoPipelineMirrorModeOnlyPublishMirror

Mengaktifkan pencerminan hanya untuk aliran yang dipublikasikan.

Kode contoh:

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. Atur tampilan render

Sebelum menampilkan pratinjau lokal atau video pengguna remote, panggil API setLocalViewConfig atau setRemoteViewConfig untuk mengatur tampilan render.

// Mengatur tampilan render untuk pratinjau lokal.
public abstract int setLocalViewConfig(AliRtcVideoCanvas viewConfig, AliRtcVideoTrack track);
// Mengatur tampilan render untuk pengguna remote tertentu.
public abstract int setRemoteViewConfig(AliRtcVideoCanvas canvas, String uid, AliRtcVideoTrack track);

Konfigurasi umum AliRtcVideoCanvas:

Parameter

Tipe

Deskripsi

view

View

Tampilan (wajib).

renderMode

AliRtcRenderMode

Mode render.

  • Auto: SDK secara otomatis memilih mode render.

  • Stretch: Meregangkan video agar mengisi tampilan. Jika rasio aspek video dan tampilan berbeda, video akan terdistorsi.

  • Fill: Menskalakan video secara proporsional agar sesuai dengan tampilan. Jika rasio aspek video dan tampilan berbeda, SDK menambahkan bilah hitam pada ruang yang tersisa.

  • Clip: Menskalakan video secara proporsional agar mengisi tampilan. Jika rasio aspek video dan tampilan berbeda, SDK memotong video agar sesuai.

mirrorMode

AliRtcRenderMirrorMode

Mode cermin.

  • Mengaktifkan pencerminan hanya untuk pratinjau kamera depan lokal.

  • Mengaktifkan pencerminan untuk semua tampilan video (lokal dan remote).

  • Menonaktifkan semua pencerminan.

rotationMode

AliRtcRotationMode

Mode rotasi. Nilai yang valid: 0, 90, 180, dan 270 derajat.

backgroundColor

int

Warna latar belakang dalam format heksadesimal RGB, misalnya 0x000000.

textureId

int

(Hanya Android) ID tekstur, digunakan untuk menampilkan tekstur OpenGL ES pihak ketiga.

textureWidth

int

(Hanya Android) Lebar tekstur.

textureHeight

int

(Hanya Android) Tinggi tekstur.

sharedContext

long

(Hanya Android) Konteks OpenGL ES bersama untuk tekstur.

Kode contoh:

7.1. Atur tampilan render lokal

Android

mLocalVideoCanvas = new AliRtcEngine.AliRtcVideoCanvas();
// Dapatkan dan atur 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;
// Atur tampilan pratinjau lokal.
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;
/* Handle jendela */
canvas.view = mHWnd;
canvas.mirrorMode = AliEngineRenderMirrorModeAllNoMirror;
mAliRtcEngine->setLocalViewConfig(canvas, AliEngineVideoTrackCamera);

Harmony

// Buat atau gunakan kembali 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. Atur tampilan render remote

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()
    // Menangani ketersediaan aliran pengguna remote.
    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(@"Callback informasi aliran pengguna remote");
            
            __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

// Notifikasi ketersediaan aliran audio/video remote
listener.onRemoteTrackAvailableNotify((userId: string, audioTrack: AliRtcAudioTrack,
  videoTrack: AliRtcVideoTrack) => {
  console.info(`Aliran audio/video remote tersedia: userId=${userId}, videoTrack=${videoTrack}`);

  // Konfigurasikan tampilan remote berdasarkan jenis aliran video.
  if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackCamera) {
    // Aliran kamera tersedia.
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackCamera);
    this.removeRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackScreen);
  } else if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackScreen) {
    // Aliran berbagi layar tersedia.
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackScreen);
    this.removeRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackCamera);
  } else if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackBoth) {
    // Aliran ganda tersedia (kamera + berbagi layar).
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackCamera);
    this.viewRemoteVideo(userId, AliRtcVideoTrack.AliRtcVideoTrackScreen);
  } else if (videoTrack === AliRtcVideoTrack.AliRtcVideoTrackNo) {
    // Tidak ada aliran video.
    this.removeAllRemoteVideo(userId);
  }
});