全部产品
Search
文档中心

ApsaraVideo Live:Pembuatan video khusus

更新时间:Nov 05, 2025

Topik ini menjelaskan cara mengimplementasikan rendering video kustom.

Deskripsi fitur

ApsaraVideo Real-time Communication (ARTC) mencakup modul rendering video yang terbukti di pasar. Modul bawaan ini memberikan pengalaman pemutaran video yang stabil dan efisien.

Jika Anda memiliki modul rendering mandiri yang matang atau persyaratan khusus untuk akurasi warna dan kontrol laju frame, kit pengembangan perangkat lunak (SDK) ARTC menyediakan antarmuka yang fleksibel. Antarmuka ini memungkinkan Anda mengintegrasikan modul rendering video kustom untuk memenuhi kebutuhan bisnis Anda.

Prasyarat

Sebelum mengonfigurasi pengaturan video, pastikan prasyarat berikut telah dipenuhi:

  • Anda telah membuat aplikasi ApsaraVideo Real-time Communication dengan Akun Alibaba Cloud yang valid. Untuk informasi lebih lanjut, lihat Buat Aplikasi. Anda juga harus memperoleh App ID dan App Key dari Konsol Manajemen Aplikasi.

  • Anda telah mengintegrasikan SDK ARTC ke dalam proyek Anda dan mengimplementasikan fitur komunikasi audio dan video dasar. Untuk informasi lebih lanjut tentang integrasi SDK, lihat Unduh dan Integrasi SDK. Untuk mempelajari cara mengimplementasikan panggilan audio dan video, lihat Implementasikan Panggilan Audio dan Video.

Prinsip teknis

Rendering video jarak jauh

Rendering video lokal berbasis buffer

Rendering video lokal berbasis ID tekstur

Implementasi

Implementasi iOS

1. Aktifkan rendering eksternal menggunakan bidang tambahan

Anda dapat mengaktifkan pemutaran video eksternal menggunakan bidang tambahan. Setelah fitur ini diaktifkan, ARTC menggunakan renderer virtual.

NSString *extras = @"{\"user_specified_use_external_video_render\":\"TRUE\"}";

/* Jika diperlukan callback untuk cvPixelBuffer, tambahkan opsi ini. */
NSString * extras = @"{\"user_specified_use_external_video_render\":\"TRUE\",\"user_specified_native_buffer_observer\":"TRUE"}";


_engine = [AliRtcEngine sharedInstance:nil extras:extras];

2. Atur callback

cvPixelBuffer/I420:
[_engine registerVideoSampleObserver];

textureID:
[_engine registerLocalVideoTexture];

3. Tangani callback

I420/cvPixelBuffer

/*
* Dipicu setelah AliRtcEngine::registerVideoSampleObserver dipanggil.
*/

- (AliRtcVideoFormat)onGetVideoFormatPreference {
    return AliRtcVideoFormat_I420;
}

/**
 * @brief Callback untuk data video yang dilanggan secara lokal.
 * @param videoSource Jenis aliran video.
 * @param videoSample Data video mentah.
 * @return
 * - YES: Sampel perlu ditulis kembali ke SDK. Ini hanya berlaku untuk format I420 dan CVPixelBuffer pada iOS dan macOS.
 * - NO: Sampel tidak perlu ditulis kembali ke SDK.
*/

- (BOOL)onCaptureVideoSample:(AliRtcVideoSource)videoSource videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {
  /*
   * lakukan....
   */
   return FALSE ;
}

