Tous les produits
Search
Centre de documentation

Alibaba Cloud Model Studio:Custom video input

Dernière mise à jour :Sep 07, 2026

Cette rubrique décrit les deux modes d'entrée vidéo personnalisée pris en charge par le SDK Client AOQ : le mode trame brute et le mode trame encodée. Elle détaille également la configuration et fournit des exemples de code pour chaque mode.

Présentation

Le module vidéo intégré du SDK Client AOQ répond aux besoins vidéo de base. Toutefois, dans certains scénarios, ce module de capture natif peut s'avérer insuffisant. La capture vidéo personnalisée est utile lorsque vous devez :

  • Contourner des conflits de périphériques de caméra ou des problèmes de compatibilité.
  • Alimenter le SDK avec des données vidéo provenant d'un système de capture personnalisé ou d'un fichier vidéo afin de les transmettre.
  • Publier via le SDK des trames générées par IA, des enregistrements d'écran ou du contenu issu d'une caméra virtuelle.

Le SDK Client AOQ prend en charge deux modes d'entrée vidéo personnalisée :

  • Mode trame brute : capturez des trames vidéo brutes dans des formats tels que BGRA, I420, NV12 ou NV21, puis injectez-les dans le SDK via pushExternalVideoCapturedFrame. Le SDK gère l'encodage et la transmission en interne.
  • Mode trame encodée : encodez vous-même les trames vidéo (actuellement JPEG uniquement), puis injectez les données encodées directement dans le SDK via pushExternalVideoEncodedFrame, en contournant ainsi l'encodeur interne du SDK.

Exemple de code

Bientôt disponible.

Prérequis

  • Une instance de moteur a été créée en appelant createEngine.
  • Une connexion au serveur est établie (le callback onConnectionStatusChange a signalé AoqConnectionStatusConnected).

Mise en œuvre

Choisissez l'un des deux modes selon votre cas d'utilisation. Ces deux modes ne peuvent pas être utilisés simultanément : une seule interface d'injection peut être active à la fois.

Mode 1 : Mode trame brute

Capturez des trames vidéo brutes dans des formats tels que BGRA, I420, NV12 ou NV21, puis injectez-les dans le SDK pour qu'il procède à l'encodage et à la transmission. Le SDK gère l'intégralité du pipeline d'encodage et d'envoi en interne.

1. Configurer les paramètres d'encodage vidéo

L'encodeur interne du SDK encode les trames brutes que vous injectez. Ajustez les paramètres d'encodage pour les adapter à votre cas d'utilisation.

AoqClientEngine.AoqVideoCodecConfig config = new AoqClientEngine.AoqVideoCodecConfig();
config.width            = 1280;
config.height           = 720;
config.fps              = 2;
config.bitrate          = 500000;   // Starting bitrate: 500 kbps
config.minBitrate       = 128000;   // Minimum bitrate: 128 kbps
config.keyframeInterval = 2;
// Leave isExternal at the default false — the SDK handles encoding internally

engine.setVideoEncoderConfig(config);
Paramètres :

Paramètre

Type

Valeur par défaut

Description

trackType

AoqTrackType

AoqTrackTypeVideo

Type de piste vidéo

codecType

AoqEncoderType

AoqEncoderTypeVideoH264

Type d'encodeur

width

int

720

Largeur d'encodage (pixels)

height

int

1280

Hauteur d'encodage (pixels)

fps

int

5

Fréquence d'images

bitrate

int

500000

Débit binaire initial (bps)

minBitrate

int

128000

Débit binaire minimal (bps)

keyframeInterval

int

2

Intervalle entre les images clés (secondes)

isExternal

boolean

false

Laisser à false pour le mode trame brute

mirrorMode

AoqMirrorMode

AoqMirrorModeDisabled

Mode miroir

orientationMode

AoqOrientationMode

AoqOrientationModeAuto

Mode d'orientation

2. Démarrer la capture vidéo en mode capture externe

Appelez startVideoCapture avec isExternal=true pour indiquer au SDK de ne pas ouvrir la caméra et d'attendre des trames provenant d'une source externe. Cette étape est obligatoire pour le mode trame brute : si vous omettez cet appel, le SDK ne traitera aucune des trames injectées.

AoqClientEngine.AoqVideoCaptureConfig config = new AoqClientEngine.AoqVideoCaptureConfig();
config.isExternal = true;  // Do not open the camera; external source will push frames
// When isExternal=true, width/height/fps have no effect — the actual resolution
// and frame rate are determined by the pushed data
int ret = engine.startVideoCapture(config);
Paramètres :

