All Products
Search
Document Center

Alibaba Cloud Model Studio:Input video kustom

Last Updated:Sep 02, 2026

Menjelaskan dua mode input video kustom yang didukung oleh AOQ Client SDK—mode raw frame dan mode encoded frame—serta konfigurasi dan contoh kode untuk masing-masing.

Ikhtisar

Modul video bawaan AOQ Client SDK mencakup kebutuhan video dasar, tetapi dalam beberapa skenario modul tangkapan bawaan mungkin tidak mencukupi. Tangkapan video kustom berguna ketika Anda perlu:

  • Mengatasi konflik atau masalah kompatibilitas perangkat kamera.
  • Memasukkan data video dari sistem tangkapan kustom atau file video ke dalam SDK untuk transmisi.
  • Menyiarkan frame yang dihasilkan AI, rekaman layar, atau konten kamera virtual melalui SDK.

AOQ Client SDK mendukung dua mode input video kustom:

  • Raw frame mode: Tangkap frame video mentah dalam format seperti BGRA, I420, NV12, atau NV21, lalu dorong ke SDK melalui pushExternalVideoCapturedFrame. SDK menangani encoding dan transmisi secara internal.
  • Encoded frame mode: Encode frame video sendiri (saat ini hanya JPEG), lalu dorong data yang telah diencode langsung ke SDK melalui pushExternalVideoEncodedFrame, melewati encoder internal SDK.

Kode contoh

Segera hadir.

Prasyarat

  • Instans engine telah dibuat dengan memanggil createEngine.
  • Koneksi ke server telah terjalin (callback onConnectionStatusChange telah melaporkan AoqConnectionStatusConnected).

Implementasi

Pilih salah satu dari dua mode berdasarkan kasus penggunaan Anda. Kedua mode tidak dapat digunakan secara bersamaan: hanya satu antarmuka push yang dapat aktif dalam satu waktu.

Mode 1: Raw frame mode

Tangkap frame video mentah dalam format seperti BGRA, I420, NV12, atau NV21 dan dorong ke SDK untuk encoding dan transmisi. SDK menangani seluruh pipeline encoding dan pengiriman secara internal.

1. Konfigurasikan parameter encoding video

Encoder internal SDK mengencode frame mentah yang Anda dorong. Sesuaikan parameter encoding agar sesuai dengan kasus penggunaan Anda.

AoqClientEngine.AoqVideoCodecConfig config = new AoqClientEngine.AoqVideoCodecConfig();
config.width            = 1280;
config.height           = 720;
config.fps              = 2;
config.bitrate          = 500000;   // Bitrate awal: 500 kbps
config.minBitrate       = 128000;   // Bitrate minimum: 128 kbps
config.keyframeInterval = 2;
// Biarkan isExternal bernilai false default — SDK menangani encoding secara internal

engine.setVideoEncoderConfig(config);
Parameter:

Parameter

Tipe

Default

Deskripsi

trackType

AoqTrackType

AoqTrackTypeVideo

Jenis track video

codecType

AoqEncoderType

AoqEncoderTypeVideoH264

Jenis encoder

width

int

720

Lebar encoding (piksel)

height

int

1280

Tinggi encoding (piksel)

fps

int

5

Laju frame

bitrate

int

500000

Bitrate awal (bps)

minBitrate

int

128000

Bitrate minimum (bps)

keyframeInterval

int

2

Interval keyframe (detik)

isExternal

boolean

false

Biar tetap false untuk raw frame mode

mirrorMode

AoqMirrorMode

AoqMirrorModeDisabled

Mode cermin

orientationMode

AoqOrientationMode

AoqOrientationModeAuto

Mode orientasi

2. Mulai tangkapan video dalam mode tangkapan eksternal

Panggil startVideoCapture dengan isExternal=true untuk memberi tahu SDK agar tidak membuka kamera dan mengharapkan frame dari sumber eksternal. Ini wajib dilakukan untuk raw frame mode—jika Anda melewatkan pemanggilan ini, SDK tidak akan mengonsumsi frame yang Anda dorong.

