すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Model Studio:カスタムビデオ入力

最終更新日:Sep 02, 2026

AOQ Client SDK でサポートされている 2 つのカスタムビデオ入力モード (ローフレームモードとエンコード済みフレームモード) について、それぞれの設定とコード例を説明します。

概要

AOQ クライアント SDK の内蔵ビデオモジュールは、基本的なビデオニーズに対応しますが、一部のシナリオでは内蔵のキャプチャモジュールでは不十分な場合があります。カスタムビデオキャプチャは、次のような場合に役立ちます:

  • カメラデバイスの競合や互換性の問題を回避する場合。
  • カスタムキャプチャシステムやビデオファイルのビデオデータを SDK に入力して伝送する場合。
  • AI が生成したフレーム、スクリーン録画、または仮想カメラのコンテンツを SDK 経由で公開する場合。

AOQ クライアント SDK は、2 つのカスタムビデオ入力モードをサポートしています:

  • RAW フレームモード : BGRA、I420、NV12、または NV21 などの形式で RAW ビデオフレームをキャプチャし、pushExternalVideoCapturedFrame を使って SDK にプッシュします。 SDK は内部でエンコーディングと伝送を処理します。
  • エンコード済みフレームモード : 自身でビデオフレーム (現在は JPEG のみ) をエンコードし、エンコード済みのデータを pushExternalVideoEncodedFrame を使って SDK に直接プッシュすることで、SDK の内部エンコーダーをバイパスします。

サンプルコード

近日公開。

前提条件

  • createEngine を呼び出してエンジンインスタンスが作成されていること。
  • サーバーへの接続が確立されていること ( onConnectionStatusChange コールバックが AoqConnectionStatusConnected を報告済み )。

実装

ユースケースに基づいて、2 つのモードのいずれかを選択してください。2 つのモードを同時に使用することはできません。一度にアクティブにできるのは、1 つのプッシュインターフェイスのみです。

モード 1:ローフレームモード

BGRA、I420、NV12、NV21 などの形式でロービデオフレームをキャプチャし、エンコーディングと伝送のために SDK にプッシュします。SDK は、エンコードから伝送までのパイプライン全体を内部で処理します。

1. ビデオエンコーディングパラメーターの設定

SDK の内部エンコーダーが、プッシュされたローフレームをエンコードします。ユースケースに合わせてエンコーディングパラメーターを調整します。

AoqClientEngine.AoqVideoCodecConfig config = new AoqClientEngine.AoqVideoCodecConfig();
config.width            = 1280;
config.height           = 720;
config.fps              = 2;
config.bitrate          = 500000;   // 開始ビットレート:500 kbps
config.minBitrate       = 128000;   // 最小ビットレート:128 kbps
config.keyframeInterval = 2;
// isExternal はデフォルトの false のままにします。SDK が内部でエンコーディングを処理します。

engine.setVideoEncoderConfig(config);
パラメーター:

パラメーター

タイプ

デフォルト

説明

trackType

AoqTrackType

AoqTrackTypeVideo

ビデオトラックタイプ

codecType

AoqEncoderType

AoqEncoderTypeVideoH264

エンコーダータイプ

width

int

720

エンコード幅 (ピクセル)

height

int

1280

エンコード高さ (ピクセル)

fps

int

2

フレームレート

bitrate

int

500000

開始ビットレート (bps)

minBitrate

int

128000

最小ビットレート (bps)

keyframeInterval

int

2

キーフレーム間隔 (秒)

isExternal

boolean

false

ローフレームモードでは false のままにします。

mirrorMode

AoqMirrorMode

AoqMirrorModeDisabled

ミラーモード

orientationMode

AoqOrientationMode

AoqOrientationModeAuto

オリエンテーションモード

2. 外部キャプチャモードでのビデオキャプチャの開始

isExternal=true を指定して startVideoCapture を呼び出すと、SDK はカメラを開かず、外部ソースからのフレームを受け取るようになります。これはローフレームモードで必須です。この呼び出しを省略すると、SDK はプッシュされたフレームを処理しません。

AoqClientEngine.AoqVideoCaptureConfig config = new AoqClientEngine.AoqVideoCaptureConfig();
config.isExternal = true;  // カメラを開きません。外部ソースがフレームをプッシュします。
// isExternal=true の場合、width/height/fps は無効です。実際の解像度とフレームレートは、
// プッシュされるデータによって決まります。
int ret = engine.startVideoCapture(config);
パラメーター:

