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:
Anda memiliki Akun Alibaba Cloud yang valid dan telah membuat aplikasi ARTC. Untuk petunjuknya, lihat Buat aplikasi. Anda akan memerlukan App ID dan App Key dari Konsol ApsaraVideo Live.
Anda telah mengintegrasikan SDK ARTC ke dalam proyek Anda dan menerapkan fitur panggilan audio dan video dasar. Untuk petunjuknya, lihat Unduh/Integrasi SDK dan Terapkan panggilan audio dan video.
Implementasi
1. Atur konfigurasi tangkapan kamera
ARTC menyediakan metode setCameraCapturerConfiguration untuk mengatur konfigurasi tangkapan kamera, termasuk arah kamera dan frame rate tangkapan.
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.
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 |
| Preferensi tangkapan.
| |
| Arah kamera (depan atau belakang). | |
| int | Frame rate tangkapan. Nilai default: -1, yang berarti SDK menggunakan fps dari konfigurasi encoding (default internal SDK adalah 15). |
| Resolusi tangkapan video.
| |
| int | (Hanya Android) Menentukan apakah akan mengaktifkan encoding tekstur. |
| 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
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.
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 |
| Resolusi video. Default: 640x480. Maksimum: 1920x1080. | |
| int | Frame rate encoding video. Default: 15. Maksimum: 30. |
| 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. |
| 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. |
| boolean | Menentukan apakah akan memaksa encoder untuk secara ketat menghasilkan keyframe pada interval yang ditetapkan. Default-nya adalah
|
| Mode cermin untuk video yang dikodekan. Catatan Anda juga dapat menggunakan metode | |
| Mode orientasi video yang dikodekan.
| |
| Sudut rotasi video yang dikodekan. Nilai yang valid adalah 0, 90, 180, dan 270. | |
| Tipe codec.
| |
| Format encoding video. Format yang didukung: default sistem, H.264, dan H.265. | |
| int | Menentukan apakah akan memaksa I-frame sebelum mengirim pesan Supplemental Enhancement Information (SEI). Nilai yang valid: |
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 |
|
|
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 |
|
|
4.1. Bisukan atau aktifkan kembali video lokal
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
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
setLocalViewConfiguntuk 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
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 = nilHarmony
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 |
| Pencerminan dinonaktifkan untuk pratinjau dan encoding. |
| Mengaktifkan pencerminan untuk pratinjau dan encoding (default). |
| Mengaktifkan pencerminan hanya untuk pratinjau. |
| 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 |
|
| Tampilan (wajib). |
|
| Mode render.
|
|
| Mode cermin.
|
|
| Mode rotasi. Nilai yang valid: 0, 90, 180, dan 270 derajat. |
|
| Warna latar belakang dalam format heksadesimal RGB, misalnya 0x000000. |
|
| (Hanya Android) ID tekstur, digunakan untuk menampilkan tekstur OpenGL ES pihak ketiga. |
|
| (Hanya Android) Lebar tekstur. |
|
| (Hanya Android) Tinggi tekstur. |
|
| (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);
}
});