全部产品
Search
文档中心

ApsaraVideo Live:Pemrosesan data video mentah

更新时间:Oct 22, 2025

Selama sesi komunikasi real-time (RTC), Anda dapat memproses data video mentah dari SDK atau mengaksesnya pada berbagai tahap dalam alur kerja pemrosesan. Topik ini menjelaskan cara menggunakan pengamat video untuk mengakses dan memproses data tersebut.

Casus penggunaan

Kasus penggunaan umum untuk pemrosesan data video kustom meliputi:

  1. Retouching Kustom: Tarik aliran video lokal dan proses menggunakan SDK retouching pihak ketiga sebelum mengirimkannya ke pengguna lain di saluran.

  2. Pengeditan Video Kustom: Edit aliran video pada berbagai tahap alur kerja pemrosesan, seperti menambahkan efek khusus, watermark, pemotongan, atau pemangkasan. Aliran yang dimodifikasi kemudian dapat disiarkan atau disimpan.

  3. Pratinjau atau Pemantauan Aliran: Tarik aliran video pada berbagai tahap alur kerja pemrosesan untuk pemantauan dan pratinjau berbasis lokal atau cloud. Anda dapat memantau konten, kualitas, dan status aliran video secara real time untuk memastikan transmisi dan pemutaran yang tepat.

Sebelum Anda mulai

Pastikan Anda telah menyelesaikan persiapan berikut:

Cara kerjanya

Pengambilan Video:

Dekoding dan Rendering:

ARTC SDK menyediakan titik observasi pada berbagai tahap dalam alur kerja pemrosesan video.

Titik observasi tersebut sesuai dengan callback berikut:

  • Titik Observasi 1: Dapatkan data frame video asli, tanpa diskalakan melalui onCaptureVideoSample (iOS) atau onLocalVideoSample (Android) tepat setelah pengambilan.

  • Titik Observasi 2: Dapatkan data pra-pengkodean melalui onPreEncodeVideoSample.

  • Titik Observasi 3: Dapatkan data terdekripsi melalui onRemoteVideoSample.

  • Titik Observasi 4: Dapatkan konteks OpenGL (glcontext) melalui onTextureCreate dan ikat ke modul retouching Anda.

  • Titik Observasi 5: Terima data tekstur yang diperbarui melalui onTextureUpdate untuk menerapkan efek Anda.

  • Titik Observasi 6: Terima notifikasi untuk melepaskan glcontext melalui onTextureDestroy.

Catatan
  • Untuk titik observasi 1, 2, dan 3, mengembalikan true menunjukkan bahwa Anda telah memodifikasi data. Mengembalikan false meninggalkan data asli tidak berubah.

  • Untuk titik observasi 5, metode tersebut harus mengembalikan textureId yang valid. Mengembalikan textureId baru memberi tahu SDK untuk menggunakan tekstur yang telah Anda modifikasi untuk pengkodean dan pemrosesan. Jika Anda tidak melakukan pemrosesan kustom apa pun, kembalikan textureId asli.

Implementasi

Android

Callback frame video

1. Daftarkan callback

Untuk menerima data video mentah, implementasikan antarmuka AliRtcEngine.AliRtcVideoObserver dan daftarkan instance Anda dengan memanggil metode registerVideoSampleObserver().

public abstract void registerVideoSampleObserver(AliRtcVideoObserver observer);

2. Tentukan titik observasi

SDK menentukan callback mana yang akan dipicu berdasarkan bitmask yang dikembalikan oleh metode ini.

 public enum AliRtcVideoObserPosition{
        /*! Data video yang ditangkap secara lokal, sesuai dengan callback onLocalVideoSample */
        AliRtcPositionPostCapture(1),
        /*! Data video jarak jauh yang didekode, sesuai dengan callback onRemoteVideoSample */
        AliRtcPositionPreRender(2),
        /*! Data video pra-pengkodean, sesuai dengan callback onPreEncodeVideoSample */
        AliRtcPositionPreEncoder(4);
    }

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

3. Tentukan format keluaran

/**
 * @brief Format data video
 */
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 memanggil metode ini setelah Anda memanggil AliRtcEngine::registerVideoSampleObserver.
*/

/**
* @brief Format keluaran data video
* @return Format keluaran video yang diinginkan. Lihat {@link AliRtcVideoFormat}.
*/
public AliRtcVideoFormat onGetVideoFormatPreference(){
    return AliRtcVideoFormat.AliRtcVideoFormatI420;
}

4. Tentukan penyelarasan memori

public enum AliRtcVideoObserAlignment{
        /*! Pertahankan lebar video asli (default) */
        AliRtcAlignmentDefault(0),
        /*! Selaraskan stride ke kelipatan 2 byte */
        AliRtcAlignmentEven(1),
        /*! Selaraskan stride ke kelipatan 4 byte */
        AliRtcAlignment4(2),
        /*! Selaraskan stride ke kelipatan 8 byte */
        AliRtcAlignment8(3),
        /*! Selaraskan stride ke kelipatan 16 byte */
        AliRtcAlignment16(4);
};

