音视频前处理

本章节主要介绍网易云提供的各种音视频前处理功能。前处理介于采集和编码之间,按照数据类型分类,可以分为音频前处理和视频前处理,音频前处理包括降噪回音消除人声检测自动增益等等,视频前处理包括美颜磨皮设置对比度镜像水印等。网易云移动端SDK中内置了基础款的美颜滤镜。 同时,网易云还提供了音视频采集数据的回调功能,所以除了SDK自带的一些音视频的前处理功能,开发者可以利用音视频采集数据的回调功能,实现自定义的音视频数据前处理,包括接入第三方变声、美颜算法。

音频前处理

音频采集数据回调与发送

在加入多人会议或者互动直播房间时,在 meetingoption 参数中指定视频采集数据回调block audioHandler,SDK 采集到的音频数据都会通过它回调给应用。audioHandler 的类型声明如下:

typedef NSUInteger(^NIMNetCallAudioSamplesHandler)(SInt16 *audioSamples, NSUInteger samplesNumber, Float64 sampleRate)

其中 audioSamples 是麦克风采集到的语音原始 PCM 采样数据,应用处理完的数据也需要通过该字段回填,回填的数据的采样点数通过该回调的返回值告知 SDK。

注意:回填数据采样点数不允许超过回调的数据采样点数;如果需要发送较多数据,可以在每次回调中发送最多 samplesNumber 个采样点数据。

建议异步地处理语音数据,并且在该回调中发送之前已经异步处理完的语音数据。

开启耳返

在通话过程中开启耳返,用户务必需要先自己判断是否有耳机连接,再开启耳返,SDK不负责判断。

@protocol NIMNetCallManager <NSObject>
/**
 打开耳返
 */
- (void)startEarBack;
@end
//若有耳机连接,开启耳返 需要自己判断是否有耳机连接
[[NIMAVChatSDK sharedSDK].netCallManager startEarBack];

关闭耳返

关闭耳返

@protocol NIMNetCallManager <NSObject>
/**
 关闭耳返
 */
- (void)stopEarBack;
@end
//关闭耳返
[[NIMAVChatSDK sharedSDK].netCallManager stopEarBack];

调节耳返音量

动态调节耳返音量。

@protocol NIMNetCallManager <NSObject>
/**
 调节耳返音量

 @param volume 耳返音量 接受输入值为 0 到 10

 @return 是否调节成功
 */
- (BOOL)changeEarBackVolume:(NSUInteger)volume;
@end
参数 类型 说明
volume NSUInteger 耳返音量 接受输入值为 0 到 10
//调节耳返音量为5
[[NIMAVChatSDK sharedSDK].netCallManager changeEarBackVolume:5]

视频前处理

视频采集数据回调

在开启视频采集时,在 NIMNetCallVideoCaptureParam 中指定视频采集数据回调 block videoHandler,SDK 采集到的视频画面都会通过它回调给应用。videoHandler 的类型声明如下:

typedef void(^NIMNetCallVideoSampleBufferHandler)(CMSampleBufferRef sampleBuffer)

回调的 sampleBuffer 携带时间戳和 NIMNetCallVideoCaptureParam 中指定的格式的 CVPixelBuffer 图像。

处理完的图像和回调的时间戳一起封装为 CMSampleBufferRef 格式的数据,调用以下接口发送出去:

- (nullable NSError *)sendVideoSampleBuffer:(CMSampleBufferRef)buffer

然后再通过onLocalDisplayviewReady:中的 view 进行绘制

视频数据发送

视频数据发送至SDK 对视频数据进行前处理(如SDK美颜,水印)及发送。

@protocol NIMNetCallManager <NSObject>
/**
 *  发送视频 SampleBuffer
 *
 *  @param buffer 只支持包含以下三种 CVPixelBuffer 数据格式的 sampleBuffer: kCVPixelFormatType_32BGRA、kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange、kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
 *
 *  @discussion 可以发送SDK回调上来的视频数据,也可以发送自定义视频数据 自定义数据输入不能超过720P
 *
 *  @return 发送结果
 */
- (nullable NSError *)sendVideoSampleBuffer:(CMSampleBufferRef)buffer;
@end
参数 类型 说明
buffer CMSampleBufferRef 只支持包含以下三种 CVPixelBuffer 数据格式的 sampleBuffer: kCVPixelFormatType_32BGRA、kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange、kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
//视频采集数据回调
_videoParam.videoHandler =^(CMSampleBufferRef sampleBuffer){
     //对采集数据进行外部前处理
     ...
     //把 sampleBuffer 数据发送给 SDK 进行显示,编码,发送 
    [[NIMAVChatSDK sharedSDK].netCallManager sendVideoSampleBuffer:sampleBuffer];
};

注意:处理完的画面封装为 CMSampleBufferRef 时,需要填入回调时该画面对应的时间戳,否则对端的视频播放时序会被破坏。

注意:SDK 只接受 sampleBuffer 为封装了 kCVPixelFormatType_32BGRA、kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange 或者 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 的 CVPixelBuffer 的视频画面发送。

iOS网络通话本地回调画面(美颜)相关的格式转换

对视频美颜

对视频美颜

@protocol NIMNetCallManager <NSObject>
/**
 选择滤镜类型

 @param type  滤镜类型
 */
- (void)selectBeautifyType:(NIMNetCallFilterType)type;
@end
参数 类型 说明
type NIMNetCallFilterType 滤镜类型
//选择自然模式进行美颜
[[NIMAVChatSDK sharedSDK].netCallManager selectBeautifyType:NIMNetCallFilterTypeZiran];

