Ikhtisar
ARTC SDK menyediakan fitur pengambilan video kustom yang fleksibel, memungkinkan Anda mengelola perangkat pengambilan video sesuai kebutuhan bisnis.
Secara default, kami menyarankan menggunakan pengambilan internal SDK. Namun, jika tidak memenuhi kebutuhan spesifik Anda terkait kualitas video, kompatibilitas perangkat, atau alur kerja pengambilan, fitur pengambilan video kustom menawarkan ekstensibilitas dan kustomisasi yang lebih besar.
Kode contoh
Pengambilan video kustom Android: Android/ARTCExample/AdvancedUsage/src/main/java/com/aliyun/artc/api/advancedusage/CustomVideoCaptureAndRender/CustomVideoCaptureActivity.java.
Pengambilan video kustom iOS: iOS/ARTCExample/AdvancedUsage/CustomVideoCapture/CustomVideoCaptureVC.swift.
Prasyarat
Sebelum memulai, pastikan Anda telah memenuhi persyaratan berikut:
Anda memiliki Akun Alibaba Cloud aktif, telah membuat aplikasi ARTC, serta telah memperoleh AppID dan AppKey. Untuk petunjuknya, lihat Buat aplikasi. Kredensial Anda tersedia di Konsol ApsaraVideo Live.
Anda telah mengintegrasikan ARTC SDK ke dalam proyek Anda dan menerapkan fitur panggilan audio dan video dasar. Untuk informasi selengkapnya, lihat Integrasikan ARTC SDK dan Terapkan panggilan audio dan video.
Implementasi
1. Nonaktifkan pengambilan internal
Panggil metode enableLocalVideo untuk menonaktifkan pengambilan internal SDK.
Android
/* Nonaktifkan pengambilan internal. */
mAliRtcEngine.enableLocalVideo(false);
/* Aktifkan pengambilan internal. Fitur ini diaktifkan secara default. */
mAliRtcEngine.enableLocalVideo(true);iOS
/* Nonaktifkan pengambilan internal. */
[_engine enableLocalVideo:NO];
/* Aktifkan pengambilan internal. Fitur ini diaktifkan secara default. */
[_engine enableLocalVideo:YES];Mac
/* Nonaktifkan pengambilan internal. */
[self.engine enableLocalVideo:NO];
/* Aktifkan pengambilan internal. Fitur ini diaktifkan secara default. */
[self.engine enableLocalVideo:YES];Windows
/* Nonaktifkan pengambilan internal. */
mAliRtcEngine->EnableLocalVideo(false);
/* Aktifkan pengambilan internal. Fitur ini diaktifkan secara default. */
mAliRtcEngine->EnableLocalVideo(true);2. Atur sumber video eksternal
Panggil setExternalVideoSource untuk mengatur sumber video eksternal. Parameter utamanya adalah:
enable: Menentukan apakah sumber video eksternal diaktifkan.
useTexture: Menentukan apakah input texture digunakan.
streamType: Menentukan aliran mana yang akan digantikan oleh SDK, seperti aliran kamera atau aliran berbagi layar.
renderMode: Mode render yang digunakan jika rasio aspek sumber video eksternal tidak sesuai dengan profil penerbitan. SDK akan menskalakan video sesuai mode ini.
Android
Input YUV
/* Input YUV */
/* Aktifkan pengambilan eksternal. Contoh ini menggunakan aliran kamera. Anda dapat menyesuaikan sourceType dan renderMode sesuai kebutuhan. */
mAliRtcEngine.setExternalVideoSource(true,false, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );
/* Nonaktifkan pengambilan eksternal. Contoh ini menggunakan aliran kamera. Anda dapat menyesuaikan sourceType sesuai kebutuhan. */
mAliRtcEngine.setExternalVideoSource(false,false, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );Input texture
/* Input texture */
/* Aktifkan pengambilan eksternal. Contoh ini menggunakan aliran kamera. Anda dapat menyesuaikan sourceType dan renderMode sesuai kebutuhan. */
mAliRtcEngine.setExternalVideoSource(true,true, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );
/* Nonaktifkan pengambilan eksternal. Contoh ini menggunakan aliran kamera. Anda dapat menyesuaikan sourceType sesuai kebutuhan. */
mAliRtcEngine.setExternalVideoSource(false,true, AliRtcVideoTrackCamera,AliRtcRenderModeAuto );iOS
/* Aktifkan pengambilan eksternal. Contoh ini menggunakan aliran kamera. Anda dapat menyesuaikan sourceType dan renderMode sesuai kebutuhan. */
[_engine setExternalVideoSource:YES sourceType:AliRtcVideosourceCameraType renderMode:AliRtcRenderModeAuto];
/* Nonaktifkan pengambilan eksternal. Contoh ini menggunakan aliran kamera. Anda dapat menyesuaikan sourceType sesuai kebutuhan. */
[_engine setExternalVideoSource:NO sourceType:AliRtcVideosourceCameraType renderMode:AliRtcRenderModeAuto]; Mac
/* Aktifkan pengambilan eksternal. Contoh ini menggunakan aliran kamera. Anda dapat menyesuaikan sourceType dan renderMode sesuai kebutuhan. */
[self.engine setExternalVideoSource:YES sourceType:AliRtcVideosourceCameraType renderMode:AliRtcRenderModeAuto];
/* Nonaktifkan pengambilan eksternal. Contoh ini menggunakan aliran kamera. Anda dapat menyesuaikan sourceType sesuai kebutuhan. */
[self.engine setExternalVideoSource:NO sourceType:AliRtcVideosourceCameraType renderMode:AliRtcRenderModeAuto];Windows
/* Input texture */
/* Aktifkan pengambilan eksternal. Contoh ini menggunakan aliran kamera. Anda dapat menyesuaikan sourceType dan renderMode sesuai kebutuhan. */
mAliRtcEngine->SetExternalVideoSource(true,true, AliEngineVideoTrackCamera,AliEngineRenderModeAuto );
/* Nonaktifkan pengambilan eksternal. Contoh ini menggunakan aliran kamera. Anda dapat menyesuaikan sourceType sesuai kebutuhan. */
mAliRtcEngine->SetExternalVideoSource(false,true, AliEngineVideoTrackCamera,AliEngineRenderModeAuto );3. Dorong frame video ke SDK
Setelah mengambil frame video, dorong frame tersebut ke ARTC SDK menggunakan metode pushExternalVideoFrame.
Android
Contoh input YUV:
/* Contoh ini menggunakan format YUV (I420). */
int width = 720;
int height = 1280;
AliRtcEngine.AliRtcVideoFormat videoformat = AliRtcEngine.AliRtcVideoFormat.AliRtcVideoFormatI420;
int[] lineSize = {width, width / 2, width / 2, 0};
int frameLength = width * height * 3 / 2;
byte[] buffer = new byte[frameLength];
/* Buat objek data untuk diteruskan ke SDK. */
AliRtcEngine.AliRtcRawDataFrame rawDataFrame
= new AliRtcEngine.AliRtcRawDataFrame(buffer,
videoformat,
width,
height,
lineSize,
0,
buffer.length);
/* Panggil API untuk mendorong objek data. */
int ret = mAliRtcEngine.pushExternalVideoFrame(rawDataFrame, AliRtcVideoTrackCamera);
if (ret != 0) {
/* Tangani error. */
}Contoh input texture:
/* Contoh ini menggunakan format texture. */
/* Buat lingkungan OpenGL. */
private static EglBase14 createEglBase14(EGLContext shareEglContext) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
EglBase14.Context eglBase14Context = shareEglContext == null ? null : new EglBase14.Context(shareEglContext);
EglBase14 eglBase14 = new EglBase14(eglBase14Context, EglBase.CONFIG_PIXEL_BUFFER);
try {
eglBase14.createDummyPbufferSurface();
eglBase14.makeCurrent();
} catch (RuntimeException e) {
Log.e(TAG, "CreateEGLBase14Context, gagal, " + e.getMessage());
}
return eglBase14;
}
return null;
}
/* Buat konteks untuk data masukan. */
float[] transformMatrix = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
int frameWidth = 720; /* Lebar gambar. */
int frameHeight = 1280; /* Tinggi gambar. */
int textureID = xxx; /* ID texture Anda. */
AliRtcEngine.AliRtcRawDataFrame aliRawDataFrame
= new AliRtcEngine.AliRtcRawDataFrame(textureID,
AliRtcVideoFormatTexture2D,
frameWidth,
frameHeight,
transformMatrix,
0,
0,
frameWidth,
frameHeight,
mEglBase14.getEglContext());
/* Panggil API untuk mendorong objek data. */
int ret = mAliRtcEngine.pushExternalVideoFrame(aliRawDataFrame, AliRtcVideoTrackCamera);
if (ret != 0) {
/* Tangani error. */
}iOS
/* Tentukan parameter berikut berdasarkan format data Anda. Contoh ini menggunakan format I420. */
AliRtcVideoDataSample *dataSample = [[AliRtcVideoDataSample alloc] init];
dataSample.dataPtr = (long)yuv_read_data;
dataSample.format = AliRtcVideoFormat_I420;
dataSample.type = AliRtcBufferType_Raw_Data;
dataSample.width = width;
dataSample.height = height;
dataSample.strideY = width;
dataSample.strideU = width/2;
dataSample.strideV = width/2;
dataSample.dataLength = dataSample.strideY * dataSample.height * 3/2;
/* Panggil API untuk mendorong objek data. */
int ret = [self.engine pushExternalVideoFrame:dataSample sourceType:AliRtcVideosourceCameraType];
if (ret != 0) {
/* Tangani error. */
}Mac
/* Tentukan parameter berikut berdasarkan format data Anda. Contoh ini menggunakan format I420. */
AliRtcVideoDataSample *dataSample = [[AliRtcVideoDataSample alloc] init];
dataSample.dataPtr = (long)yuv_read_data;
dataSample.format = AliRtcVideoFormat_I420;
dataSample.type = AliRtcBufferType_Raw_Data;
dataSample.width = width;
dataSample.height = height;
dataSample.strideY = width;
dataSample.strideU = width/2;
dataSample.strideV = width/2;
dataSample.dataLength = dataSample.strideY * dataSample.height * 3/2;
/* Panggil API untuk mendorong objek data. */
int ret = [self.engine pushExternalVideoFrame:dataSample sourceType:AliRtcVideosourceCameraType];
if (ret != 0) {
/* Tangani error. */
if ( ret == AliRtcErrAudioBufferFull ) {
// Buffer penuh. Tunggu 20 ms lalu coba lagi.
[NSThread sleepForTimeInterval:0.02] ;
continue ;
}
break ;
}Windows
AliEngineVideoRawData sample;
sample.dataPtr = (unsigned char*)cache_buf;
sample.format = AliEngineVideoFormatI420;
sample.width = mIYuvWidth;
sample.height = mIYuvHeight;
sample.strideY = mIYuvWidth;
sample.strideU = mIYuvWidth / 2;
sample.strideV = mIYuvWidth / 2;
sample.dataLength = frame_length;
sample.rotation = 0;
/* Panggil API untuk mendorong objek data. */
int ret = mAliRtcEngine->PushExternalVideoFrame(sample, AliEngineVideoTrackScreen);
if ( ret != 0 ) {
if ( ret == AliEngineErrorAudioBufferFull ) {
Sleep(20);
continue;
}else {
// Tangani error.
break ;
}
} else {
}