このトピックでは、カスタムビデオレンダリングを実装する方法について説明します。
機能の説明
Alibaba Real-Time Communication (ARTC) には、市場で実績のあるビデオレンダリングモジュールが含まれています。組み込みモジュールは、安定した効率的なビデオ再生体験を提供します。
成熟した自社開発のレンダリングモジュールがある場合、または色の精度やフレームレートの制御に特定の要件がある場合、ARTC ソフトウェア開発キット (SDK) は柔軟なインターフェイスを提供します。これらのインターフェイスを使用すると、カスタムビデオレンダリングモジュールを統合して、ビジネスニーズを満たすことができます。
前提条件
ビデオ設定を行う前に、次の前提条件が満たされていることを確認してください。
有効な Alibaba Cloud アカウントでリアルタイム音声・映像アプリケーションを作成済みであること。詳細については、「アプリケーションの作成」をご参照ください。また、[アプリケーション管理コンソール] から App ID と App Key を取得する必要があります。
ARTC SDK をプロジェクトに統合し、基本的な音声およびビデオ通信機能を実装済みであること。SDK の統合に関する詳細については、「SDK のダウンロードと統合」をご参照ください。音声およびビデオ通話の実装方法については、「音声およびビデオ通話の実装」をご参照ください。
技術的原則
リモートビデオレンダリング
バッファーベースのローカルビデオレンダリング
テクスチャ ID ベースのローカルビデオレンダリング
実装
iOS の実装
1. extra フィールドを使用した外部レンダリングの有効化
extra フィールドを使用して、外部ビデオ再生を有効にできます。この機能が有効になると、ARTC は仮想レンダラーを使用します。
NSString *extras = @"{\"user_specified_use_external_video_render\":\"TRUE\"}";
/* cvPixelBuffer のコールバックが必要な場合は、このオプションを追加します。 */
NSString * extras = @"{\"user_specified_use_external_video_render\":\"TRUE\",\"user_specified_native_buffer_observer\":"TRUE"}";
_engine = [AliRtcEngine sharedInstance:nil extras:extras];
2. コールバックの設定
cvPixelBuffer/I420:
[_engine registerVideoSampleObserver];
textureID:
[_engine registerLocalVideoTexture];3. コールバックの処理
I420/cvPixelBuffer
/*
* AliRtcEngine::registerVideoSampleObserver が呼び出された後にトリガーされます。
*/
- (AliRtcVideoFormat)onGetVideoFormatPreference {
return AliRtcVideoFormat_I420;
}
/**
* @brief ローカルでキャプチャされたサブスクライブ済みのビデオデータのコールバック。
* @param videoSource ビデオストリームのタイプ。
* @param videoSample RAW ビデオデータ。
* @return
* - YES: サンプルを SDK に書き戻す必要があります。これは、iOS および macOS の I420 および CVPixelBuffer フォーマットでのみ有効です。
* - NO: サンプルを SDK に書き戻す必要はありません。
*/
- (BOOL)onCaptureVideoSample:(AliRtcVideoSource)videoSource videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {
/*
* 処理....
*/
return FALSE ;
}
textureID
OpenGL コンテキスト作成後のコールバック
/** * @brief OpenGL コンテキスト作成のコールバック。 * @param context OpenGL コンテキスト。 * @note このコールバックは、SDK 内で OpenGL コンテキストが作成されたときにトリガーされます。 */ - (void)onTextureCreate:(void *_Nullable)context { [[renderEngine_ shared] create:context]; }OpenGL テクスチャ更新のコールバック
/** * @brief OpenGL テクスチャ更新のコールバック。 * @param textureId OpenGL テクスチャ ID。 * @param width OpenGL テクスチャの幅。 * @param height OpenGL テクスチャの高さ。 * @param videoSample ビデオフレームデータ。詳細については、{@link AliRtcVideoDataSample} をご参照ください。 * @return OpenGL テクスチャ ID。 * @note * - このコールバックは、各ビデオフレームが OpenGL テクスチャにアップロードされた後にトリガーされます。OpenGL テクスチャデータの外部オブザーバーが登録されている場合、このコールバックでテクスチャを処理し、処理されたテクスチャ ID を返すことができます。 * - 戻り値は有効なテクスチャ ID である必要があります。処理が実行されない場合は、元の textureId パラメーターを返す必要があります。 * 返される TextureID のフォーマットは 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; }OpenGL コンテキスト削除のコールバック
- (void)onTextureDestory { if (self.settingModel.chnnelType == ChannelTypePrimary) { [[renderEngine_ shared] destroy]; } }
4. 終了
/* I420/cvPixelBuffer */
unregisterVideoSampleObserver
/* textureID */
unregisterLocalVideoTextureAndroid の実装
1. extra フィールドを使用した外部レンダリングの有効化
extra フィールドを使用して、外部ビデオ再生を有効にできます。この機能が有効になると、ARTC は仮想レンダラーを使用します。
String extras = "{\"user_specified_use_external_video_render\":\"TRUE\"}";
/*
textureID のコールバックが必要な場合は、このオプションを追加します。
テクスチャのハードウェアエンコーディングも有効にすることをお勧めします。
*/
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. コールバックの設定
cvPixelBuffer/I420:
_engine.registerVideoSampleObserver();
textureID:
_engine.registerLocalVideoTextureObserver();3. コールバックの処理
I420/cvPixelBuffer
/**
* @brief ローカルでキャプチャされたサブスクライブ済みのビデオデータのコールバック。
* @param videoSource ビデオストリームのタイプ。
* @param videoSample RAW ビデオデータ。
* @return
* - true: サンプルを SDK に書き戻す必要があります。これは、iOS および macOS の I420 および CVPixelBuffer フォーマットでのみ有効です。
* - false: サンプルを SDK に書き戻す必要はありません。
*/
public int onGetVideoAlignment(){
return AliRtcVideoObserAlignment.AliRtcAlignmentDefault.getValue();
}
@Override
public boolean onLocalVideoSample(AliRtcEngine.AliRtcVideoSourceType sourceType, AliRtcEngine.AliRtcVideoSample videoSample) {
boolean ret = false;
/*
* ローカルでキャプチャされたビデオデータをレンダリングのために処理します。
*/
local_renderEngine.draw(videoSample);
return ret;
}
@Override
public boolean onRemoteVideoSample(String userId, AliRtcEngine.AliRtcVideoSourceType sourceType, AliRtcEngine.AliRtcVideoSample videoSample) {
/*
* リモートデータをレンダリングのために処理します。
*/
remote_renderEngine.draw(userId, videoSample);
return false;
}
textureID
OpenGL コンテキスト作成後のコールバック
@Override public void onTextureCreate(long context) { context_ = context ; render.bind(context); Log.d(TAG, "texture context: "+context_+" create!") ; }OpenGL テクスチャ更新のコールバック
/** @Override public int onTextureUpdate(int textureId, int width, int height, AliRtcEngine.AliRtcVideoSample videoSample) { /* * テクスチャ ID を処理します。 */ render.drawTexture(textureId); return textureId; }OpenGL コンテキスト削除のコールバック
@Override public void onTextureDestroy() { render.free(context_); Log.d(TAG, "texture context: "+context_+" destory!") ; }
4. 終了
/* I420/cvPixelBuffer */
_engine.unregisterVideoSampleObserver();
/* textureID */
_engine.unRegisterLocalVideoTextureObserver();