AoqClientEngine.AoqVideoCaptureConfig config = new AoqClientEngine.AoqVideoCaptureConfig();
config.isExternal = true;  // Jangan buka kamera; sumber eksternal akan mendorong frame
// Saat isExternal=true, width/height/fps tidak berpengaruh — resolusi aktual
// dan laju frame ditentukan oleh data yang didorong
int ret = engine.startVideoCapture(config);
Parameter:

Parameter

Tipe

Default

Deskripsi

width

int

1280

Lebar tangkapan (diabaikan saat isExternal=true)

height

int

720

Tinggi tangkapan (diabaikan saat isExternal=true)

fps

int

15

Laju frame tangkapan (diabaikan saat isExternal=true)

isExternal

boolean

false

true: jangan buka kamera; sumber eksternal menyediakan frame

cameraDirection

AoqCameraDirection

AoqCameraDirectionFront

Arah kamera (diabaikan saat isExternal=true)

3. Dorong frame video mentah

Panggil pushExternalVideoCapturedFrame untuk memasukkan frame mentah yang telah ditangkap ke dalam SDK. SDK menangani encoding dan transmisi.

Format yang didukung: BGRA, I420, NV12, NV21, RGBA. Pada platform Apple, zero-copy CVPixelBuffer juga didukung.

3.1 Format BGRA

BGRA adalah format packed dengan 4 byte per piksel (Blue, Green, Red, Alpha). Ukuran frame = lebar × tinggi × 4 byte.

// Buat frame video BGRA
AoqClientEngine.AoqVideoFrame frame = new AoqClientEngine.AoqVideoFrame();
frame.format    = AoqClientEngine.AoqVideoPixelFormat.AoqVideoPixelFormatBGRA;
frame.width     = 1280;
frame.height    = 720;

frame.data      = bgraBytes; // byte[], panjang = width * height * 4

frame.timeStamp = System.currentTimeMillis();

int ret = engine.pushExternalVideoCapturedFrame(
    AoqClientEngine.AoqTrackType.AoqTrackTypeVideo, frame);

3.2 Format I420

I420 adalah format planar dengan tiga bidang terpisah (Y, U, V). Ukuran bidang Y = lebar × tinggi; bidang U dan V masing-masing berukuran (lebar/2) × (tinggi/2).

// Buat frame video I420
AoqClientEngine.AoqVideoFrame frame = new AoqClientEngine.AoqVideoFrame();
frame.format    = AoqClientEngine.AoqVideoPixelFormat.AoqVideoPixelFormatI420;
frame.width     = 1280;
frame.height    = 720;

frame.dataY     = yPlane;  // byte[], panjang = width * height

frame.dataU     = uPlane;  // byte[], panjang = (width/2) * (height/2)

frame.dataV     = vPlane;  // byte[], panjang = (width/2) * (height/2)

frame.strideY   = 1280;    // Stride baris bidang Y (byte)
frame.strideU   = 640;     // Stride baris bidang U (byte)
frame.strideV   = 640;     // Stride baris bidang V (byte)
frame.timeStamp = System.currentTimeMillis();

int ret = engine.pushExternalVideoCapturedFrame(
    AoqClientEngine.AoqTrackType.AoqTrackTypeVideo, frame);

3.3 Format NV12 / NV21

NV12 dan NV21 adalah format semi-planar yang terdiri dari bidang Y dan bidang UV interleaved. NV12 menginterleaving UV dalam urutan tersebut; NV21 menginterleaving VU. Ukuran frame = lebar × tinggi × 3 / 2 byte, dikemas ke dalam field data.

// Buat frame video NV12 (NV21 identik — cukup ubah field format)
AoqClientEngine.AoqVideoFrame frame = new AoqClientEngine.AoqVideoFrame();
frame.format    = AoqClientEngine.AoqVideoPixelFormat.AoqVideoPixelFormatNV12;
frame.width     = 1280;
frame.height    = 720;