textureID

  • Callback setelah konteks OpenGL dibuat

    /**
     * @brief Callback untuk pembuatan konteks OpenGL.
     * @param context Konteks OpenGL.
     * @note Callback ini dipicu ketika konteks OpenGL dibuat di dalam SDK.
     */
    - (void)onTextureCreate:(void *_Nullable)context {
        [[renderEngine_ shared] create:context];
    }
  • Callback untuk pembaruan tekstur OpenGL

    /**
     * @brief Callback untuk pembaruan tekstur OpenGL.
     * @param textureId ID tekstur OpenGL.
     * @param width Lebar tekstur OpenGL.
     * @param height Tinggi tekstur OpenGL.
     * @param videoSample Data frame video. Untuk informasi lebih lanjut, lihat {@link AliRtcVideoDataSample}.
     * @return ID tekstur OpenGL.
     * @note
     * - Callback ini dipicu setelah setiap frame video diunggah ke tekstur OpenGL. Jika observer eksternal untuk data tekstur OpenGL terdaftar, Anda dapat memproses tekstur dalam callback ini dan mengembalikan ID tekstur yang diproses.
     * - Nilai kembali harus berupa ID tekstur yang valid. Jika tidak ada pemrosesan yang dilakukan, Anda harus mengembalikan parameter textureId asli.
     * Format TextureID yang dikembalikan adalah AliRtcVideoFormat_Texture2D.
     */
    - (int)onTextureUpdate:(int)textureId width:(int)width height:(int)height videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {
        
        if ( [[renderEngine_ shared] enabled] == NO) {
            return textureId;
        }
        
        int texId = [[renderEngine_ shared] processTextureToTexture:textureId Width:width Height:height];
        
        if(texId<0) {
           texId = textureId;
        }
        return texId;
    }
  • Callback untuk penghapusan konteks OpenGL

    - (void)onTextureDestory
    {
        if (self.settingModel.chnnelType == ChannelTypePrimary) {
            [[renderEngine_ shared] destroy];
        }
        
    }

4. Keluar

/* I420/cvPixelBuffer */
unregisterVideoSampleObserver

/* textureID */
unregisterLocalVideoTexture

Implementasi Android

1. Aktifkan rendering eksternal menggunakan bidang tambahan

Anda dapat mengaktifkan pemutaran video eksternal menggunakan bidang tambahan. Setelah fitur ini diaktifkan, ARTC menggunakan renderer virtual.

String extras = "{\"user_specified_use_external_video_render\":\"TRUE\"}";

/* 
   Jika diperlukan callback untuk textureID, tambahkan opsi ini.
   Kami sarankan Anda juga mengaktifkan encoding perangkat keras untuk tekstur.
   */
String extras = "{\"user_specified_use_external_video_render\":\"TRUE\",\"user_specified_camera_texture_capture\":"TRUE",\"user_specified_texture_encode\":"TRUE" }";

_engine = AliRtcEngine.getInstance(getApplicationContext(), extras);

2. Atur callback

cvPixelBuffer/I420:
_engine.registerVideoSampleObserver();


textureID:
_engine.registerLocalVideoTextureObserver();

3. Tangani callback

I420/cvPixelBuffer

/**
 * @brief Callback untuk data video yang dilanggan secara lokal.
 * @param videoSource Jenis aliran video.
 * @param videoSample Data video mentah.
 * @return
 * - true: Sampel perlu ditulis kembali ke SDK. Ini hanya berlaku untuk format I420 dan CVPixelBuffer pada iOS dan macOS.
 * - false: Sampel tidak perlu ditulis kembali ke SDK.
*/
public int onGetVideoAlignment(){
  return AliRtcVideoObserAlignment.AliRtcAlignmentDefault.getValue();
}

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

@Override
public boolean onRemoteVideoSample(String userId, AliRtcEngine.AliRtcVideoSourceType sourceType, AliRtcEngine.AliRtcVideoSample videoSample) {
  /*
  * Proses data jarak jauh untuk rendering.
  */
  remote_renderEngine.draw(userId, videoSample);
  
  return false;
}

textureID

  • Callback setelah konteks OpenGL dibuat

    @Override
    public void onTextureCreate(long context) {
          context_ = context ;
          render.bind(context);
          Log.d(TAG, "konteks tekstur: "+context_+" dibuat!") ;
    }
    
  • Callback untuk pembaruan tekstur OpenGL

    /**
    @Override
    public int onTextureUpdate(int textureId, int width, int height, AliRtcEngine.AliRtcVideoSample videoSample) {
        /*
        *  Proses ID tekstur.
        */
        render.drawTexture(textureId);
         return textureId;
    }    
    
    
  • Callback untuk penghapusan konteks OpenGL

    @Override
    public void onTextureDestroy() {
         render.free(context_);
         Log.d(TAG, "konteks tekstur: "+context_+" dihapus!") ;
    }

4. Keluar

/* I420/cvPixelBuffer */
_engine.unregisterVideoSampleObserver();

/* textureID */
_engine.unRegisterLocalVideoTextureObserver();