パラメーター

タイプ

デフォルト

説明

width

int

1280

キャプチャ幅 (isExternal=true の場合は無視されます)

height

int

720

キャプチャ高さ (isExternal=true の場合は無視されます)

fps

int

15

キャプチャフレームレート (isExternal=true の場合は無視されます)

isExternal

boolean

false

true:カメラを開きません。外部ソースがフレームを提供します。

cameraDirection

AoqCameraDirection

AoqCameraDirectionFront

カメラの向き (isExternal=true の場合は無視されます)

3. ロービデオフレームのプッシュ

pushExternalVideoCapturedFrame を呼び出して、キャプチャしたローフレームを SDK にプッシュします。SDK がエンコーディングと伝送を処理します。

サポートされている形式:BGRA、I420、NV12、NV21、RGBA。Apple プラットフォームでは、CVPixelBuffer のゼロコピーもサポートされています。

3.1 BGRA 形式

BGRA は、1 ピクセルあたり 4 バイト (Blue、Green、Red、Alpha) のパックフォーマットです。フレームサイズ = width × height × 4 バイトです。

// BGRA ビデオフレームを作成します
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 I420 形式

I420 は、3 つの独立したプレーン (Y、U、V) を持つプレーナーフォーマットです。Y プレーンサイズ = width × height、U と V の各プレーンは (width/2) × (height/2) です。

// I420 ビデオフレームを作成します
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 プレーンの行ストライド (バイト)
frame.strideU   = 640;     // U プレーンの行ストライド (バイト)
frame.strideV   = 640;     // V プレーンの行ストライド (バイト)
frame.timeStamp = System.currentTimeMillis();

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

3.3 NV12 / NV21 形式

NV12 と NV21 は、Y プレーンとインターリーブされた UV プレーンで構成されるセミプレーナーフォーマットです。NV12 は UV の順でインターリーブし、NV21 は VU の順でインターリーブします。フレームサイズ = width × height × 3 / 2 バイトで、data フィールドにパックされます。

// NV12 ビデオフレームを作成します (NV21 も同様です。format フィールドを変更するだけです)
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 CVPixelBuffer 形式 (Apple プラットフォーム)

iOS と macOS では、CVPixelBufferRef をゼロコピーで直接渡すことができます。これにより、メモリコピーによるパフォーマンスオーバーヘッドを回避できます。

// 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 は pixelBuffer を非同期に保持します。参照カウントを +1 して保持してください。
// SDK は処理完了後に解放します。
let _ = Unmanaged.passRetained(pixelBuffer)

engine.pushExternalVideoCapturedFrame(.video, frame: frame)

4. ローフレームキャプチャの停止

フレームのプッシュが不要になったら、最初にプッシュタイマーを停止し、その後 stopVideoCapture を呼び出してビデオキャプチャを停止します。

// 1. フレームプッシュタイマーを停止します
stopExternalFramePush();
// 2. ビデオキャプチャを停止します
engine.stopVideoCapture();

モード 2:エンコードフレームモード

ビデオフレームを自身でエンコード (現時点では JPEG のみ) し、内部エンコーダーをバイパスして、エンコード済みデータを SDK に直接プッシュします。このモードでは、startVideoCapture やその他のキャプチャ関連 API を呼び出す必要は ありません

1. ビデオエンコーディングパラメーターの設定と外部エンコーディングの有効化

isExternal=true を指定して setVideoEncoderConfig を呼び出すと、SDK は内部エンコーダーをスキップし、外部からのエンコード済みデータを受け取るようになります。

AoqClientEngine.AoqVideoCodecConfig config = new AoqClientEngine.AoqVideoCodecConfig();
config.width      = 1280;
config.height     = 720;
config.fps        = 2;
config.isExternal = true;  // 内部エンコーディングをスキップします。外部ソースがエンコード済みフレームを提供します。

engine.setVideoEncoderConfig(config);

設定後は、すぐにエンコード済みフレームをプッシュできます。startVideoCapture を呼び出す必要はありません。

2. エンコード済みビデオフレームのプッシュ

pushExternalVideoEncodedFrame を呼び出して、エンコード済みビデオデータを SDK に直接渡します。現時点でサポートされているエンコーディングは JPEG のみです。