frame.data      = nv12Bytes; // byte[], panjang = width * height * 3 / 2

frame.timeStamp = System.currentTimeMillis();

int ret = engine.pushExternalVideoCapturedFrame(
    AoqClientEngine.AoqTrackType.AoqTrackTypeVideo, frame);

3.4 Format CVPixelBuffer (platform Apple)

Pada iOS dan macOS, Anda dapat meneruskan CVPixelBufferRef secara langsung untuk transfer zero-copy, menghindari overhead performa akibat penyalinan memori.

// iOS / macOS
let frame = AoqVideoFrame()
frame.format      = .cvPixelBuffer
frame.width       = 1280
frame.height      = 720
frame.pixelBuffer = pixelBuffer  // CVPixelBufferRef
frame.timeStamp   = Int64(Date().timeIntervalSince1970 * 1000)

// SDK menyimpan pixelBuffer secara asinkron — pertahankan dengan +1 ref count.
// SDK melepaskannya setelah selesai.
let _ = Unmanaged.passRetained(pixelBuffer)

engine.pushExternalVideoCapturedFrame(.video, frame: frame)

4. Hentikan tangkapan raw frame

Saat Anda tidak lagi perlu mendorong frame, hentikan timer push terlebih dahulu, lalu panggil stopVideoCapture untuk mematikan tangkapan video.

// 1. Hentikan timer push frame
stopExternalFramePush();
// 2. Hentikan tangkapan video
engine.stopVideoCapture();

Mode 2: Encoded frame mode

Encode frame video sendiri (saat ini hanya JPEG) dan dorong data yang telah diencode langsung ke SDK, melewati encoder internal. Mode ini tidak memerlukan pemanggilan startVideoCapture atau API terkait tangkapan lainnya.

1. Konfigurasikan parameter encoding video dan aktifkan encoding eksternal

Panggil setVideoEncoderConfig dengan isExternal=true untuk memberi tahu SDK agar melewati encoder internal dan mengharapkan data yang telah diencode dari luar.

AoqClientEngine.AoqVideoCodecConfig config = new AoqClientEngine.AoqVideoCodecConfig();
config.width      = 1280;
config.height     = 720;
config.fps        = 2;
config.isExternal = true;  // Lewati encoding internal; sumber eksternal menyediakan frame yang telah diencode

engine.setVideoEncoderConfig(config);

Setelah dikonfigurasi, Anda dapat segera mendorong frame yang telah diencode—tidak perlu memanggil startVideoCapture.

2. Dorong frame video yang telah diencode

Panggil pushExternalVideoEncodedFrame untuk meneruskan data video yang telah diencode langsung ke SDK. Saat ini hanya encoding JPEG yang didukung.

// Hasilkan data JPEG dari Bitmap
android.graphics.Bitmap bmp = android.graphics.Bitmap.createBitmap(
    width, height, android.graphics.Bitmap.Config.ARGB_8888);
// ... isi konten Bitmap ...

java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
bmp.compress(android.graphics.Bitmap.CompressFormat.JPEG, 85, baos);
bmp.recycle();

// Buat frame yang telah diencode dan dorong
AoqClientEngine.AoqVideoEncodedFrame frame = new AoqClientEngine.AoqVideoEncodedFrame();
frame.codec     = AoqClientEngine.AoqVideoCodecType.AoqVideoCodecTypeJPEG;
frame.data      = baos.toByteArray();
frame.width     = width;
frame.height    = height;
frame.timeStamp = System.currentTimeMillis();

int ret = engine.pushExternalVideoEncodedFrame(
    AoqClientEngine.AoqTrackType.AoqTrackTypeVideo, frame);
Parameter AoqVideoEncodedFrame:

Parameter

Tipe

Default

Deskripsi

