QwenCloudBRASIL
Tradução de apoio para consulta. Código e identificadores técnicos preservados. Consultar referência original ↗

Entrada de vídeo personalizada

Use uma fonte de vídeo externa em vez da câmera do dispositivo

Descreve os dois modos de entrada de vídeo personalizados compatíveis com o SDK do cliente AOQ (modo de quadro bruto e modo de quadro codificado), incluindo configuração e exemplos de código para cada um.

Visão geral

O módulo de vídeo integrado do SDK do cliente AOQ cobre necessidades básicas de vídeo, mas em alguns cenários o módulo de captura integrado pode não ser suficiente. A captura de vídeo personalizada é útil quando você precisa:

O SDK do cliente AOQ oferece suporte a dois modos de entrada de vídeo personalizados:

Código de exemplo

Em breve.

Pré-requisitos

Implementação

Escolha um dos dois modos com base no seu caso de uso. Os dois modos não podem ser usados simultaneamente: apenas uma interface push pode estar ativa por vez.

Modo 1: modo de quadro bruto

Capture quadros de vídeo brutos em formatos como BGRA, I420, NV12 ou NV21 e envie-os para o SDK para codificação e transmissão. O SDK lida internamente com a codificação completa e o pipeline de envio.

1. Configure os parâmetros de codificação de vídeo

O codificador interno do SDK codifica os quadros brutos que você envia. Ajuste os parâmetros de codificação de acordo com seu caso de uso.

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

Parâmetros:

Parâmetro Tipo Padrão Descrição
trackType AoqTrackType AoqTrackTypeVídeo Tipo de trilha de vídeo
tipo de codec AoqEncoderType AoqEncoderTypeVideoH264 Tipo de codificador
largura interno 720 Largura de codificação (pixels)
altura interno 1280 Altura de codificação (pixels)
FPS interno 5 Taxa de quadros
taxa de bits interno 500000 Taxa de bits inicial (bps)
minTaxa de bits interno 128.000 Taxa de bits mínima (bps)
keyframeInterval interno 2 Intervalo de quadro-chave (segundos)
éExterno booleano falso Mantenha falso para o modo de quadro bruto
modo espelho AoqMirrorMode AoqMirrorModeDesativado Modo espelho
modo de orientação AoqOrientationMode AoqOrientationModeAuto Modo de orientação

2. Inicie a captura de vídeo no modo de captura externa

Ligar startVideoCapture com isExternal=true para informar ao SDK para não abrir a câmera e esperar quadros de uma fonte externa. Isso é necessário para o modo de quadro bruto. Se você ignorar esta chamada, o SDK não consumirá nenhum quadro enviado por push.

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

Parâmetros:

Parâmetro Tipo Padrão Descrição
largura interno 1280 Largura de captura (ignorada quando isExternal=true)
altura interno 720 Altura de captura (ignorada quando isExternal=true)
FPS interno 15 Taxa de quadros de captura (ignorada quando isExternal=true)
éExterno booleano falso verdadeiro: não abra a câmera; fonte externa fornece frames
direção da câmera AoqCameraDireção AoqCameraDirectionFrente Direção da câmera (ignorada quando isExternal=true)

3. Envie quadros de vídeo brutos

Ligar pushExternalVideoCapturedFrame para alimentar quadros brutos capturados no SDK. O SDK lida com codificação e transmissão.

Formatos suportados: BGRA, I420, NV12, NV21, RGBA. Nas plataformas Apple, a cópia zero do CVPixelBuffer também é suportada.

Formato 3.1 BGRA

BGRA é um formato compactado com 4 bytes por pixel (azul, verde, vermelho, alfa). Tamanho do quadro = largura x altura x 4 bytes.

// 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 Formato I420

