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

ApsaraVideo Live:生ビデオデータ処理

最終更新日:Oct 22, 2025

リアルタイムコミュニケーション (RTC) セッション中に、SDK からの生ビデオデータを処理したり、処理パイプラインのさまざまな段階でデータにアクセスしたりできます。このトピックでは、ビデオオブザーバーを使用してこのデータにアクセスし、処理する方法について説明します。

ユースケース

カスタムビデオデータ処理の一般的なユースケースは次のとおりです。

  1. カスタムレタッチ: ローカルビデオストリームを取得し、サードパーティのレタッチ SDK を使用して処理してから、チャンネル内の他のユーザーに送信します。

  2. カスタムビデオ編集: 特殊効果、ウォーターマーク、トリミング、クリッピングの追加など、処理パイプラインのさまざまな段階でビデオストリームを編集します。変更されたストリームは、ブロードキャストまたは保存できます。

  3. ストリームのプレビューまたはモニタリング: ローカルまたはクラウドベースのモニタリングとプレビューのために、処理パイプラインのさまざまな段階でビデオストリームを取得します。ビデオストリームのコンテンツ、品質、ステータスをリアルタイムで監視して、適切な伝送と再生を確保できます。

始める前に

次の準備が完了していることを確認してください。

仕組み

ビデオキャプチャ:

デコードとレンダリング:

ARTC SDK は、ビデオ処理パイプラインのさまざまな段階でオブザベーションポイントを提供します。

オブザベーションポイントは、次のコールバックに対応しています。

  • オブザベーションポイント 1: キャプチャ直後に onCaptureVideoSample (iOS) または onLocalVideoSample (Android) を介して、スケーリングされていない元のビデオフレームデータを取得します。

  • オブザベーションポイント 2: onPreEncodeVideoSample を介してエンコード前のデータを取得します。

  • オブザベーションポイント 3: onRemoteVideoSample を介してデコードされたデータを取得します。

  • オブザベーションポイント 4: onTextureCreate を介して OpenGL コンテキスト (glcontext) を取得し、レタッチモジュールにバインドします。

  • オブザベーションポイント 5: onTextureUpdate を介して更新されたテクスチャデータを受信し、効果を適用します。

  • オブザベーションポイント 6: onTextureDestroy を介して glcontext を解放する通知を受信します。

説明
  • 観測ポイント 1、2、および 3 の場合、true を返すと、データを変更したことを示します。false を返すと、元のデータは変更されません。

  • 観測ポイント 5 の場合、メソッドは有効な textureId を返す必要があります。新しい textureId を返すと、SDK は変更されたテクスチャをエンコーディングと処理に使用するように指示します。カスタム処理を実行しない場合は、元の textureId を返します。

実装

Android

ビデオフレームコールバック

1. コールバックの登録

生ビデオデータを受信するには、AliRtcEngine.AliRtcVideoObserver インターフェイスを実装し、registerVideoSampleObserver() メソッドを呼び出してインスタンスを登録します。

public abstract void registerVideoSampleObserver(AliRtcVideoObserver observer);

2. オブザベーションポイントの指定

SDK は、このメソッドから返されるビットマスクに基づいて、トリガーするコールバックを決定します。

 public enum AliRtcVideoObserPosition{
        /*! ローカルでキャプチャされたビデオデータ、onLocalVideoSample コールバックに対応 */
        AliRtcPositionPostCapture(1),
        /*! デコードされたリモートビデオデータ、onRemoteVideoSample コールバックに対応 */
        AliRtcPositionPreRender(2),
        /*! エンコード前のビデオデータ、onPreEncodeVideoSample コールバックに対応 */
        AliRtcPositionPreEncoder(4);
    }

public int onGetObservedFramePosition(){
    return AliRtcVideoObserPosition.AliRtcPositionPostCapture.getValue() | AliRtcVideoObserPosition.AliRtcPositionPreRender.getValue();
}

3. 出力フォーマットの指定

/**
 * @brief ビデオデータ形式
 */