Paramètre

Type

Valeur par défaut

Description

width

int

1280

Largeur de capture (ignorée lorsque isExternal=true)

height

int

720

Hauteur de capture (ignorée lorsque isExternal=true)

fps

int

15

Fréquence d'images de capture (ignorée lorsque isExternal=true)

isExternal

boolean

false

true : ne pas ouvrir la caméra ; une source externe fournit les trames

cameraDirection

AoqCameraDirection

AoqCameraDirectionFront

Direction de la caméra (ignorée lorsque isExternal=true)

3. Injecter des trames vidéo brutes

Appelez pushExternalVideoCapturedFrame pour alimenter le SDK avec les trames brutes capturées. Le SDK se charge de l'encodage et de la transmission.

Formats pris en charge : BGRA, I420, NV12, NV21, RGBA. Sur les plateformes Apple, le zéro copie via CVPixelBuffer est également pris en charge.

3,1 Format BGRA

BGRA est un format compact utilisant 4 octets par pixel (Blue, Green, Red, Alpha). Taille de la trame = largeur × hauteur × 4 octets.

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

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

frame.timeStamp = System.currentTimeMillis();

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

3,2 Format I420

I420 est un format planaire composé de trois plans distincts (Y, U, V). La taille du plan Y correspond à largeur × hauteur ; les plans U et V mesurent chacun (largeur/2) × (hauteur/2).

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

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

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

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

frame.strideY   = 1280;    // Y plane row stride (bytes)
frame.strideU   = 640;     // U plane row stride (bytes)
frame.strideV   = 640;     // V plane row stride (bytes)
frame.timeStamp = System.currentTimeMillis();

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

3,3 Formats NV12 / NV21

NV12 et NV21 sont des formats semi-planaires constitués d'un plan Y et d'un plan UV entrelacé. NV12 entrelace les composantes dans l'ordre UV, tandis que NV21 utilise l'ordre VU. La taille de la trame équivaut à largeur × hauteur × 3 / 2 octets, stockés dans le champ data.

// Build an NV12 video frame (NV21 is identical — just change the format field)
AoqClientEngine.AoqVideoFrame frame = new AoqClientEngine.AoqVideoFrame();
frame.format    = AoqClientEngine.AoqVideoPixelFormat.AoqVideoPixelFormatNV12;
frame.width     = 1280;
frame.height    = 720;

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

frame.timeStamp = System.currentTimeMillis();

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

3,4 Format CVPixelBuffer (plateformes Apple)

Sur iOS et macOS, vous pouvez transmettre directement un CVPixelBufferRef pour bénéficier d'un transfert zéro copie, évitant ainsi la surcharge de performance liée aux copies mémoire.

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

// The SDK holds pixelBuffer asynchronously — retain it with +1 ref count.
// The SDK releases it when done.
let _ = Unmanaged.passRetained(pixelBuffer)

engine.pushExternalVideoCapturedFrame(.video, frame: frame)

4. Arrêter la capture de trames brutes

Lorsque vous n'avez plus besoin d'injecter des trames, arrêtez d'abord le minuteur d'injection, puis appelez stopVideoCapture pour fermer la capture vidéo.

// 1. Stop the frame push timer
stopExternalFramePush();
// 2. Stop video capture
engine.stopVideoCapture();

Mode 2 : Mode trame encodée

Encodez vous-même les trames vidéo (actuellement JPEG uniquement) et injectez les données encodées directement dans le SDK, en contournant l'encodeur interne. Ce mode ne nécessite pas l'appel à startVideoCapture ni à aucune autre API liée à la capture.

1. Configurer les paramètres d'encodage vidéo et activer l'encodage externe

Appelez setVideoEncoderConfig avec isExternal=true pour indiquer au SDK d'ignorer l'encodeur interne et d'attendre des données pré-encodées provenant d'une source externe.

AoqClientEngine.AoqVideoCodecConfig config = new AoqClientEngine.AoqVideoCodecConfig();
config.width      = 1280;
config.height     = 720;
config.fps        = 2;
config.isExternal = true;  // Skip internal encoding; external source provides encoded frames

engine.setVideoEncoderConfig(config);

Une fois la configuration terminée, vous pouvez injecter immédiatement des trames encodées sans avoir à appeler startVideoCapture.

2. Injecter des trames vidéo encodées

