自定义音频播放是用户有一定的研发能力的情况,希望自己控制播放来实现某些需求,因此ARTC提供了相关的功能方便用户实现这些需求。
前提条件
ARTC内置了经过市场检验的视频渲染模块,因此一般情况下建议客户使用ARTC内置的视频渲染模块,如果有特殊需求,客户有自己完善的视频渲染模块或特殊需求,可以使用自己的视频渲染模块处理和回放视频。
技术原理
因为iOS和Android端设备的视频渲染API存在差异,接下来我们分两部分介绍iOS端和Android端视频渲染的功能设计。
iOS端功能设计
远端视频渲染
本地视频渲染-Buffer
本地视频渲染-textureID
Android端功能设计
远端视频渲染
本地视频渲染-Buffer
本地视频渲染-textureID
iOS端实现方案
1.通过extra字段开启外部渲染
通过extra字段开启外部视频播放功能,开启该功能之后,RTC会启用虚拟render来渲染。
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 视频裸数据
* @return
* - YES: 需要写回SDK(只对I420和CVPixelBuffer(ios/mac)有效)
* - NO: 不需要写回SDK
*/
- (BOOL)onCaptureVideoSample:(AliRtcVideoSource)videoSource videoSample:(AliRtcVideoDataSample *_Nonnull)videoSample {
/*
* do....
*/
return FALSE ;
}
textureID
openGL context创建后回调
/** * @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 */
unregisterLocalVideoTexture
Android端实现方案
1.通过extra字段开启外部渲染
通过extra字段开启外部视频播放功能,开启该功能之后,RTC会启用虚拟render来渲染。
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 视频裸数据
* @return
* - YES: 需要写回SDK(只对I420和CVPixelBuffer(ios/mac)有效)
* - NO: 不需要写回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 context创建后回调
@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) { /* * 进行 textureid处理 */ 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();
该文章对您有帮助吗?
- 本页导读 (1)
- 前提条件
- 技术原理
- iOS端功能设计
- Android端功能设计
- iOS端实现方案
- 1.通过extra字段开启外部渲染
- 2.设置回调
- 3.处理回调
- 4.退出
- Android端实现方案
- 1.通过extra字段开启外部渲染
- 2.设置回调
- 3.处理回调
- 4.退出