codec

AoqVideoCodecType

AoqVideoCodecTypeJPEG

Format encoding; saat ini hanya JPEG yang didukung

data

byte[]

null

Data frame yang telah diencode

width

int

0

Lebar frame (piksel)

height

int

0

Tinggi frame (piksel)

timeStamp

long

0

Timestamp (milidetik); saat 0, SDK menggunakan jam lokal

3. Hentikan pendorongan frame yang telah diencode

Encoded frame mode tidak melibatkan perangkat tangkapan apa pun, sehingga penghentian cukup dengan menghentikan timer push Anda.

stopExternalFramePush();

Referensi

AoqVideoFrame (raw frame mode)

Bidang

Tipe

Deskripsi

format

AoqVideoPixelFormat

Format piksel

width

int

Lebar frame (piksel)

height

int

Tinggi frame (piksel)

data

byte[]

Data format packed (NV12/NV21/BGRA/RGBA)

dataY

byte[]

Data bidang Y I420

dataU

byte[]

Data bidang U I420

dataV

byte[]

Data bidang V I420

strideY

int

Stride baris bidang Y I420 (byte)

strideU

int

Stride baris bidang U I420 (byte)

strideV

int

Stride baris bidang V I420 (byte)

textureId

int

ID tekstur Android (TextureOES/Texture2D)

transformMatrix

float[]

Matriks transformasi tekstur (4×4, row-major)

eglContext

EGLContext

Konteks EGL bersama Android (untuk mode tekstur)

pixelBuffer

CVPixelBufferRef

CVPixelBuffer zero-copy Apple (hanya iOS/macOS)

timeStamp

long

Timestamp (milidetik); saat 0, SDK menggunakan jam lokal

Nilai enum AoqVideoPixelFormat

Nilai enum

Nilai numerik

Deskripsi

AoqVideoPixelFormatUnknown

0

Format tidak dikenal

AoqVideoPixelFormatI420

1

Format planar I420

AoqVideoPixelFormatNV12

2

Format semi-planar NV12 (UV interleaved)

AoqVideoPixelFormatNV21

3

Format semi-planar NV21 (VU interleaved)

AoqVideoPixelFormatBGRA

4

Format packed BGRA

AoqVideoPixelFormatRGBA

5

Format packed RGBA

AoqVideoPixelFormatCVPixelBuffer

6

CVPixelBuffer Apple (hanya iOS/macOS)

AoqVideoPixelFormatTextureOES

7

Tekstur eksternal OES Android

AoqVideoPixelFormatTexture2D

8

Tekstur 2D Android

AoqVideoEncodedFrame (encoded frame mode)

Bidang

Tipe

Deskripsi

codec

AoqVideoCodecType

Format encoding

data

byte[]

Data frame yang telah diencode

width

int

Lebar frame (piksel)

height

int

Tinggi frame (piksel)

timeStamp

long

Timestamp (milidetik); saat 0, SDK menggunakan jam lokal

Nilai enum AoqVideoCodecType

Nilai enum

Nilai numerik

Deskripsi

AoqVideoCodecTypeJPEG

0

Format encoding JPEG

Catatan penting

  • Raw frame mode: Anda harus memanggil startVideoCapture(isExternal=true) sebelum mendorong frame. Jika Anda melewatkan pemanggilan ini, SDK akan mengembalikan error parameter.
  • Encoded frame mode: panggil setVideoEncoderConfig(isExternal=true) dan dorong segera—pemanggilan startVideoCapture tidak diperlukan.
  • Raw frame mode dan encoded frame mode tidak dapat digunakan secara bersamaan: hanya satu antarmuka push yang dapat aktif dalam satu waktu.
  • Encoded frame mode saat ini hanya mendukung JPEG.
  • Setelah Anda mendorong frame, SDK mengelola siklus hidupnya secara internal. Anda tidak perlu menyimpan data tersebut setelah pemanggilan push selesai.