// Bitmap から JPEG データを生成します
android.graphics.Bitmap bmp = android.graphics.Bitmap.createBitmap(
    width, height, android.graphics.Bitmap.Config.ARGB_8888);
// ... ここで Bitmap のコンテンツを書き込みます ...

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

// エンコード済みフレームを作成してプッシュします
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);
AoqVideoEncodedFrame パラメーター:

パラメーター

タイプ

デフォルト

説明

codec

AoqVideoCodecType

AoqVideoCodecTypeJPEG

エンコード形式。現時点では JPEG のみがサポートされています。

data

byte[]

null

エンコード済みフレームデータ

width

int

0

フレーム幅 (ピクセル)

height

int

0

フレーム高さ (ピクセル)

timeStamp

long

0

タイムスタンプ (ミリ秒)。0 の場合、SDK はローカルクロックを使用します。

3. エンコード済みフレームのプッシュ停止

エンコードフレームモードではキャプチャデバイスを使用しないため、停止するにはプッシュタイマーを停止するだけです。

stopExternalFramePush();

関連ドキュメント

AoqVideoFrame (ローフレームモード)

フィールド

タイプ

説明

format

AoqVideoPixelFormat

ピクセルフォーマット

width

int

フレーム幅 (ピクセル)

height

int

フレーム高さ (ピクセル)

data

byte[]

パックフォーマットデータ (NV12/NV21/BGRA/RGBA)

dataY

byte[]

I420 の Y プレーンデータ

dataU

byte[]

I420 の U プレーンデータ

dataV

byte[]

I420 の V プレーンデータ

strideY

int

I420 の Y プレーンの行ストライド (バイト)

strideU

int

I420 の U プレーンの行ストライド (バイト)

strideV

int

I420 の V プレーンの行ストライド (バイト)

textureId

int

Android テクスチャ ID (TextureOES/Texture2D)

transformMatrix

float[]

テクスチャ変換行列 (4×4、行優先)

eglContext

EGLContext

Android 共有 EGL コンテキスト (テクスチャモード用)

pixelBuffer

CVPixelBufferRef

Apple ゼロコピー CVPixelBuffer (iOS/macOS のみ)

timeStamp

long

タイムスタンプ (ミリ秒)。0 の場合、SDK はローカルクロックを使用します。

AoqVideoPixelFormat enum 値

列挙値

数値

説明

AoqVideoPixelFormatUnknown

0

不明な形式

AoqVideoPixelFormatI420

1

I420 プレーナーフォーマット

AoqVideoPixelFormatNV12

2

NV12 セミプレーナーフォーマット (UV インターリーブ)

AoqVideoPixelFormatNV21

3

NV21 セミプレーナーフォーマット (VU インターリーブ)

AoqVideoPixelFormatBGRA

4

BGRA パックフォーマット

AoqVideoPixelFormatRGBA

5

RGBA パックフォーマット

AoqVideoPixelFormatCVPixelBuffer

6

Apple CVPixelBuffer (iOS/macOS のみ)

AoqVideoPixelFormatTextureOES

7

Android OES 外部テクスチャ

AoqVideoPixelFormatTexture2D

8

Android 2D テクスチャ

AoqVideoEncodedFrame (エンコードフレームモード)

フィールド

タイプ

説明

codec

AoqVideoCodecType

エンコード形式

data

byte[]

エンコード済みフレームデータ

width

int

フレーム幅 (ピクセル)

height

int

フレーム高さ (ピクセル)

timeStamp

long

タイムスタンプ (ミリ秒)。0 の場合、SDK はローカルクロックを使用します。

AoqVideoCodecType enum 値

列挙値

数値

説明

AoqVideoCodecTypeJPEG

0

JPEG エンコード形式

重要な注意事項

  • ローフレームモード:フレームをプッシュする前に、startVideoCapture(isExternal=true) を呼び出す必要があります。この呼び出しを省略すると、SDK はパラメーターエラーを返します。
  • エンコードフレームモード:setVideoEncoderConfig(isExternal=true) を呼び出してすぐにプッシュします。startVideoCapture の呼び出しは 不要 です。
  • ローフレームモードとエンコードフレームモードは同時に使用できません。同時に有効にできるプッシュインターフェイスは 1 つだけです。
  • エンコードフレームモードは、現時点では JPEG のみをサポートしています。
  • フレームをプッシュすると、SDK がライフサイクルを内部で管理します。プッシュ呼び出しの完了後は、データを保持する必要はありません。