腾讯云直播SDK自定义采集和渲染_音视频解决方案_同尘科技
定制推流画面
iOS 平台
方案一:修改 OpenGL 纹理方案二:自己采集数据研发实力不俗的客户,会有自定义图像处理的需求(例如堆加字幕),同时又希望复用 RTMP SDK 的整体流程,如果是这样,您可以按照如下攻略进行定制。1. 设置视频处理回调。n设置 TXLivePush 的 videoProcessDelegate 代理点,即可实现对视频画面的定制。
@protocol TXVideoCustomProcessDelegate
/*** 在OpenGL线程中回调,在这里可以进行采集图像的二次处理* @param textureId 纹理 ID* @param width 纹理的宽度* @param height 纹理的高度* @return 返回给 SDK 的纹理* 说明:SDK回调出来的纹理类型是 GL_TEXTURE_2D,接口返回给SDK的纹理类型也必须是 GL_TEXTURE_2D*/-(GLuint)onPreProcessTexture:(GLuint)texture width:(CGFloat)width height:(CGFloat)height;
/*** 在OpenGL线程中回调,可以在这里释放创建的OpenGL资源*/-(void)onTextureDestoryed;
@end
2. 在回调函数中对视频数据进行加工。n实现 TXVideoCustomProcessDelegate 的 onPreProcessTexture 函数,以实现对视频画面的自定义处理。textureId 指定的纹理是一块类型为 GLES20.GL_TEXTURE_2D 的纹理。 对于 texture 数据的操作,需要一定的 OpenGL 基础知识,另外计算量不宜太大,因为 onPreProcessTexture 的调用频率跟 FPS 相同,过于繁重的处理很容易造成 GPU 过热。如果您只希望使用 SDK 来编码和推流(例如已经对接了商汤等产品),音视频采集和预处理(即美颜、滤镜这些)全部由自己的代码来控制,可以按如下步骤实现:1. 不再调用 TXLivePush 的 startPreview 接口。n这样 SDK 本身就不会再采集视频数据和音频数据,而只是启动预处理、编码、流控、发送等跟推流相关的工作。2. 通过 TXLivePushConfig 设置 customModeType。
#define CUSTOM_MODE_AUDIO_CAPTURE 0X001 //客户自己采集声音#define CUSTOM_MODE_VIDEO_CAPTURE 0X002 //客户自己采集视频
//如果声音和视频都要自己采集,可以设置 customModeType 为 3@interface TXLivePushConfig : NSObject@property(nonatomic, assign) int customModeType;@end
3. 使用 sendVideoSampleBuffer 向 SDK 填充 Video 数据。nsendVideoSampleBuffer 的作用是向 SDK 塞入您采集和处理后的视频数据,目前支持 RGBA 和 NV12 两种格式。
TXLivePushConfig *config = [[TXLivePushConfig alloc] init];config.customModeType = CUSTOM_MODE_VIDEO_CAPTURE; // 自定义采集数据TXLivePush *pusher = [[TXLivePush alloc] initWithConfig:config];
//可以塞入自己采集和处理的 RGBA 或者 NV12 数据[pusher sendVideoSampleBuffer:sampleBuffer];
4. 使用 sendAudioSampleBuffer 向 SDK 填充 Audio 数据。nsendAudioSampleBuffer 的作用是向 SDK 塞入您采集和处理后的音频数据,请使用单声道、16位宽、48000Hz 的 PCM 声音数据。n该函数支持两种 RPSampleBufferType, RPSampleBufferTypeAudioApp 和 RPSampleBufferTypeAudioMic,前者用于 replaykit,后者用于常规的麦克风采集(也用于 replaykit)。
TXLivePushConfig *config = [[TXLivePushConfig alloc] init];config.customModeType = CUSTOM_MODE_AUDIO_CAPTURE; // 自定义采集数据TXLivePush *pusher = [[TXLivePush alloc] initWithConfig:config];
//可以塞入自己采集和处理的 声音数据[pusher sendAudioSampleBuffer:sampleBuffer withType:RPSampleBufferTypeAudioMic];
Android 平台
方案一:修改 OpenGL 纹理方案二:自己采集数据研发实力不俗的客户,会有自定义图像处理的需求(例如堆加字幕),同时又希望复用 RTMP SDK 的整体流程,如果是这样,您可以按照如下攻略进行定制。1. 设置视频处理回调。n设置 TXLivePush 的 setVideoProcessListener 自定义视频回调,即可实现对视频画面的定制。
public interface VideoCustomProcessListener {/*** 在 OpenGL 线程中回调,在这里可以进行采集图像的二次处理** @param textureId 纹理 ID* @param width 纹理的宽度* @param height 纹理的高度* @return 返回给 SDK 的纹理 ID,如果不做任何处理,返回传入的纹理 ID 即可** 说明:SDK 回调出来的纹理类型是 GLES20.GL_TEXTURE_2D,接口返回给 SDK 的纹理类型也必须是 GLES20.GL_TEXTURE_2D*/int onTextureCustomProcess(int textureId, int width, int height);
/** * 增值版回调人脸坐标** @param points 归一化人脸坐标,每两个值表示某点 P 的 X,Y 值。值域[0.f,1.f]*/void onDetectFacePoints(float[] points);
/*** 在 OpenGL 线程中回调,可以在这里释放创建的 OpenGL 资源*/void onTextureDestoryed();}
2. 在回调函数中对视频数据进行加工。n实现 VideoCustomProcessListener 的 onTextureCustomProcess 函数,以实现对视频画面的自定义处理。textureId 指定的纹理是一块类型为 GLES20.GL_TEXTURE_2D 的纹理。 对于 texture 数据的操作,需要一定的 OpenGL 基础知识,另外计算量不宜太大,因为 onTextureCustomProcess 的调用频率跟 FPS 相同,过于繁重的处理很容易造成 GPU 过热。如果您只希望使用 SDK 来编码和推流(例如已经对接了商汤等产品),音视频采集和预处理(即美颜、滤镜这些)全部由自己的代码来控制,可以按如下步骤实现:1. 不再调用 TXLivePush 的 startPreview 接口。n这样 SDK 本身就不会再采集视频数据和音频数据,而只是启动预处理、编码、流控、发送等跟推流相关的工作。2. 通过 TXLivePushConfig 设置 customModeType
public static final int CUSTOM_MODE_AUDIO_CAPTURE = 0X001; //客户自定义音频采集public static final int CUSTOM_MODE_VIDEO_CAPTURE = 0X002; //客户自定义视频采集
//如果声音和视频都要自己采集,可以设置 customModeType 为 3public class TXLivePushConfig { public void setCustomModeType(int modeType) {}}
3. 使用 sendCustomVideoTexture 或者 sendCustomVideoData 向 SDK 填充 Video 数据。nsendCustomVideoTexture 的作用是向 SDK 塞入您采集和处理后的 texture 视频数据,目前仅支持普通纹理,暂不支持外部纹理。nsendCustomVideoData 的作用是向 SDK 塞入您采集和处理后的视频数据,目前支持 YUV_420P 和 RGB_RGBA 两种格式。
TXLivePushConfig config = new TXLivePushConfig();config.setCustomModeType(CUSTOM_MODE_VIDEO_CAPTURE); // 自定义采集数据config.setVideoResolution(VIDEO_RESOLUTION_TYPE_640_360); // 设置为您发送 YUV 数据的 width、heightTXLivePusher pusher = new TXLivePusher(context);pusher.setConfig(config);
//可以塞入自己采集和处理的 texture 数据pusher.sendCustomVideoTexture(textureID, width, height);
//可以塞入自己采集和处理的 RGBA 或者 NV12 数据pusher.sendCustomVideoData(buffer, bufferType, width, height);
4. 使用 sendCustomPCMData 向 SDK 填充 Audio 数据。nsendCustomPCMData 的作用是向 SDK 发送自己采集的音频 PCM 数据。nSDK 对每次传入的 PCM buffer 大小有严格要求,每一个采样点要求是16位宽。 如果是单声道,请保证传入的 PCM 长度为2048;如果是双声道,请保证传入的 PCM 长度为4096。
TXLivePushConfig config = new TXLivePushConfig();config.setCustomModeType(CUSTOM_MODE_AUDIO_CAPTURE); // 自定义采集数据config.setAudioSampleRate(48000); // 采样率:48000Hzconfig.setAudioChannels(1); // 默认值:1(单声道)TXLivePusher pusher = new TXLivePusher(context);pusher.setConfig(config);
//可以塞入自己采集和处理的 声音数据pusher.sendCustomPCMData(pcmBuffer);
定制播放数据
iOS 平台
1. 设置 TXLivePlayer 的 TXVideoCustomProcessDelegate 属性。
@interface TXLivePlayer : NSObject// 设置之后,Player 的每帧画面都会经过 onPlayerPixelBuffer@property(nonatomic, weak) id videoProcessDelegate;
2. 通过 onPlayerPixelBuffer 回调捕获 Player 的图像数据。n如果当前 Player 是硬解码模式,pixelBuffer 的图像格式是 NV12,如果当前 Player 是软解码模式,pixelBuffer 的图像格式是 i420 。nonPlayerPixelBuffer 返回值为 YES 时, SDK 不会继续做图像渲染,这种方式可以解决 OpenGL 线程冲突的问题。
@protocol TXVideoCustomProcessDelegate@optional
/*** 视频渲染对象回调* @prarm pixelBuffer 渲染图像* @return 返回YES则SDK不再显示;返回NO则SDK渲染模块继续渲染* 说明:渲染图像的数据类型为config中设置的renderPixelFormatType*/-(BOOL)onPlayerPixelBuffer:(CVPixelBufferRef)pixelBuffer;@end
Android 平台
1. 设置 TXLivePlayer 的 ITXLivePlayVideoRenderListener 接口。
public class TXLivePlayer { /** * 设置视频渲染纹理回调 * * @param listener 自定义渲染纹理回调 * @param glContext OpenGL 上下文,如果您的渲染模块使用 (javax.microedition.khronos.egl.*) 定义的 OpenGL 接口,请填 javax.microedition.khronos.egl.EGLContext 类型的对象 * 如果您的渲染模块使用 (android.opengl.*) 定义的 OpenGL 接口,请填 android.opengl.EGLContext 类型的对象。 * 如果填 null 表示使用 SDK 内部默认的 javax.microedition.khronos.egl.EGLContext 环境 * @return 0:成功;-1:glContext 类型非法。 */ public int setVideoRenderListener(final ITXLivePlayVideoRenderListener listener, Object glContext) {}}
2. 通过 onRenderVideoFrame 回调捕获 Player 的图像数据。
static public class TXLiteAVTexture{ public int textureId; // 视频纹理 ID public int width; // 视频宽度 public int height; // 视频高度 public Object eglContext; // javax.microedition.khronos.egl.EGLContext 或 android.opengl.EGLContext 定义的 OpenGL Context}
public interface ITXLivePlayVideoRenderListener { /** * 解码器解出一帧数据回调一次 * * @param texture 视频纹理 */ void onRenderVideoFrame(TXLiteAVTexture texture);}
对音视频的解决方案有疑惑?想了解解决方案收费? 联系解决方案专家
腾讯云限时活动1折起,即将结束: 马上收藏
同尘科技为腾讯云授权服务中心,购买腾讯云享受折上折,更有现金返利:同意关联,立享优惠
阿里云解决方案也看看?: 点击对比阿里云的解决方案
暂无评论,你要说点什么吗?