I420 é um formato planar com três planos separados (Y, U, V). Tamanho do plano Y = largura x altura; Os planos U e V são cada um (largura/2) x (altura/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 Formato NV12 / NV21

NV12 e NV21 são formatos semiplanares que consistem em um plano Y e um plano UV intercalado. O NV12 intercala o UV nessa ordem; NV21 intercala VU. Tamanho do quadro = largura x altura x 3/2 bytes, compactado no data campo.

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

Formato 3.4 CVPixelBuffer (plataformas Apple)

No iOS e no macOS, você pode passar um CVPixelBufferRef diretamente para transferência de cópia zero, evitando a sobrecarga de desempenho das cópias de memória.

// 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. Pare a captura de quadros brutos

Quando você não precisar mais enviar frames, pare primeiro o temporizador de envio e depois ligue stopVideoCapture para encerrar a captura de vídeo.

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

Modo 2: modo de quadro codificado

Codifique você mesmo os quadros de vídeo (atualmente apenas JPEG) e envie os dados codificados diretamente para o SDK, ignorando o codificador interno. Este modo não requer chamada startVideoCapture ou quaisquer outras APIs relacionadas à captura.

1. Configure os parâmetros de codificação de vídeo e habilite a codificação externa

Ligar setVideoEncoderConfig com isExternal=true para informar ao SDK para ignorar o codificador interno e esperar dados pré-codificados de fora.

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

Uma vez configurado, você pode enviar quadros codificados imediatamente - não há necessidade de chamar startVideoCapture.

2. Quadros de vídeo codificados por push

Ligar pushExternalVideoEncodedFrame para passar dados de vídeo pré-codificados diretamente para o SDK. Atualmente, apenas a codificação JPEG é suportada.

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

Parâmetros AoqVideoEncodedFrame:

Parâmetro Tipo Padrão Descrição
codec AoqVideoCodecType AoqVideoCodecTypeJPEG Formato de codificação; atualmente apenas JPEG é suportado
dados byte[] nulo Dados de quadro codificados
largura interno 0 Largura do quadro (pixels)
altura interno 0 Altura do quadro (pixels)
carimbo de data / hora longo 0 Carimbo de data/hora (milissegundos); quando 0, o SDK usa o relógio local

3. Pare de enviar quadros codificados

O modo de quadro codificado não envolve nenhum dispositivo de captura, portanto, parar é simplesmente uma questão de interromper o cronômetro de envio.

stopExternalFramePush();

Referência

AoqVideoFrame (modo de quadro bruto)

Campo Tipo Descrição
formato AoqVideoPixelFormat Formato de pixel
largura interno Largura do quadro (pixels)
altura interno Altura do quadro (pixels)
dados byte[] Dados em formato compactado (NV12/NV21/BGRA/RGBA)
dadosY byte[] Dados do avião I420 Y
dadosU byte[] Dados do avião I420 U
dadosV byte[] Dados do plano I420 V
passoY interno Passo da linha do plano Y I420 (bytes)
passoU interno Passo da linha do plano I420 U (bytes)
passoV interno Passo da linha plana I420 V (bytes)
ID da textura interno ID de textura do Android (TextureOES/Texture2D)
transformarMatriz flutuar[] Matriz de transformação de textura (4x4, linha principal)
eglContexto Contexto EGL Contexto EGL compartilhado do Android (para modo de textura)
pixelBuffer CVPixelBufferRef CVPixelBuffer de cópia zero da Apple (somente iOS/macOS)
carimbo de data / hora longo Carimbo de data/hora (milissegundos); quando 0, o SDK usa o relógio local

Valores de enumeração AoqVideoPixelFormat

Valor enum Valor numérico Descrição
AoqVideoPixelFormatUnknown 0 Formato desconhecido
AoqVideoPixelFormatI420 1 Formato plano I420
AoqVideoPixelFormatNV12 2 Formato semiplanar NV12 (intercalado UV)
AoqVideoPixelFormatNV21 3 Formato semiplanar NV21 (intercalado VU)
AoqVideoPixelFormatBGRA 4 Formato compactado BGRA
AoqVideoPixelFormatRGBA 5 Formato compactado RGBA
AoqVideoPixelFormatCVPixelBuffer 6 Apple CVPixelBuffer (somente iOS/macOS)
AoqVideoPixelFormatTextureOES 7 Textura externa Android OES
AoqVideoPixelFormatTexture2D 8 Textura 2D Android

AoqVideoEncodedFrame (modo de quadro codificado)

Campo Tipo Descrição
codec AoqVideoCodecType Formato de codificação
dados byte[] Dados de quadro codificados
largura interno Largura do quadro (pixels)
altura interno Altura do quadro (pixels)
carimbo de data / hora longo Carimbo de data/hora (milissegundos); quando 0, o SDK usa o relógio local

Valores de enumeração AoqVideoCodecType

Valor enum Valor numérico Descrição
AoqVideoCodecTypeJPEG 0 Formato de codificação JPEG

Notas importantes