有奖捉虫:云通信与企业服务文档专题,速来> HOT

定制推流画面

iOS 平台

方案一:修改 OpenGL 纹理
方案二:自己采集数据
研发实力不俗的客户,会有自定义图像处理的需求(例如堆加字幕),同时又希望复用 RTMP SDK 的整体流程,如果是这样,您可以按照如下攻略进行定制。
1. 设置视频处理回调。n设置 TXLivePushvideoProcessDelegate 代理点,即可实现对视频画面的定制。
@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设置 TXLivePushsetVideoProcessListener 自定义视频回调,即可实现对视频画面的定制。
public interface VideoCustomProcessListener {
/**
*OpenGL 线程中回调,在这里可以进行采集图像的二次处理
*
* @param textureId 纹理 ID
* @param width 纹理的宽度
* @param height 纹理的高度
* @return 返回给 SDK 的纹理 ID,如果不做任何处理,返回传入的纹理 ID 即可
* <p>
* 说明:SDK 回调出来的纹理类型是 GLES20.GL_TEXTURE_2D,接口返回给 SDK 的纹理类型也必须是 GLES20.GL_TEXTURE_2D
*/
int onTextureCustomProcess(int textureId, int width, int height);

/**
* 增值版回调人脸坐标
*
* @param points 归一化人脸坐标,每两个值表示某点 PXY 值。值域[0.f1.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 为 3
public 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、height
TXLivePusher 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); // 采样率:48000Hz
config.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);
}