/*
* SDK memanggil metode ini setelah Anda memanggil AliRtcEngine::registerVideoSampleObserver.
*/

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

5. Tentukan apakah akan menerapkan efek cermin

public boolean onGetObserverDataMirrorApplied(){
  return false;
}

6. Implementasikan callback

/*
* Kembalikan true untuk menulis modifikasi Anda kembali ke alur kerja pemrosesan SDK. 
* Ini diperlukan jika Anda memodifikasi AliRtcVideoSample.data.
*/

@Override
public boolean onLocalVideoSample(AliRtcEngine.AliRtcVideoSourceType sourceType, AliRtcEngine.AliRtcVideoSample videoSample) {
  boolean ret = false;
  /*
  * Proses data yang ditangkap secara lokal.
  */
  return ret;
}

@Override
public boolean onRemoteVideoSample(String userId, AliRtcEngine.AliRtcVideoSourceType sourceType, AliRtcEngine.AliRtcVideoSample videoSample) {
  /*
  * Proses data terdekripsi dari pengguna jarak jauh.
  */
  return false;
}

@Override
public boolean onPreEncodeVideoSample(AliRtcEngine.AliRtcVideoSourceType aliVideoSourceType, AliRtcEngine.AliRtcVideoSample videoSample) {
  boolean ret = false;
  /*
  * Proses data pra-pengkodean.
  */
  return false ;
}

7. Hapus pendaftaran callback

Ketika Anda tidak lagi perlu mengamati frame video, hapus pendaftaran pengamat untuk menghindari pemrosesan yang tidak perlu.

unregisterVideoSampleObserver

Pemrosesan tekstur

Semua callback terkait tekstur dipanggil pada thread OpenGL khusus yang sama. Untuk menggunakannya, implementasikan antarmuka AliRtcTextureObserver.

Prasyarat

Aktifkan penangkapan tekstur dan pengkodean tekstur dengan menyetel opsi berikut saat Anda menginisialisasi mesin.

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

1. Daftarkan callback tekstur

public abstract void registerLocalVideoTextureObserver(AliRtcTextureObserver observer);

2. Implementasikan callback

Callback setelah pembuatan konteks OpenGL
@Override
public void onTextureCreate(long context) {
      context_ = context ;
      Log.d(TAG, "konteks tekstur: "+context_+" dibuat!") ;
}
Callback pembaruan tekstur OpenGL
@Override
public int onTextureUpdate(int textureId, int width, int height, AliRtcEngine.AliRtcVideoSample videoSample) {
    /*
    *  Proses textureid.
    */
     ++log_ref ;
     return textureId;
}       
Callback penghancuran konteks OpenGL
@Override
public void onTextureDestroy() {
     Log.d(TAG, "konteks tekstur: "+context_+" dihancurkan!") ;
}

3. Hapus pendaftaran callback tekstur

public abstract void  unRegisterLocalVideoTextureObserver();

iOS

Callback bingkai video

1. Daftarkan callback

Implementasikan AliRtcEngineDelegate dan panggil registerVideoSampleObserver untuk mendaftarkan callback frame video.

registerVideoSampleObserver

2. Tentukan titik observasi

SDK menentukan callback mana yang akan dipicu berdasarkan bitmask yang dikembalikan oleh metode ini.

/**
 * @brief Posisi keluaran data video
 */
typedef NS_ENUM(NSInteger, AliRtcVideoObserPosition) {
    /** Data video yang ditangkap, sesuai dengan callback onCaptureVideoSample */
    AliRtcPositionPostCapture = 1 << 0,
    /** Data video jarak jauh yang didekode, sesuai dengan callback onRemoteVideoSample */
    AliRtcPositionPreRender = 1 << 1,
    /** Data video pra-pengkodean, sesuai dengan callback onPreEncodeVideoSample */
    AliRtcPositionPreEncoder = 1 << 2,
};

/*
* SDK memanggil metode ini setelah Anda memanggil AliRtcEngine::registerVideoSampleObserver.
*/

- (NSInteger)onGetVideoObservedFramePosition;

3. Tentukan format keluaran

Untuk menerima data video sebagai CVPixelBuffer, atur opsi user_specified_native_buffer_observer ke TRUE di bidang extra saat Anda membuat mesin.

/**
 * @brief Format data video
 */
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 memanggil metode ini setelah Anda memanggil AliRtcEngine::registerVideoSampleObserver.
*/

- (AliRtcVideoFormat)onGetVideoFormatPreference {
    return AliRtcVideoFormat_I420;
}

4. Tentukan penyelarasan memori

/**
 * @brief Penyelarasan lebar keluaran video
 */
typedef enum {
    /** Pertahankan lebar video asli (default) */
    AliRtcAlignmentDefault = 0,
    /** Selaraskan stride ke kelipatan 2 byte */
    AliRtcAlignmentEven = 1,
    /** Selaraskan stride ke kelipatan 4 byte */
    AliRtcAlignment4 = 2,
    /** Selaraskan stride ke kelipatan 8 byte */
    AliRtcAlignment8 = 3,
    /** Selaraskan stride ke kelipatan 16 byte */
    AliRtcAlignment16 = 4,
} AliRtcVideoObserAlignment;

