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:
Retouching Kustom: Tarik aliran video lokal dan proses menggunakan SDK retouching pihak ketiga sebelum mengirimkannya ke pengguna lain di saluran.
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.
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:
Buat aplikasi ARTC dan dapatkan AppID dan AppKey dari Konsol ApsaraVideo Live.
Integrasi ARTC SDK ke dalam proyek Anda dan implementasikan fitur panggilan audio dan video dasar.
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) atauonLocalVideoSample(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) melaluionTextureCreatedan ikat ke modul retouching Anda.Titik Observasi 5: Terima data tekstur yang diperbarui melalui
onTextureUpdateuntuk menerapkan efek Anda.Titik Observasi 6: Terima notifikasi untuk melepaskan
glcontextmelaluionTextureDestroy.
Untuk titik observasi 1, 2, dan 3, mengembalikan
truemenunjukkan bahwa Anda telah memodifikasi data. Mengembalikanfalsemeninggalkan data asli tidak berubah.Untuk titik observasi 5, metode tersebut harus mengembalikan
textureIdyang valid. MengembalikantextureIdbaru memberi tahu SDK untuk menggunakan tekstur yang telah Anda modifikasi untuk pengkodean dan pemrosesan. Jika Anda tidak melakukan pemrosesan kustom apa pun, kembalikantextureIdasli.
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.
unregisterVideoSampleObserverPemrosesan 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.
registerVideoSampleObserver2. 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.
unregisterVideoSampleObserverPemrosesan tekstur
Semua callback terkait tekstur dipanggil pada thread OpenGL khusus yang sama.
1. Daftarkan callback tekstur
registerLocalVideoTexture2. 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