Appelez pushExternalVideoEncodedFrame pour transmettre des données vidéo pré-encodées directement au SDK. Seul l'encodage JPEG est actuellement pris en charge.

// Generate JPEG data from a Bitmap
android.graphics.Bitmap bmp = android.graphics.Bitmap.createBitmap(
    width, height, android.graphics.Bitmap.Config.ARGB_8888);
// ... fill in Bitmap content ...

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

// Build the encoded frame and push it
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);
Paramètres de AoqVideoEncodedFrame :

Paramètre

Type

Valeur par défaut

Description

codec

AoqVideoCodecType

AoqVideoCodecTypeJPEG

Format d'encodage ; seul JPEG est actuellement pris en charge

data

byte[]

null

Données de la trame encodée

width

int

0

Largeur de la trame (pixels)

height

int

0

Hauteur de la trame (pixels)

timeStamp

long

0

Horodatage (millisecondes) ; si la valeur est 0, le SDK utilise l'horloge locale

3. Arrêter l'injection de trames encodées

Le mode trame encodée n'utilisant aucun périphérique de capture, l'arrêt consiste simplement à suspendre votre minuteur d'injection.

stopExternalFramePush();

Référence

AoqVideoFrame (mode trame brute)

Champ

Type

Description

format

AoqVideoPixelFormat

Format de pixel

width

int

Largeur de la trame (pixels)

height

int

Hauteur de la trame (pixels)

data

byte[]

Données au format compact (NV12/NV21/BGRA/RGBA)

dataY

byte[]

Données du plan Y pour I420

dataU

byte[]

Données du plan U pour I420

dataV

byte[]

Données du plan V pour I420

strideY

int

Pas de ligne du plan Y pour I420 (octets)

strideU

int

Pas de ligne du plan U pour I420 (octets)

strideV

int

Pas de ligne du plan V pour I420 (octets)

textureId

int

ID de texture Android (TextureOES/Texture2D)

transformMatrix

float[]

Matrice de transformation de texture (4×4, ordre ligne)

eglContext

EGLContext

Contexte EGL partagé Android (pour le mode texture)

pixelBuffer

CVPixelBufferRef

CVPixelBuffer Apple zéro copie (iOS/macOS uniquement)

timeStamp

long

Horodatage (millisecondes) ; si la valeur est 0, le SDK utilise l'horloge locale

Valeurs de l'énumération AoqVideoPixelFormat

Valeur d'énumération

Valeur numérique

Description

AoqVideoPixelFormatUnknown

0

Format inconnu

AoqVideoPixelFormatI420

1

Format planaire I420

AoqVideoPixelFormatNV12

2

Format semi-planaire NV12 (UV entrelacé)

AoqVideoPixelFormatNV21

3

Format semi-planaire NV21 (VU entrelacé)

AoqVideoPixelFormatBGRA

4

Format compact BGRA

AoqVideoPixelFormatRGBA

5

Format compact RGBA

AoqVideoPixelFormatCVPixelBuffer

6

CVPixelBuffer Apple (iOS/macOS uniquement)

AoqVideoPixelFormatTextureOES

7

Texture externe OES Android

AoqVideoPixelFormatTexture2D

8

Texture 2D Android

AoqVideoEncodedFrame (mode trame encodée)

Champ

Type

Description

codec

AoqVideoCodecType

Format d'encodage

data

byte[]

Données de la trame encodée

width

int

Largeur de la trame (pixels)

height

int

Hauteur de la trame (pixels)

timeStamp

long

Horodatage (millisecondes) ; si la valeur est 0, le SDK utilise l'horloge locale

Valeurs de l'énumération AoqVideoCodecType

Valeur d'énumération

Valeur numérique

Description

AoqVideoCodecTypeJPEG

0

Format d'encodage JPEG

Remarques importantes

  • Mode trame brute : vous devez appeler startVideoCapture(isExternal=true) avant d'injecter des trames. En l'absence de cet appel, le SDK renvoie une erreur de paramètre.
  • Mode trame encodée : appelez setVideoEncoderConfig(isExternal=true) et injectez les données immédiatement. L'appel à startVideoCapture n'est pas requis.
  • Les modes trame brute et trame encodée sont mutuellement exclusifs : une seule interface d'injection peut être active à la fois.
  • Le mode trame encodée ne prend actuellement en charge que le format JPEG.
  • Après l'injection d'une trame, le SDK gère son cycle de vie en interne. Il est inutile de conserver les données une fois l'appel d'injection terminé.