public enum AliRtcVideoFormat{
        AliRtcVideoFormatUNKNOW(-1),
        AliRtcVideoFormatBGRA(0),
        AliRtcVideoFormatI420(1),
        AliRtcVideoFormatNV21(2),
        AliRtcVideoFormatNV12 (3),
        AliRtcVideoFormatRGBA(4),
        AliRtcVideoFormatI422 (5),
        AliRtcVideoFormatARGB(6),
        AliRtcVideoFormatABGR (7),
        AliRtcVideoFormatRGB24(8),
        AliRtcVideoFormatBGR24(9),
        AliRtcVideoFormatRGB565(10),
        AliRtcVideoFormatTextureOES(11),
        AliRtcVideoFormatTexture2D(12),
        AliRtcVideoFormatH264(13),
        AliRtcVideoFormatH265(14),
        AliRtcVideoFormatFile(15);
};

/*
* SDK は AliRtcEngine::registerVideoSampleObserver を呼び出した後にこのメソッドを呼び出します。
*/

/**
* @brief ビデオデータの出力フォーマット
* @return 目的のビデオ出力フォーマット。{@link AliRtcVideoFormat} をご参照ください。
*/
public AliRtcVideoFormat onGetVideoFormatPreference(){
    return AliRtcVideoFormat.AliRtcVideoFormatI420;
}

4. メモリ配置の指定

public enum AliRtcVideoObserAlignment{
        /*! 元のビデオ幅を維持 (デフォルト) */
        AliRtcAlignmentDefault(0),
        /*! ストライドを 2 バイトの倍数に配置 */
        AliRtcAlignmentEven(1),
        /*! ストライドを 4 バイトの倍数に配置 */
        AliRtcAlignment4(2),
        /*! ストライドを 8 バイトの倍数に配置 */
        AliRtcAlignment8(3),
        /*! ストライドを 16 バイトの倍数に配置 */
        AliRtcAlignment16(4);
};

/*
* SDK は AliRtcEngine::registerVideoSampleObserver を呼び出した後にこのメソッドを呼び出します。
*/

public int onGetVideoAlignment(){
  return AliRtcVideoObserAlignment.AliRtcAlignmentDefault.getValue();
}

5. ミラー効果を適用するかどうかの指定

public boolean onGetObserverDataMirrorApplied(){
  return false;
}

6. コールバックの実装

/*
* 変更を SDK の処理パイプラインに書き戻すには true を返します。
* これは AliRtcVideoSample.data を変更する場合に必要です。
*/

@Override
public boolean onLocalVideoSample(AliRtcEngine.AliRtcVideoSourceType sourceType, AliRtcEngine.AliRtcVideoSample videoSample) {
  boolean ret = false;
  /*
  * ローカルでキャプチャされたデータを処理します。
  */
  return ret;
}

@Override
public boolean onRemoteVideoSample(String userId, AliRtcEngine.AliRtcVideoSourceType sourceType, AliRtcEngine.AliRtcVideoSample videoSample) {
  /*
  * リモートユーザーからデコードされたデータを処理します。
  */
  return false;
}

@Override
public boolean onPreEncodeVideoSample(AliRtcEngine.AliRtcVideoSourceType aliVideoSourceType, AliRtcEngine.AliRtcVideoSample videoSample) {
  boolean ret = false;
  /*
  * エンコード前のデータを処理します。
  */
  return false ;
}

7. コールバックの登録解除

ビデオフレームを監視する必要がなくなったら、オブザーバーの登録を解除して不要な処理を回避します。

unregisterVideoSampleObserver

テクスチャ処理

テクスチャ関連のすべてのコールバックは、同じ専用の OpenGL スレッドで呼び出されます。これらを使用するには、AliRtcTextureObserver インターフェイスを実装します。

前提条件

エンジンを初期化するときに次のオプションを設定して、テクスチャキャプチャとテクスチャエンコーディングを有効にします。

String extras = "{\"user_specified_camera_texture_capture\":\"TRUE\",\"user_specified_texture_encode\":\"TRUE\" }";
_engine = AliRtcEngine.getInstance(getApplicationContext(), extras);

1. テクスチャコールバックの登録

public abstract void registerLocalVideoTextureObserver(AliRtcTextureObserver observer);

2. コールバックの実装

OpenGL コンテキスト作成後のコールバック
@Override
public void onTextureCreate(long context) {
      context_ = context ;
      Log.d(TAG, "texture context: "+context_+" create!") ;
}
OpenGL テクスチャ更新コールバック
@Override
public int onTextureUpdate(int textureId, int width, int height, AliRtcEngine.AliRtcVideoSample videoSample) {
    /*
    *  textureid を処理します。
    */
     ++log_ref ;
     return textureId;
}       
OpenGL コンテキスト破棄コールバック
@Override
public void onTextureDestroy() {
     Log.d(TAG, "texture context: "+context_+" destory!") ;
}