设置磨皮强度

设置磨皮强度

@protocol NIMNetCallManager <NSObject>
/**
 设置磨皮滤镜强度,支持自然 粉嫩 怀旧 黑白模式

 @param value 强度 [0-1] 默认为 0
 */
- (void)setSmoothFilterIntensity:(float)value;
@end
参数 类型 说明
value float 强度 [0-1] 默认为 0
//进行磨皮 磨破强度选择0.5
[[NIMAVChatSDK sharedSDK].netCallManager setSmoothFilterIntensity:0.5];

设置对比度强度

设置对比度强度

@protocol NIMNetCallManager <NSObject>
/**
 设置对比度滤镜强度,支持自然 粉嫩 怀旧 黑白模式

 @param value 强度 [0-4] 默认为 1
 */

- (void)setContrastFilterIntensity:(float)value;
@end
参数 类型 说明
value float 强度 [0-4] 默认为 1
//选择设置对比度 对比度强度选择2
[[NIMAVChatSDK sharedSDK].netCallManager setContrastFilterIntensity:2];

设置视频预览镜像

设置视频预览镜像

@protocol NIMNetCallManager <NSObject>
/**
 设置预览镜像

 @param isMirrorOn  是否开启预览镜像
 */
- (void)setPreViewMirror:(BOOL)isMirrorOn;
@end
参数 类型 说明
isMirrorOn BOOL 是否开启预览镜像
//开启预览镜像
[[NIMAVChatSDK sharedSDK].netCallManager setPreViewMirror:on];

设置视频编码镜像

设置视频编码镜像

@protocol NIMNetCallManager <NSObject>
/**
 设置编码镜像

 @param isMirrorOn  是否开启编码镜像
 */
- (void)setCodeMirror:(BOOL)isMirrorOn;
@end
参数 类型 说明
isMirrorOn BOOL 是否开启编码镜像
//开启编码镜像
[[NIMAVChatSDK sharedSDK].netCallManager setCodeMirror:on];

设置静态水印

设置静态水印

@protocol NIMNetCallManager <NSObject>
/**
 添加静态水印

 @param image  水印图片

 @param rect   水印具体位置和大小(x,y根据location位置,计算具体的位置信息)

 @param location  水印位置
 */
- (void)addWaterMark:(UIImage *)image
                rect:(CGRect)rect
            location:(NIMNetCallWaterMarkLocation)location;
@end
参数 类型 说明
image UIImage 水印图片
rect CGRect 水印具体位置和大小(x,y根据location位置,计算具体的位置信息)
location NIMNetCallWaterMarkLocation 水印位置
//获取 image 水印图片
UIImage *image = [UIImage imageNamed:@"icon_waterMark"];

//位置为右上 在预览画面的右上角
NIMNetCallWaterMarkLocation location = NIMNetCallWaterMarkLocationRightUp;

//设置水印具体位置 由于水印位置为右上 所以相对于右上角(以右上角为原点) 向下10像素 向左10像素 图片宽50像素 高50像素
CGRect rect = CGRectMake(10, 10, 50, 50);

//先清除当前水印
[[NIMAVChatSDK sharedSDK].netCallManager cleanWaterMark];

//添加静态水印
[[NIMAVChatSDK sharedSDK].netCallManager addWaterMark:image rect:rect location: location];

设置动态水印

设置动态水印

@protocol NIMNetCallManager <NSObject>
/**
 添加动态水印

 @param imageArray 动态图像数组

 @param count 播放速度的快慢:count代表count帧显示同一张图

 @param looped 是否循环,不循环就显示一次

 @param rect 具体位置和大小(x,y根据location位置,计算具体的位置信息)

 @param location 位置
 */
- (void)addDynamicWaterMarks:(NSArray*)imageArray
                    fpsCount:(unsigned int)count
                        loop:(BOOL)looped
                        rect:(CGRect)rect
                    location:(NIMNetCallWaterMarkLocation)location;
@end
参数 类型 说明
imageArray NSArray 动态图像数组
count unsigned int 播放速度的快慢
looped BOOL 是否循环,不循环就显示一次)
rect CGRect 具体位置和大小(x,y根据location位置,计算具体的位置信息)
location NIMNetCallWaterMarkLocation 水印位置
//创建图像数组
NSMutableArray *array = [NSMutableArray array];
for (NSInteger i = 0; i < 23; i++) {
    NSString *str = [NSString stringWithFormat:@"水印_%ld.png",(long)i];
    UIImage* image = [UIImage imageNamed:[[[NSBundle mainBundle] bundlePath]stringByAppendingPathComponent:str]];
    [array addObject:image];
}

//位置为右上 在预览画面的右上角
NIMNetCallWaterMarkLocation location = NIMNetCallWaterMarkLocationRightUp;

//设置水印具体位置 由于水印位置为右上 所以相对于右上角(以右上角为原点) 向下10像素 向左10像素 图片宽50像素 高50像素
CGRect rect = CGRectMake(10, 10, 50, 50);

//先清除当前水印
[[NIMAVChatSDK sharedSDK].netCallManager cleanWaterMark];

//添加动态水印
[[NIMAVChatSDK sharedSDK].netCallManager addDynamicWaterMarks:array fpsCount:4 loop:YES rect:rect location:location];

清除水印

清除水印

@protocol NIMNetCallManager <NSObject>
/**
 *  清除水印
 */
- (void)cleanWaterMark;
@end
//清除水印
[[NIMAVChatSDK sharedSDK].netCallManager cleanWaterMark];