音视频前处理
本章节主要介绍网易云信提供的各种音视频前处理功能。前处理介于采集和编码之间,按照数据类型分类,可以分为音频前处理和视频前处理,音频前处理包括降噪、回音消除、人声检测、自动增益等等,视频前处理包括美颜、磨皮、设置对比度、镜像、水印等。网易云信移动端SDK中内置了基础款的美颜滤镜。 同时,网易云信还提供了音视频采集数据的回调功能,所以除了SDK自带的一些音视频的前处理功能,开发者可以利用音视频采集数据的回调功能,实现自定义的音视频数据前处理,包括接入第三方变声、美颜算法。
音频前处理
音频采集数据回调与发送
在加入多人会议或者互动直播房间时,在 meeting
的 option
参数中指定视频采集数据回调block audioHandler
,SDK 采集到的音频数据都会通过它回调给应用。audioHandler
的类型声明如下:
typedef NSUInteger(^NIMNetCallAudioSamplesHandler)(SInt16 *audioSamples, NSUInteger samplesNumber, Float64 sampleRate)
其中 audioSamples
是麦克风采集到的语音原始 PCM 采样数据,应用处理完的数据也需要通过该字段回填,回填的数据的采样点数通过该回调的返回值告知 SDK。
注意:回填数据采样点数不允许超过回调的数据采样点数;如果需要发送较多数据,可以在每次回调中发送最多 samplesNumber
个采样点数据。
建议异步地处理语音数据,并且在该回调中发送之前已经异步处理完的语音数据。
开启耳返
- API介绍
在通话过程中开启耳返,用户务必需要先自己判断是否有耳机连接,再开启耳返,SDK不负责判断。
- API原型
@protocol NIMNetCallManager <NSObject>
/**
打开耳返
*/
- (void)startEarBack;
@end
参数说明
无
示例
//若有耳机连接,开启耳返 需要自己判断是否有耳机连接
[[NIMAVChatSDK sharedSDK].netCallManager startEarBack];
关闭耳返
- API介绍
关闭耳返
- API原型
@protocol NIMNetCallManager <NSObject>
/**
关闭耳返
*/
- (void)stopEarBack;
@end
参数说明
无
示例
//关闭耳返
[[NIMAVChatSDK sharedSDK].netCallManager stopEarBack];
调节耳返音量
- API介绍
动态调节耳返音量。
- API原型
@protocol NIMNetCallManager <NSObject>
/**
调节耳返音量
@param volume 耳返音量 接受输入值为 0 到 10
@return 是否调节成功
*/
- (BOOL)changeEarBackVolume:(NSUInteger)volume;
@end
- 参数说明
参数 | 类型 | 说明 |
---|---|---|
volume | NSUInteger | 耳返音量 接受输入值为 0 到 10 |
- 示例
//调节耳返音量为5
[[NIMAVChatSDK sharedSDK].netCallManager changeEarBackVolume:5]
开始音频自定义输入
- API介绍
开始音频自定义输入
- API原型
/**
开始音频自定义输入
@param task 自定义输入任务
@return 结果 如果成功 返回 nil
*/
- (nullable NSError *)startAudioCustomInputTask:(NIMNetCallAudioCustomInputTask *)task;
- 参数说明
参数 | 类型 | 说明 |
---|---|---|
task | NIMNetCallAudioCustomInputTask | 自定义输入任务 |
- 示例
NIMNetCallAudioCustomInputTask *task = [[NIMNetCallAudioCustomInputTask alloc]init];
task.needPlay = needPlay;
task.needSend = needSend;
task.sampleRate = audioinfo.sample_rate;
[[NIMAVChatSDK sharedSDK].netCallManager startAudioCustomInputTask:task];
输入自定义音频数据
- API介绍
输入自定义音频数据,目前支持输入音频的pcm数据。
- API原型
/**
输入音频pcm数据
@param audioData 音频数据
@param size 音频数据大小 单位字节 不能超过半秒数据 计算方式(采样率 * (mBytesPerPacket / mFramesPerPacket) * 0.5秒)
@param sampleRate 采样率 需要与开始任务中的采样率一致
@return 结果 如果成功 返回 nil
@discussion 传入的音频数据格式(AudioStreamBasicDescription)需要符合
mFormatID = kAudioFormatLinearPCM;
mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
mFramesPerPacket = 1;//每个packet的中frame的个数
mChannelsPerFrame = 1;//声道数
mBitsPerChannel = 16;//每个采样数据的位数
mBytesPerPacket = 2;//每个packet中数据的字节数
内部不做校验(如果不符合可能会无声音或异常声音)
*/
- (nullable NSError *)inputAudioData:(SInt16 *)audioData
size:(UInt32)size
sampleRate:(Float64)sampleRate;
- 参数说明
参数 | 类型 | 说明 |
---|---|---|
audioData | SInt16* | 音频数据 |
size | UInt32 | 音频数据大小 单位字节 不能超过半秒数据 计算方式(采样率 (mBytesPerPacket / mFramesPerPacket) 0.5秒) |
sampleRate | Float64 | 采样率 |
- 示例
[[NIMAVChatSDK sharedSDK].netCallManager inputAudioData:(SInt16 *)audioRawData->usrData size:audioRawData->data_size sampleRate:audioRawData->samplerate];
结束音频自定义输入
- API介绍
结束音频自定义输入。
- API原型
/**
结束音频自定义输入
*/
- (void)stopAudioCustomInputTask;
参数说明
无
示例
[[NIMAVChatSDK sharedSDK].netCallManager stopAudioCustomInputTask];
视频前处理
视频采集数据回调
在开启视频采集时,在 NIMNetCallVideoCaptureParam
中指定视频采集数据回调 block videoHandler
,SDK 采集到的视频画面都会通过它回调给应用。videoHandler
的类型声明如下:
typedef void(^NIMNetCallVideoSampleBufferHandler)(CMSampleBufferRef sampleBuffer)
回调的 sampleBuffer
携带时间戳和 NIMNetCallVideoCaptureParam
中指定的格式的 CVPixelBuffer 图像。
需要同步处理图像数据,不再需要通过sendVideoSampleBuffer
的方式传入SDK。
- 示例
//视频采集数据回调
_videoParam.videoHandler =^(CMSampleBufferRef sampleBuffer){
//对采集数据进行外部前处理
//需要同步处理sampleBuffer
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
[[NTESCustomVideoProcessorManager sharedInstance] renderPixelBuffer:pixelBuffer];
};
然后再通过onLocalDisplayviewReady:
中的 view 进行绘制
特殊说明
1.若在视频采集数据回调中进行自定义前处理,需要在视频采集参数
NIMNetCallVideoCaptureParam
中指定前处理参数videoProcessorParam
(只需要初始化) 才能在本地看到自定义前处理的效果。2.不推荐在视频采集数据回调中调用 SDK 内部前处理功能(美颜,水印等),推荐在
videoProcessorParam
前处理参数中进行相关参数指定。
视频数据发送
- API介绍
视频数据发送至SDK 对视频数据进行前处理(如SDK美颜,水印)及发送。适用场景:自定义视频输入。
- API原型
@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 |
- 示例
//把 sampleBuffer 数据发送给 SDK 进行显示,编码,发送
[[NIMAVChatSDK sharedSDK].netCallManager sendVideoSampleBuffer:sampleBuffer];
- 特殊说明
注意:处理完的画面封装为 CMSampleBufferRef 时,需要填入回调时该画面对应的时间戳,否则对端的视频播放时序会被破坏。
注意:SDK 只接受 sampleBuffer 为封装了 kCVPixelFormatType_32BGRA、kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange 或者 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange 的 CVPixelBuffer 的视频画面发送。
对视频美颜
- API介绍
对视频美颜
- API原型
@protocol NIMNetCallManager <NSObject>
/**
选择滤镜类型
@param type 滤镜类型
*/
- (void)selectBeautifyType:(NIMNetCallFilterType)type;
@end
- 参数说明
参数 | 类型 | 说明 |
---|---|---|
type | NIMNetCallFilterType | 滤镜类型 |
- 示例
//选择自然模式进行美颜
[[NIMAVChatSDK sharedSDK].netCallManager selectBeautifyType:NIMNetCallFilterTypeZiran];
设置磨皮强度
- API介绍
设置磨皮强度
- API原型
@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];
设置对比度强度
- API介绍
设置对比度强度
- API原型
@protocol NIMNetCallManager <NSObject>
/**
设置对比度滤镜强度,支持自然 粉嫩 怀旧 黑白模式
@param value 强度 [0-4] 默认为 1
*/
- (void)setContrastFilterIntensity:(float)value;
@end
- 参数说明
参数 | 类型 | 说明 |
---|---|---|
value | float | 强度 [0-4] 默认为 1 |
- 示例
//选择设置对比度 对比度强度选择2
[[NIMAVChatSDK sharedSDK].netCallManager setContrastFilterIntensity:2];
设置视频预览镜像
- API介绍
设置视频预览镜像
- API原型
@protocol NIMNetCallManager <NSObject>
/**
设置预览镜像
@param isMirrorOn 是否开启预览镜像
*/
- (void)setPreViewMirror:(BOOL)isMirrorOn;
@end
- 参数说明
参数 | 类型 | 说明 |
---|---|---|
isMirrorOn | BOOL | 是否开启预览镜像 |
- 示例
//开启预览镜像
[[NIMAVChatSDK sharedSDK].netCallManager setPreViewMirror:on];
设置视频编码镜像
- API介绍
设置视频编码镜像
- API原型
@protocol NIMNetCallManager <NSObject>
/**
设置编码镜像
@param isMirrorOn 是否开启编码镜像
*/
- (void)setCodeMirror:(BOOL)isMirrorOn;
@end
- 参数说明
参数 | 类型 | 说明 |
---|---|---|
isMirrorOn | BOOL | 是否开启编码镜像 |
- 示例
//开启编码镜像
[[NIMAVChatSDK sharedSDK].netCallManager setCodeMirror:on];
设置静态水印
- API介绍
设置静态水印
- API原型
@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];
设置动态水印
- API介绍
设置动态水印
- API原型
@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];
清除水印
- API介绍
清除水印
- API原型
@protocol NIMNetCallManager <NSObject>
/**
* 清除水印
*/
- (void)cleanWaterMark;
@end
参数说明
无
示例
//清除水印
[[NIMAVChatSDK sharedSDK].netCallManager cleanWaterMark];