3. テクスチャコールバックの登録解除

public abstract void  unRegisterLocalVideoTextureObserver();

iOS

ビデオフレームコールバック

1. コールバックの登録

AliRtcEngineDelegate を実装し、registerVideoSampleObserver を呼び出してビデオフレームコールバックを登録します。

registerVideoSampleObserver

2. オブザベーションポイントの指定

SDK は、このメソッドから返されるビットマスクに基づいて、トリガーするコールバックを決定します。

/**
 * @brief ビデオデータ出力位置
 */
typedef NS_ENUM(NSInteger, AliRtcVideoObserPosition) {
    /** キャプチャされたビデオデータ、onCaptureVideoSample コールバックに対応 */
    AliRtcPositionPostCapture = 1 << 0,
    /** デコードされたリモートビデオデータ、onRemoteVideoSample コールバックに対応 */
    AliRtcPositionPreRender = 1 << 1,
    /** エンコード前のビデオデータ、onPreEncodeVideoSample コールバックに対応 */
    AliRtcPositionPreEncoder = 1 << 2,
};

/*
* SDK は AliRtcEngine::registerVideoSampleObserver を呼び出した後にこのメソッドを呼び出します。
*/

- (NSInteger)onGetVideoObservedFramePosition;

3. 出力フォーマットの指定

ビデオデータを CVPixelBuffer として受信するには、エンジンを作成するときに extra フィールドで user_specified_native_buffer_observer オプションを TRUE に設定します。

/**
 * @brief ビデオデータ形式
 */
typedef NS_ENUM(NSInteger, AliRtcVideoFormat) {
    AliRtcVideoFormat_UNKNOW = -1,
    AliRtcVideoFormat_BGRA = 0,
    AliRtcVideoFormat_I420,
    AliRtcVideoFormat_NV21,
    AliRtcVideoFormat_NV12,
    AliRtcVideoFormat_RGBA,
    AliRtcVideoFormat_I422,
    AliRtcVideoFormat_ARGB,
    AliRtcVideoFormat_ABGR,
    AliRtcVideoFormat_RGB24,
    AliRtcVideoFormat_BGR24,
    AliRtcVideoFormat_RGB565,
    AliRtcVideoFormat_TextureOES,
    AliRtcVideoFormat_Texture2D,
    AliRtcVideoFormat_H264,
    AliRtcVideoFormat_H265,
    AliRtcVideoFormat_File,
    AliRtcVideoFormat_cvPixelBuffer,
};

/*
* SDK は AliRtcEngine::registerVideoSampleObserver を呼び出した後にこのメソッドを呼び出します。
*/

- (AliRtcVideoFormat)onGetVideoFormatPreference {
    return AliRtcVideoFormat_I420;
}

4. メモリ配置の指定

/**
 * @brief ビデオ出力幅の配置
 */
typedef enum {
    /** 元のビデオ幅を維持 (デフォルト) */
    AliRtcAlignmentDefault = 0,
    /** ストライドを 2 バイトの倍数に配置 */
    AliRtcAlignmentEven = 1,
    /** ストライドを 4 バイトの倍数に配置 */
    AliRtcAlignment4 = 2,
    /** ストライドを 8 バイトの倍数に配置 */
    AliRtcAlignment8 = 3,
    /** ストライドを 16 バイトの倍数に配置 */
    AliRtcAlignment16 = 4,
} AliRtcVideoObserAlignment;

/*
* SDK は AliRtcEngine::registerVideoSampleObserver を呼び出した後にこのメソッドを呼び出します。
*/

- (AliRtcVideoObserAlignment)onGetVideoAlignment {
  return AliRtcAlignmentDefault;
}

5. ミラー効果を適用するかどうかの指定

/**
 * @brief 出力ビデオデータをミラーリングするかどうかを指定します。
 * @return
 * - YES: ミラーリング
 * - NO: ミラーリングしない (デフォルト)
 */
 
 /*
* SDK は AliRtcEngine::registerVideoSampleObserver を呼び出した後にこのメソッドを呼び出します。
*/
- (BOOL)onGetObserverDataMirrorApplied {
  return FLASE ;
}

6. コールバックの実装