/*
* SDK memanggil metode ini setelah Anda memanggil AliRtcEngine::registerVideoSampleObserver.
*/

- (AliRtcVideoObserAlignment)onGetVideoAlignment {
  return AliRtcAlignmentDefault;
}

5. Tentukan apakah akan menerapkan efek cermin

/**
 * @brief Menentukan apakah data video keluaran harus dicerminkan.
 * @return
 * - YES: Dicerminkan
 * - NO: Tidak dicerminkan (default)
 */
 
 /*
* SDK memanggil metode ini setelah Anda memanggil AliRtcEngine::registerVideoSampleObserver.
*/
- (BOOL)onGetObserverDataMirrorApplied {
  return FLASE ;
}

6. Implementasikan callback

/**
 * @brief Callback untuk data video lokal yang dilanggan.
 * @param videoSource Jenis aliran video.
 * @param videoSample Data video mentah.
 * @return
 * - YES: Tulis data yang dimodifikasi kembali ke SDK. Di iOS dan macOS, menulis kembali data dengan mengembalikan YES hanya didukung untuk format I420 dan CVPixelBuffer.
 * - NO: Jangan tulis data kembali ke SDK.
*/
- (BOOL)onCaptureVideoSample:(AliRtcVideoSource)videoSource videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {
  /*
   * lakukan....
   */
   return FALSE ;
}

/**
 * @brief Callback untuk data video pra-pengkodean lokal yang dilanggan.
 * @param videoSource Jenis aliran video.
 * @param videoSample Data video mentah.
 * @return
 * - YES: Tulis data yang dimodifikasi kembali ke SDK. Di iOS dan macOS, menulis kembali data dengan mengembalikan YES hanya didukung untuk format I420 dan CVPixelBuffer.
 * - NO: Jangan tulis data kembali ke SDK.
*/
- (BOOL)onPreEncodeVideoSample:(AliRtcVideoSource)videoSource videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {
  /*
   * lakukan....
   */
   return FALSE ;
}

/**
 * @brief Callback untuk data video jarak jauh yang dilanggan.
 * @param uid ID pengguna.
 * @param videoSource Jenis aliran video.
 * @param videoSample Data video mentah.
 * @return
 * - YES: Tulis data yang dimodifikasi kembali ke SDK. Di iOS dan macOS, menulis kembali data dengan mengembalikan YES hanya didukung untuk format I420 dan CVPixelBuffer.
 * - NO: Jangan tulis data kembali ke SDK.
*/
- (BOOL)onRemoteVideoSample:(NSString *_Nonnull)uid videoSource:(AliRtcVideoSource)videoSource videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {

  /*
   * lakukan....
   */
  return TRUE ;
}

7. Hapus pendaftaran callback

Ketika Anda tidak lagi perlu mengamati frame video, hapus pendaftaran pengamat untuk menghindari pemrosesan yang tidak perlu.

unregisterVideoSampleObserver

Pemrosesan tekstur

Semua callback terkait tekstur dipanggil pada thread OpenGL khusus yang sama.

1. Daftarkan callback tekstur

registerLocalVideoTexture

2. Implementasikan callback

Callback setelah pembuatan konteks OpenGL
/**
 * @brief Callback untuk pembuatan konteks OpenGL.
 * @param context Konteks OpenGL.
 * @note Callback ini dipicu ketika konteks OpenGL internal SDK dibuat.
 */
- (void)onTextureCreate:(void *_Nullable)context {
    [[beautifyMoudle_ shared] create];
}
Callback pembaruan tekstur OpenGL
/**
 * @brief Callback untuk pembaruan tekstur OpenGL.
 * @param textureId ID tekstur OpenGL.
 * @param width Lebar tekstur.
 * @param height Tinggi tekstur.
 * @param videoSample Data frame video, lihat {@link AliRtcVideoDataSample}.
 * @return ID tekstur OpenGL yang diproses.
 * @note
 * - Callback dipanggil setelah SDK mengunggah frame video saat ini ke tekstur GPU. Jika Anda mendaftarkan pengamat tekstur OpenGL, Anda dapat memproses tekstur dan mengembalikan ID tekstur yang akan digunakan hilir setelah pemrosesan Anda.
 * - Anda harus mengembalikan ID tekstur yang valid,Jika Anda tidak memodifikasi tekstur, kembalikan textureId yang masuk tanpa perubahan.
 * ID textureId callback dalam format 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;
}
Callback penghancuran konteks OpenGL
- (void)onTextureDestory
{
    if (self.settingModel.chnnelType == ChannelTypePrimary) {
        [[beautifyMoudle_ shared] destroy];
    }
    
}

3. Hapus pendaftaran callback tekstur

unregisterLocalVideoTexture