/**
 * @brief サブスクライブされたローカルビデオデータのコールバック。
 * @param videoSource ビデオストリームのタイプ。
 * @param videoSample 生ビデオデータ。
 * @return
 * - YES: 変更されたデータを SDK に書き戻します。iOS および macOS では、YES を返すことによるデータの書き戻しは、I420 および CVPixelBuffer フォーマットでのみサポートされます。
 * - NO: データを SDK に書き戻しません。
*/
- (BOOL)onCaptureVideoSample:(AliRtcVideoSource)videoSource videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {
  /*
   * 処理...
   */
   return FALSE ;
}

/**
 * @brief サブスクライブされたローカルのエンコード前ビデオデータのコールバック。
 * @param videoSource ビデオストリームのタイプ。
 * @param videoSample 生ビデオデータ。
 * @return
 * - YES: 変更されたデータを SDK に書き戻します。iOS および macOS では、YES を返すことによるデータの書き戻しは、I420 および CVPixelBuffer フォーマットでのみサポートされます。
 * - NO: データを SDK に書き戻しません。
*/
- (BOOL)onPreEncodeVideoSample:(AliRtcVideoSource)videoSource videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {
  /*
   * 処理...
   */
   return FALSE ;
}

/**
 * @brief サブスクライブされたリモートビデオデータのコールバック。
 * @param uid ユーザー ID。
 * @param videoSource ビデオストリームのタイプ。
 * @param videoSample 生ビデオデータ。
 * @return
 * - YES: 変更されたデータを SDK に書き戻します。iOS および macOS では、YES を返すことによるデータの書き戻しは、I420 および CVPixelBuffer フォーマットでのみサポートされます。
 * - NO: データを SDK に書き戻しません。
*/
- (BOOL)onRemoteVideoSample:(NSString *_Nonnull)uid videoSource:(AliRtcVideoSource)videoSource videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {

  /*
   * 処理...
   */
  return TRUE ;
}

7. コールバックの登録解除

ビデオフレームを監視する必要がなくなったら、オブザーバーの登録を解除して不要な処理を回避します。

unregisterVideoSampleObserver

テクスチャ処理

テクスチャ関連のすべてのコールバックは、同じ専用の OpenGL スレッドで呼び出されます。

1. テクスチャコールバックの登録

registerLocalVideoTexture

2. コールバックの実装

OpenGL コンテキスト作成後のコールバック
/**
 * @brief OpenGL コンテキスト作成のコールバック。
 * @param context OpenGL コンテキスト。
 * @note このコールバックは、SDK の内部 OpenGL コンテキストが作成されたときにトリガーされます。
 */
- (void)onTextureCreate:(void *_Nullable)context {
    [[beautifyMoudle_ shared] create];
}
OpenGL テクスチャ更新コールバック
/**
 * @brief OpenGL テクスチャ更新のコールバック。
 * @param textureId OpenGL テクスチャの ID。
 * @param width テクスチャの幅。
 * @param height テクスチャの高さ。
 * @param videoSample ビデオフレームデータ、{@link AliRtcVideoDataSample} をご参照ください。
 * @return 処理された OpenGL テクスチャの ID。
 * @note
 * - このコールバックは、SDK が現在のビデオフレームを GPU テクスチャにアップロードした後に呼び出されます。OpenGL テクスチャオブザーバーを登録した場合、テクスチャを処理し、処理後にダウンストリームで使用されるテクスチャ ID を返すことができます。
 * - 有効なテクスチャ ID を返す必要があります。テクスチャを変更しない場合は、受信した textureId を変更せずに返します。
 * コールバックの textureId は AliRtcVideoFormat_Texture2D フォーマットです。
 */
- (int)onTextureUpdate:(int)textureId width:(int)width height:(int)height videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {
    
    if ( [[beautifyMoudle_ shared] enabled] == NO) {
        return textureId;
    }
    
    int texId = [[beautifyMoudle_ shared] processTextureToTexture:textureId Width:width Height:height];
    
    if(texId<0) {
       texId = textureId;
    }
    return texId;
}
OpenGL コンテキスト破棄コールバック
- (void)onTextureDestory
{
    if (self.settingModel.chnnelType == ChannelTypePrimary) {
        [[beautifyMoudle_ shared] destroy];
    }
    
}

3. テクスチャコールバックの登録解除

unregisterLocalVideoTexture