本文详细说明iOS端推流SDK接口、SDK的基本使用流程以及相关功能的使用示例。
功能特性
支持RTMP推流协议。
支持基于RTC的RTS超低延时直播推拉流协议。
支持连麦互动和PK互动。
使用视频H.264编码以及音频AAC编码。
支持码控、分辨率、显示模式等自定义配置。
支持多种摄像头相关操作。
支持实时美颜和自定义美颜效果调节。
支持增、删动态贴纸实现动态水印效果。
支持录屏直播。
支持自定义YUV、PCM等外部音视频输入。
支持多路混流功能。
支持纯音视频推流以及后台推流。
支持背景音乐及其相关操作。
支持视频截图功能。
支持自动重连、异常处理。
支持音频3A算法。
增加视频软编、硬编切换逻辑,提升编码模块稳定性。
功能限制
使用iOS推流SDK需注意以下限制:
您只能在推流之前设置横竖屏模式,不支持在直播的过程中实时切换。
在推流设定为横屏模式时,需设定界面为不允许自动旋转。
在硬编模式下,考虑编码器兼容问题分辨率会使用16的倍数,如设定为540P,则输出的分辨率为544*960,在设置播放器视图大小时需按输出分辨率等比缩放,避免黑边等问题。
使用流程
基本使用流程如下:
功能使用
注册SDK
申请并配置License请参见License集成指南。
在使用推流功能之前,需要先进行注册,否则将无法使用推流SDK功能。
请在较早的位置(使用推流SDK前)调用注册License接口。
[AlivcLiveBase registerSDK];
通过AlivcLiveBase类,可以设置日志级别、设置本地日志路径、获取SDK版本等。
在AlivcLiveBase#setObserver接口的onLicenceCheck方法,异步判断Licence是否配置成功。
配置推流参数
在需要使用推流器的ViewController中引用头文件#import <AlivcLivePusher/AlivcLivePusher.h>
。
基本推流配置对应参数都有默认值,建议采用默认值,即您可以进行简单初始化,不做配置。
AlivcLivePushConfig *config = [[AlivcLivePushConfig alloc] init];//初始化推流配置类,也可使用initWithResolution来初始化。
config.resolution = AlivcLivePushResolution540P;//默认为540P,最大支持720P
config.fps = AlivcLivePushFPS20; //建议用户使用20fps
config.enableAutoBitrate = true; // 打开码率控制,默认为true
config.videoEncodeGop = AlivcLivePushVideoEncodeGOP_2;//默认值为2,关键帧间隔越大,延时越高。建议设置为1-2。
config.connectRetryInterval = 2000; // 单位为毫秒,重连时长2s,重连间隔设置不小于1秒,建议使用默认值即可。
config.previewMirror = false; // 默认为false,正常情况下都选择false即可。
config.orientation = AlivcLivePushOrientationPortrait; // 默认为竖屏,可设置home键向左或向右横屏。
综合手机性能和网络带宽要求,建议您将分辨率设置为540P(主流移动直播App基本都采用540P)。
关闭码率控制后,码率将固定在初始码率,不会在设定的目标码率和最小码率之间自适应调整。如果网络情况不稳定,可能造成播放卡顿,请慎用。
推流(摄像头推流)
初始化。
在配置好推流参数后,可以使用推流SDK的initWithConfig方法进行初始化。示例代码如下:
self.livePusher = [[AlivcLivePusher alloc] initWithConfig:config];
AlivcLivePusher目前不支持多实例,所以一个init必须对应有一个destroy。
注册推流回调。
推流回调分为三种:
Info:主要做提示和状态检测使用。
Error:错误回调。
Network:主要为网络相关。
注册delegate可接收对应的回调。示例代码如下:
[self.livePusher setInfoDelegate:self]; [self.livePusher setErrorDelegate:self]; [self.livePusher setNetworkDelegate:self];
开始预览。
livePusher对象初始化完成之后,可以进行开始预览操作。预览时需要传入摄像头预览的显示view(继承自UIView)。示例代码如下:
[self.livePusher startPreview:self.view];
开始推流。
预览成功后才可以开始推流,因此需监听AlivcLivePusherInfoDelegate的onPreviewStarted回调,在回调里面添加如下代码。
[self.livePusher startPushWithURL:@"推流测试地址(rtmp://......)"];
推流地址支持RTMP和超低延时直播RTS(artc://)推流地址,地址获取可参见生成推流地址和播放地址。
阿里云视频直播暂不支持同一时间向同一个推流URL进行多路推流(第二路推流会被拒绝)。
摄像头相关操作
您只能在开始预览之后调用摄像头相关操作,包括推流状态、暂停状态、重连状态等,可操作摄像头切换、闪光灯、焦距、变焦和镜像设置等。未开始预览状态下调用如下接口无效。示例代码如下:
/*切换前后摄像头*/
[self.livePusher switchCamera];
/*开启/关闭闪光灯,在前置摄像头时开启闪关灯无效*/
[self.livePusher setFlash:false];
/*焦距调整,即可实现采集画面的缩放功能。传入参数为正数,则放大焦距,传入参数为负数则缩小焦距。*/
CGFloat max = [_livePusher getMaxZoom];
[self.livePusher setZoom:MIN(1.0, max)];
/*手动对焦。手动聚焦需要传入两个参数:1.point 对焦的点(需要对焦的点的坐标);2.autoFocus 是否需要自动对焦,该参数仅对调用接口的该次对焦操作生效。后续是否自动对 焦沿用上述自动聚焦接口设置值。*/
[self.livePusher focusCameraAtAdjustedPoint:CGPointMake(50, 50) autoFocus:true];
/*设置是否自动对焦*/
[self.livePusher setAutoFocus:false];
/*镜像设置。镜像相关接口有两个,PushMirror推流镜像和PreviewMirror预览镜像。PushMirror设置仅对播放画面生效,PreviewMirror仅对预览画面生效,两者互不影响。*/
[self.livePusher setPushMirror:false];
[self.livePusher setPreviewMirror:false];
推流控制
推流控制主要包括开始推流、停止推流、停止预览、重新推流、暂停摄像头推流、恢复推流、销毁推流等操作,用户可以根据业务需求添加按钮进行操作。示例代码如下:
/*用户可以设置pauseImage后调用pause接口,从摄像头推流切换成静态图片推流,音频推流继续。*/
[self.livePusher pause];
/*从静态图片推流切换成摄像头推流,音频推流继续。*/
[self.livePusher resume];
/*推流状态下可调用停止推流,完成后推流停止。*/
[self.livePusher stopPush];
/*在预览状态下才可以调用停止预览,正在推流状态下,调用停止预览无效。预览停止后,预览画面定格在最后一帧。*/
[self.livePusher stopPreview];
/*推流状态下或者接收到所有Error相关回调状态下可调用重新推流,且Error状态下只可以调用此接口(或者reconnectPushAsync重连)或者调用destory销毁推流。完成后重新开始推流,重启ALivcLivePusher内部的一切资源,包括预览、推流等等restart。*/
[self.livePusher restartPush];
/*推流状态下或者接收到AlivcLivePusherNetworkDelegate相关的Error回调状态下可调用此接口, 且Error状态下只可以调用此接口(或者restartPush重新推流)或者调用destory销毁推流。完成后推流重连,重新链接推流RTMP。*/
[self.livePusher reconnectPushAsync];
/*销毁推流后,推流停止,预览停止,预览画面移除。AlivcLivePusher相关的一切资源销毁。*/
[self.livePusher destory];
self.livePusher = nil;
/*获取推流状态。*/
AlivcLivePushStatus status = [self.livePusher getLiveStatus];
录屏推流(屏幕共享推流)
ReplayKit是iOS 9引入的支持屏幕录制功能。iOS 10在ReplayKit中新增了调用第三方App扩展来直播屏幕内容的功能。在iOS 10及以上系统中,使用推流SDK配合Extension录屏进程,可以实现录屏直播。
iOS为了保证系统运行流畅,给Extension录屏进程的资源相对较少,Extension录屏进程内存占用过大会被系统强杀退出。为了解决Extension录屏进程内存限制,推流SDK将录屏推流分成Extension录屏进程(Extension App)和主App进程(Host App)。Extension录屏进程负责抓取屏幕内容,并通过进程间通信将屏幕内容发送给主App进程。主App进程创建推流引擎AlivcLivePusher,并将屏幕数据推送到远端。由于在主App进程中完成整个推流过程,因此麦克风的采集和发送可以放到主App进程中进行,Extension录屏进程只负责屏幕内容采集。
推流SDK Demo是通过App Group实现Extension录屏进程和主App进程之间的进程通信,并将该部分逻辑封装在了AlivcLibReplayKitExt.framework
中。
iOS上实现屏幕推流,Extension录屏进程由系统在录屏需要的时候创建,并负责接收系统采集到屏幕图像。需要如下对接操作步骤:
创建App Group。
需登录Apple Developer ,完成以下操作:
在Certificates, IDs & Profiles 页面中注册App Group,具体操作步骤可以参考注册App Group。
回到Identifier页面,选择App IDs,然后单击您的App ID(主App进程与Extension录屏进程的 App ID需要进行同样的配置)启用App Group功能。具体操作步骤可以参考启用App Group。
完成后重新下载对应的Provisioning Profile并配置到XCode中。
操作正确完成后Extension录屏进程可以和主App进程之间进行进程通信。
创建App Group完成后需保存App Group Identifier值,作为后续步骤的输入内容。
创建Extension录屏进程。
iOS推流SDK Demo中实现了支持录屏直播的App扩展AlivcLiveBroadcast和AlivcLiveBroadcastSetupUI。App中具体创建Extension录屏进程如下:
在现有工程选择
,选择Broadcast Upload Extension,如下图:
修改Product Name,勾选Include UI Extension,单击Finish创建直播扩展和直播UI,如下图:
配置直播扩展Info.plist,在新创建的Target中,Xcode会默认创建名为SampleHandler的头文件和源文件,如下图:
将
AlivcLibReplayKitExt.framework
拖到工程中,使得Extension Target依赖它。替换SampleHandler.m中的代码成如下代码(需将代码中的KAPP Group替换成上文第一步骤创建的App Group Identifier)。示例代码如下:
#import "SampleHandler.h" #import <AlivcLibReplayKitExt/AlivcLibReplayKitExt.h> @implementation SampleHandler - (void)broadcastStartedWithSetupInfo:(NSDictionary<NSString *,NSObject *> *)setupInfo { //User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional. [[AlivcReplayKitExt sharedInstance] setAppGroup:kAPPGROUP]; } - (void)processSampleBuffer:(CMSampleBufferRef)sampleBuffer withType:(RPSampleBufferType)sampleBufferType { if (sampleBufferType != RPSampleBufferTypeAudioMic) { //声音由主App进程采集发送 [[AlivcReplayKitExt sharedInstance] sendSampleBuffer:sampleBuffer withType:sampleBufferType]; } } - (void)broadcastFinished { [[AlivcReplayKitExt sharedInstance] finishBroadcast]; } @end
在您的工程中,完成创建Broadcast Upload Extension的Target,在该Extension Target中集成为录屏扩展模块定制的
AlivcLibReplayKitExt.framework
。在录屏推流主App进程中集成直播SDK。
在录屏推流主App进程中创建AlivcLivePushConfig、AlivcLivePusher对象,设置外置推流ExternMainStream为True,AudioFromExternal为False(该配置表示音频仍通过SDK内部采集),调用StartScreenCapture开始接收Extension App屏幕数据,开始和结束推流。具体可参考以下操作步骤:
录屏推流主App进程中加入AlivcLivePusher.framework、AlivcLibRtmp.framework、RtsSDK.framework和AlivcLibReplayKitExt.framework的依赖。
初始化推流SDK,配置使用外部视频源。
ExternMainStream设置为True,ExternVideoFormat设置为AlivcLivePushVideoFormatYUV420P,音频使用内部SDK采集AudioFromExternal设置为False,配置其他推流参数,请参见示例代码如下:
self.pushConfig.externMainStream = true; self.pushConfig.externVideoFormat = AlivcLivePushVideoFormatYUV420P; self.pushConfig.audioSampleRate = 44100; self.pushConfig.audioChannel = 2; self.pushConfig.audioFromExternal = false; self.pushConfig.videoEncoderMode = AlivcLivePushVideoEncoderModeSoft; self.pushConfig.qualityMode = AlivcLivePushQualityModeCustom; self.pushConfig.targetVideoBitrate = 2500; self.pushConfig.minVideoBitrate = 2000; self.pushConfig.initialVideoBitrate = 2000; self.livePusher = [[AlivcLivePusher alloc] initWithConfig:self.pushConfig];
使用AlivcLivePusher来完成直播相关功能,调用如下函数:
开始接收录屏数据。
需将代码中的
kAPPGroup
替换成上文创建的App Group Identifier
,示例代码如下:[self.livePusher startScreenCapture:kAPPGROUP];
开始推流。
示例代码如下:
[self.livePusher startPushWithURL:self.pushUrl]
结束推流。
示例代码如下:
[self.livePusher stopPush]; [self.livePusher destory]; self.livePusher = nil;
预览显示模式
推流SDK支持三种预览模式,预览显示模式不影响推流。
ALIVC_LIVE_PUSHER_PREVIEW_SCALE_FILL :预览显示时,铺满窗口。当视频比例和窗口比例不一致时,预览会有变形。
ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FIT:预览显示时,保持视频比例。当视频比例与窗口比例不一致时,预览会有黑边。(默认)
ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FILL:预览显示时,剪切视频以适配窗口比例。当视频比例和窗口比例不一致时,预览会裁剪视频。
示例代码如下:
mAlivcLivePushConfig.setPreviewDisplayMode(AlivcPreviewDisplayMode.ALIVC_LIVE_PUSHER_PREVIEW_ASPECT_FIT);
三种模式可以在AlivcLivePushConfig中设置,也可以在预览中和推流中通过API setpreviewDisplayMode进行动态设置。
本设置只对预览显示生效,实际推出的视频流的分辨率和AlivcLivePushConfig中预设置的分辨率一致,并不会因为更改预览显示模式而变化。预览显示模式是为了适配不同尺寸的手机,您可以自由选择预览效果。
图片推流
为了更好的用户体验,SDK提供了后台图片推流和码率过低时进行图片推流的设置。当SDK退至后台时默认暂停推流视频,只推流音频,此时可以设置图片来进行图片推流。例如,在图片上提醒用户主播离开片刻,稍后回来。示例代码如下:
config.pauseImg = [UIImage imageNamed:@"图片.png"];//设置用户后台推流的图片
另外,当网络较差时您可以根据自己的需求设置推流一张静态图片。设置图片后,SDK检测到当前码率较低时,会推流此图片,避免视频流卡顿。示例代码如下:
config.networkPoorImg = [UIImage imageNamed:@"图片.png"];//设置网络较差时推流
推送外部音视频流
推流SDK支持将外部的音视频源输入进行推流,比如推送一个音视频文件。
在推流配置里面进行外部音视频输入配置。
插入外部视频数据。
插入音频数据。
示例代码如下:
config.externMainStream = true;//开启允许外部流输入
config.externVideoFormat = AlivcLivePushVideoFormatYUVNV21;//设置视频数据颜色格式定义,这里设置为YUVNV21,可根据需求设置为其他格式。
config.externAudioFormat = AlivcLivePushAudioFormatS16;//设置音频数据位深度格式,这里设置为S16,可根据需求设置为其他格式
示例代码如下:
/*只支持外部视频yuv和rbg格式的连续buffer数据,才可以通过sendVideoData接口,发送视频数据buffer、长度、宽高、时间戳、旋转角度*/
[self.livePusher sendVideoData:yuvData width:720 height:1280 size:dataSize pts:nowTime rotation:0];
/*如果外部视频数据是CMSampleBufferRef格式,可以使用sendVideoSampleBuffer接口*/
[self.livePusher sendVideoSampleBuffer:sampleBuffer]
/*也可以将 CMSampleBufferRef格式转化为连续buffer后再传递给sendVideoData接口, 以下为转换的参考代码*/
//获取samplebuffer长度
- (int) getVideoSampleBufferSize:(CMSampleBufferRef)sampleBuffer {
if(!sampleBuffer) {
return 0;
}
int size = 0;
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
if(CVPixelBufferIsPlanar(pixelBuffer)) {
int count = (int)CVPixelBufferGetPlaneCount(pixelBuffer);
for(int i=0; i<count; i++) {
int height = (int)CVPixelBufferGetHeightOfPlane(pixelBuffer,i);
int stride = (int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer,i);
size += stride*height;
}
}else {
int height = (int)CVPixelBufferGetHeight(pixelBuffer);
int stride = (int)CVPixelBufferGetBytesPerRow(pixelBuffer);
size += stride*height;
}
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
return size;
}
//将samplebuffer转化为连续buffer
- (int) convertVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer toNativeBuffer:(void*)nativeBuffer
{
if(!sampleBuffer || !nativeBuffer) {
return -1;
}
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
int size = 0;
if(CVPixelBufferIsPlanar(pixelBuffer)) {
int count = (int)CVPixelBufferGetPlaneCount(pixelBuffer);
for(int i=0; i<count; i++) {
int height = (int)CVPixelBufferGetHeightOfPlane(pixelBuffer,i);
int stride = (int)CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer,i);
void *buffer = CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, i);
int8_t *dstPos = (int8_t*)nativeBuffer + size;
memcpy(dstPos, buffer, stride*height);
size += stride*height;
}
}else {
int height = (int)CVPixelBufferGetHeight(pixelBuffer);
int stride = (int)CVPixelBufferGetBytesPerRow(pixelBuffer);
void *buffer = CVPixelBufferGetBaseAddress(pixelBuffer);
size += stride*height;
memcpy(nativeBuffer, buffer, size);
}
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
return 0;
}
示例代码如下:
/*只支持外部pcm格式的连续buffer数据,sendPCMData,发送音频数据buffer、长度、时间戳*/
[self.livePusher sendPCMData:pcmData size:size pts:nowTime];
配置水印
推流SDK提供了添加水印功能,并且最多支持添加多个水印,水印图片必须为PNG格式图片。示例代码如下:
NSString *watermarkBundlePath = [[NSBundle mainBundle] pathForResource:
[NSString stringWithFormat:@"watermark"] ofType:@"png"];//设置水印图片路径
[config addWatermarkWithPath: watermarkBundlePath
watermarkCoordX:0.1
watermarkCoordY:0.1
watermarkWidth:0.3];//添加水印
coordX、coordY、width为相对值,例如watermarkCoordX:0.1表示水印的x值为推流画面x轴的10%位置,如果推流分辨率为540*960,则水印x值为54。
水印图片的高度,按照水印图片的真实宽高与输入的width值等比缩放。
要实现文字水印,可以先将文字转换为图片,再使用此接口添加水印。
为了保障水印显示的清晰度与边缘平滑,请您尽量使用和水印输出尺寸相同大小的水印源图片。如输出视频分辨率544*940,水印显示的w是0.1f,则尽量使用水印源图片宽度在544*0.1f=54.4左右。
设置视频质量
视频质量支持三种模式:清晰度优先模式,流畅度优先模式,自定义模式。
设置视频质量需要开启码率控制:config.enableAutoBitrate = true;
清晰度优先模式(默认)
清晰度优先模式下,SDK内部会对码率参数进行配置,优先保障推流视频的清晰度。
config.qualityMode = AlivcLivePushQualityModeResolutionFirst;//清晰度优先模式
流畅度优先模式
流畅度优先模式下,SDK内部会对码率参数进行配置,优先保障推流视频的流畅度。
config.qualityMode = AlivcLivePushQualityModeFluencyFirst;//流畅度优先模式
自定义模式
自定义模式下,SDK会根据开发者设置的码率进行配置。设置为自定义模式时,需要自己定义初始码率、最小码率和目标码率。
初始码率:开始直播时的码率。
最小码率:当网络较差时,码率会逐步减低到最小码率,以减少视频的卡顿。
目标码率:当网络较好时,码率会逐步提高到目标码率,以提高视频清晰度。
config.qualityMode = AlivcLivePushQualityModeCustom//设置为自定义模式
config.targetVideoBitrate = 1400; //目标码率1400kbps
config.minVideoBitrate = 600; //最小码率600kbps
config.initialVideoBitrate = 1000; //初始码率1000kbps
设置自定义码率时,请参考阿里云推荐设置配置对应码率。推荐设置请参考下表内容:
表 1. 自定义码率控制推荐设置(画质优先)
分辨率 | 初始码率 initialVideoBitrate | 最小码率 minVideoBitrate | 目标码率 targetVideoBitrate |
360P | 600 | 300 | 1000 |
480P | 800 | 300 | 1200 |
540P | 1000 | 600 | 1400 |
720P | 1500 | 600 | 2000 |
1080P | 1800 | 1200 | 2500 |
表 2. 自定义码率控制推荐设置(流畅度优先)
分辨率 | 初始码率 initialVideoBitrate | 最小码率 minVideoBitrate | 目标码率 targetVideoBitrate |
360P | 400 | 200 | 600 |
480P | 600 | 300 | 800 |
540P | 800 | 300 | 1000 |
720P | 1000 | 300 | 1200 |
1080P | 1500 | 1200 | 2200 |
分辨率自适应
开启动态调整推流分辨率功能后,当网络较差时会自动降低分辨率以提高视频的流畅度和清晰度。示例代码如下:
config.enableAutoResolution = YES; // 打开分辨率自适应,默认为NO
分辨率自适应只有在视频质量模式为清晰度优先或流畅度优先时才会生效,自定义模式时无效。
某些播放器可能不支持动态分辨率,如果您需要使用分辨率自适应功能,建议使用阿里云播放器。
背景音乐
推流SDK提供了背景音乐播放、混音、降噪、耳返、静音等功能,背景音乐相关接口在开始预览之后才可调用。示例代码如下:
/*开始播放背景音乐。*/
[self.livePusher startBGMWithMusicPathAsync:musicPath];
/*停止播放背景音乐。若当前正在播放BGM,并且需要切换歌曲,只需要调用开始播放背景音乐接口即可,无需停止当前正在播放的背景音乐。*/
[self.livePusher stopBGMAsync];
/*暂停播放背景音乐,背景音乐开始播放后才可调用此接口。*/
[self.livePusher pauseBGM];
/*恢复播放背景音乐,背景音乐暂停状态下才可调用此接口。*/
[self.livePusher resumeBGM];
/*开启循环播放音乐*/
[self.livePusher setBGMLoop:true];
/*设置降噪开关。打开降噪后,将对采集到的声音中非人声的部分进行过滤处理。可能存在对人声稍微抑制作用,建议让用户自由选择是否开启降噪功能,默认不使用*/
[self.livePusher setAudioDenoise:true];
/*设置耳返开关。耳返功能主要应用于KTV场景。打开耳返后,插入耳机将在耳机中听到主播说话声音。关闭后,插入耳机无法听到人声。未插入耳机的情况下,耳返不起作用。*/
[self.livePusher setBGMEarsBack:true];
/*混音设置,提供背景音乐和人声采集音量调整。*/
[self.livePusher setBGMVolume:50];//设置背景音乐音量
[self.livePusher setCaptureVolume:50];//设置人声采集音量
/*设置静音。静音后音乐声音和人声输入都会静音。要单独设置音乐或人声静音可以通过混音音量设置接口来调整。*/
[self.livePusher setMute:isMute?true:false];
推流截图
推流SDK提供了本地视频流截图功能,示例代码如下:
/*设置截图回调*/
[self.livePushersetSnapshotDelegate:self];
/*调用截图API*/
[self.livePushersnapshot:1interval:1];
配置美颜功能
阿里云推流SDK提供两种美颜模式:基础美颜和高级美颜。基础美颜支持美白、磨皮和红润。高级美颜支持基于面部识别的美白、磨皮、红润、大眼、小脸、瘦脸等功能。此功能由美颜特效SDK提供,使用示例代码如下:
#pragma mark - "美颜类型和美颜参数API"/**
* @brief 打开或者关闭某个美颜类型
* @param type QueenBeautyType 类型的一个值
* @param isOpen YES: 打开,NO:关闭
*
*/
- (void)setQueenBeautyType:(kQueenBeautyType)type enable:(BOOL)isOpen;
/**
* @brief 设置美颜参数
* @param param 美颜参数类型,QueenBeautyParams中的一个
* @param value 需要设置的数值,值的范围都是[0,1],小于0的置0,大于1的置1
*/
- (void)setQueenBeautyParams:(kQueenBeautyParams)param
value:(float)value;
#pragma mark - "滤镜相关API"
/**
* @brief 设置滤镜图片,设置滤镜图片前需要将kQueenBeautyTypeLUT打开
* @param imagePath 所要设置的滤镜图片的地址
*/
- (void)setLutImagePath:(NSString *)imagePath;
#pragma mark - "美型相关API"
/**
*@brief 设置美型类型,设置前需要将kQueenBeautyTypeFaceShape打开
*@param faceShapeType 需要设置美型的类型,参考QueenBeautyFaceShapeType
*@param value 需要设置的值
*/
- (void)setFaceShape:(kQueenBeautyFaceShapeType)faceShapeType
value:(float)value;
#pragma mark - "美妆相关api"
/**
* @brief 设置美妆类型和图片素材路径,设置美妆需要将kQueenBeautyTypeMakeup打开
* @param makeupType 美妆类型
* @param imagePaths 美妆素材地址集合
* @param blend 混合类型
*/
- (void)setMakeupWithType:(kQueenBeautyMakeupType)makeupType
paths:(NSArray<NSString *> *)imagePaths
blendType:(kQueenBeautyBlend)blend;
/**
* @brief 设置美妆类型和图片素材路径
* @param makeupType 美妆类型
* @param imagePaths 美妆素材地址集合
* @param blend 混合类型
* @param fps 对应的帧率
*/
- (void)setMakeupWithType:(kQueenBeautyMakeupType)makeupType
paths:(NSArray<NSString *> *)imagePaths
blendType:(kQueenBeautyBlend)blend fps:(int)fps;
/**
* @brief 设置美妆透明度,可指定性别
* @param makeupType 美妆类型
* @param isFeMale 是否是女性,女性:YES,男性:NO
* @param alpha 妆容透明度
*/
- (void)setMakeupAlphaWithType:(kQueenBeautyMakeupType)makeupType
female:(BOOL)isFeMale alpha:(float)alpha;
/**
* @brief 设置美妆类型的混合类型
* @param makeupType 美妆类型
* @param blend 混合类型
*/
- (void)setMakeupBlendWithType:(kQueenBeautyMakeupType)makeupType
blendType:(kQueenBeautyBlend)blend;
/**
* @brief 清除所有美妆
*/
- (void)resetAllMakeupType;
实时调整美颜参数
推流SDK支持在推流时实时调整美颜参数,开启美颜开关,分别调整对应的参数值,示例代码如下:
[_queenEngine setQueenBeautyType:kQueenBeautyTypeSkinBuffing enable:YES];
[_queenEngine setQueenBeautyType:kQueenBeautyTypeSkinWhiting enable:YES];
[_queenEngine setQueenBeautyParams:kQueenBeautyParamsWhitening value:0.8f];
[_queenEngine setQueenBeautyParams:kQueenBeautyParamsSharpen value:0.6f];
[_queenEngine setQueenBeautyParams:kQueenBeautyParamsSkinBuffing value:0.6];
配置直播答题功能
直播答题功能可以通过在直播流里面插入SEI信息,播放器解析SEI来实现。在推流SDK里面提供了插入SEI的接口,在推流状态下,才能调用此接口。示例代码如下:
/*
msg: 需要插入流的SEI消息体,建议是JSON格式。阿里云播放器SDK可收到此SEI消息,解析后做具体展示。
repeatCount:发送的帧数。为了保证SEI不被丢帧,需设置重复次数,如设置100,则在接下去的100帧均插入此SEI消息。播放器会对相同的SEI进行去重处理。
delayTime:延时多少毫秒发送。
KeyFrameOnly:是否只发关键帧。
*/
[self.livePusher sendMessage:@"题目信息" repeatCount:100 delayTime:0 KeyFrameOnly:false];
iPhoneX适配
一般场景下,预览view的frame设置为全屏可以正常预览,由于iPhoneX屏幕比例的特殊性,所以iPhoneX下预览view设置为全屏大小会有画面拉伸的现象。建议iPhoneX不要使用全屏大小的view来预览。
推流过程中改变view的大小
请遍历您在调用startPreview或者startPreviewAsync接口时赋值的UIView。更改预览view的所有subView的frame。例如:
[self.livePusher startPreviewAsync:self.previewView];
for (UIView *subView in [self.previewView subviews]) {
// ...
}
播放外部音效
如果您需要在推流页播放音效音乐等,由于SDK暂时与AudioServicesPlaySystemSound有冲突,建议您使用AVAudioPlayer,并且在播放后需要更新设置AVAudioSession、AVAudioPlayer播放音效示例代码:
- (void)setupAudioPlayer {
NSString *filePath = [[NSBundle
mainBundle] pathForResource:@"sound" ofType:@"wav"];
NSURL *fileUrl = [NSURL URLWithString:filePath];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:nil];
self.player.volume = 1.0;
[self.player prepareToPlay];
}
- (void)playAudio {
self.player.volume = 1.0;
[self.player play];
// 配置AVAudioSession
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setMode:AVAudioSessionModeVideoChat error:nil];
[session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker|AVAudioSessionCategoryOptionAllowBluetooth
| AVAudioSessionCategoryOptionMixWithOthers error:nil];
[session setActive:YES error:nil];
}
退后台和接听电话
SDK内部已经做好退后台相关处理,无需您做操作。退入后台SDK默认继续推流音频,视频保留在最后一帧。您需要在App的Capabilities中打开Background Mode选项,选中Audio,AirPlay and Picture in Picture。保证App退后台可以正常采集音频。如图:
如果退后台时不需要保持音频推流,即退入后台停止推流且返回前台继续推流,您可以在退后台时将推流引擎销毁,在前台后重新创建推流引擎继续推流。
在此方式下,退后台必须监听UIApplicationWillResignActiveNotification和UIApplicationDidBecomeActiveNotification,其他方式存在风险。
回调监听
推流SDK主要包含以下回调:
回调类型 | 回调类名 |
回调类型 | 回调类名 |
AlivcLivePusherInfoDelegate | |
AlivcLivePusherNetworkDelegate | |
AlivcLivePusherErrorDelegate | |
AlivcLivePusherBGMDelegate | |
AlivcLivePusherCustomFilterDelegate |
推流回调
推流回调用于向App通知SDK相应状态,包括预览开始、渲染第一帧视频、发送第一帧音视频流、推流开始、推流停止等回调。
onPushStarted:表示连接服务端成功。
onFirstFramePushed:表示发送第一帧音视频流成功。
onPushStarted、onFirstFramePushed:表示SDK推流成功。
网络相关回调
网络相关回调用于向App通知SDK相应网络状态和链接状态。短时间的网络波动或者网络切换,时长在AlivcLivePushConfig设置的重连超时时长和次数范围之内,SDK会进行自动重连,重连成功之后将继续推流。
基础模式:基础直播场景
onConnectFail:表示推流失败,建议检查推流地址是否非法、是否存在非法字符、鉴权是否有问题、是否超过最大推流并发限制、是否在禁推黑名单中等,确定推流地址合法且可用后再尝试推流。其中具体错误码有0x30020901 ~ 0x30020905, 0x30010900 ~ 0x30010901。
onConnectionLost:链接断开回调,链接断开后SDK内部会自动重连,回抛onReconnectStart,如果超过最大重连次数(config.connectRetryCount)后推流链接还是没有恢复,会回抛onReconnectError。
onNetworkPoor:网络慢回调,当收到此回调说明当前网络对于推流的支撑度不足,此时推流仍在继续、没有中断。您可以在此处理自己的业务逻辑,比如UI提醒用户。
onNetworkRecovery:网络恢复回调。
onReconnectError:重连失败回调,表示重连失败,建议检查当前网络,待网络恢复时,重新推流。
onSendDataTimeout:送数据超时回调,建议检查当前网络,待网络恢复时,结束推流后重新开始推流。
onPushURLAuthenticationOverdue:鉴权过期回调,此回调表示当前推流URL鉴权过期,需要给SDK传递一个新的URL。
互动模式:直播连麦场景
onConnectFail:表示推流失败,建议检查连麦推流地址中token是否非法、网络是否异常等。确定推流地址合法且网络正常可用后再尝试推流。
onConnectionStatusChange:连接状态改变的回调,在该回调中会返回连接的相关状态,例如网络连接断开、建立网络连接中、网络已连接、网络连接失败等。当回调AliLiveConnectionStatusFailed状态时,表示链接无法恢复,建议检查当前网络,待网络恢复后重新推流。建议在互动模式下接入该回调,以获取连接相关状态。
onPushURLTokenWillExpire:连麦推流地址中的token即将过期。在token过期前30秒,会触发该回调。收到该回调后,应该及时向业务服务器请求带有新token的连麦推流地址,并通过refreshPushURLToken接口将新的token传入SDK。
onPushURLTokenExpired:连麦推流URL的token已经过期。该回调触发代表token鉴权信息已过期,需要在结束推流后使用新的token的URL重新推流。
onPusherNetworkQualityChanged:当前用户上行网络质量回调,当上行网络质量发生变化时,会回调当前上行网络质量评级。
onConnectionLost:链接断开回调,不同于基础模式,在互动模式下,当触发onConnectionLost回调时,表示连接无法恢复。建议检查当前网络情况,并在网络恢复后重新进行推流。
错误回调
onSystemError:系统设备异常回调,需要销毁引擎重新尝试。
onSDKError:SDK错误回调,需要根据错误码做不同的处理:
如果错误码是805438211,表示设备性能差,编码和渲染帧率过低,需要给主播提示,并在app层停掉处理耗时长的业务逻辑(比如高级美颜、动画等)。
您需要特别处理App没有麦克风权限和没有摄像头权限的回调,App没有麦克风权限错误码为268455940,App没有摄像头权限错误码为268455939。
其他的暂时都只打日志,不做其他额外操作。
背景音乐回调
onOpenFailed:背景音乐开启失败,检查背景音乐开始播放接口所传入的音乐路径与该音乐文件是否正确,可调用startBGMAsync重新播放。
onDownloadTimeout:背景音乐播放超时,多出现于播放网络URL的背景音乐,提示主播检查当前网络状态,可调用startBGMAsync重新播放。
外置美颜、滤镜处理相关回调
通过AlivcLivePusherCustomFilterDelegate回调来对接三方的美颜SDK,实现基础美颜和高级美颜的功能。AlivcLivePusherCustomFilterDelegate的主要作用是将SDK内部的纹理或CVPixelBuffer回调出来,供美颜SDK处理,并将处理后的纹理或CVPixelBuffer返回给SDK,从而实现美颜效果。
基础模式:基础直播场景
在基础模式下,AlivcLivePushConfig中的livePushMode开关设置为AlivcLivePushBasicMode。SDK通过AlivcLivePusherCustomFilterDelegate回调的是纹理ID,而不回调CVPixelBuffer。其核心回调如下:
onCreate:OpenGL上下文创建回调,通常用于在该回调里初始化美颜引擎。
onProcess:OpenGL纹理更新回调,该方法将回调SDK内部的原始纹理ID。在这个回调中,调用美颜处理方法,并将处理后的纹理ID返回。
onDestory:OpenGL上下文销毁回调,通常用于在该回调里销毁美颜引擎。
互动模式:直播连麦场景
在互动模式下,AlivcLivePushConfig中的livePushMode开关设置为AlivcLivePushInteractiveMode,SDK通过AlivcLivePusherCustomFilterDelegate可以回调CVPixelBuffer数据,也可以回调纹理ID,默认是回调CVPixelBuffer数据。
CVPixelBuffer回调
在互动模式下,SDK通过onProcessVideoSampleBuffer方法默认回调CVPixelBuffer数据。只需在该回调中将CVPixelBuffer数据送入美颜处理,然后将处理后的数据写回SDK。同时,将该方法的返回值设置为YES,即可实现美颜效果。若返回值为NO,则数据不会写回SDK,也就不会有美颜效果。在 CVPixelBuffer回调模式下,AlivcLivePusherCustomFilterDelegate中除了 onProcessVideoSampleBuffer方法,其他方法都不会被回调。
- (BOOL)onProcessVideoSampleBuffer:(AlivcLivePusher *)pusher sampleBuffer:(AlivcLiveVideoDataSample *)sampleBuffer { BOOL result = NO; if (self.beautyOn) { result = [[AlivcBeautyController sharedInstance] processPixelBuffer:sampleBuffer.pixelBuffer withPushOrientation:self.pushConfig.orientation]; } return result; }
纹理回调
在互动模式下,SDK默认会回调CVPixelBuffer数据。如果将AlivcLivePushConfig中的enableLocalVideoTexture变量开关设置为YES,则会回调纹理数据。在纹理数据回调模式下,SDK将会回调除了onProcessVideoSampleBuffer之外的其他方法。
onCreate:OpenGL上下文创建回调,通常用于在该回调里初始化美颜引擎。
onProcess:OpenGL纹理更新回调,该方法将回调SDK内部的原始纹理ID。在这个回调中,调用美颜处理方法,并将处理后的纹理ID返回。
onDestory:OpenGL上下文销毁回调,通常用于在该回调里销毁美颜引擎。
AlivcLivePusherCustomDetectorDelegate回调用于一些美颜SDK需要使用buffer来处理人脸识别算法,而并非所有美颜操作都需要。只有特定的美颜SDK需要使用buffer来进行人脸识别。在这种情况下,通过AlivcLivePusherCustomFilterDelegate回调纹理ID来进行美颜处理,而通过AlivcLivePusherCustomDetectorDelegate回调buffer来进行人脸识别。若将CVPixelBuffer回调传递给美颜SDK,则无需处理此回调。
如果美颜SDK需要使用buffer来处理人脸识别算法,应使用onDetectorProcess回调函数进行处理,该回调函数将返回buffer数据。在互动模式下,如果使用纹理回调且还需要buffer数据回调,需要打开AlivcLivePushConfig中的enableLocalVideoRawBuffer开关,以便触发onDetectorProcess的buffer数据回调。
常用方法和接口
/*在自定义模式下,用户可以实时调整最小码率和目标码率。*/
[self.livePusher setTargetVideoBitrate:800];
[self.livePusher setMinVideoBitrate:200]
/*获取是否正在推流的状态*/
BOOL isPushing = [self.livePusher isPushing];
/*获取推流地址*/
NSString *pushURLString = [self.livePusher getPushURL];
/*获取推流性能调试信息。推流性能参数具体参数和描述参考API文档或者接口注释。*/
AlivcLivePushStatsInfo *info = [self.livePusher getLivePushStatusInfo];
/*获取版本号。*/
NSString *sdkVersion = [self.livePusher getSDKVersion];
/*设置log级别,根据需求过滤想要的调试信息*/
[self.livePusher setLogLevel:(AlivcLivePushLogLevelDebug)];
调试工具
SDK提供UI调试工具DebugView。DebugView为可移动的全局悬浮窗,添加后始终悬浮在视图的最上层。内含推流日志查看、推流性能参数实时检测、推流主要性能折线图表等debug功能。
在您的release版本下,请勿调用添加DebugView的接口。
示例代码如下:
[AlivcLivePusher showDebugView];//打开调试工具
连麦互动(互动版)
直播推流SDK互动版V4.4.4及以上版本提供基于RTC的连麦互动能力,V4.4.5及以上版本提供基于RTC的连麦PK互动能力,用户可以使用推流SDK互动版本完成主播和连麦观众超低延时(300ms以内)互动,直播连麦相关的功能使用,请参见连麦互动开发指南和主播PK互动开发指南。
连麦互动暂不支持录屏推流。
API文档
常见问题
推流失败
您可以使用自助问题排查功能对推流地址进行检测,检测推流地址是否有效。
如何获取已推的音视频流信息
您可以进入流管理,在在线流中可查看并管理已推的音视频流。
如何进行播流
开始推流后,可用播放器(阿里云播放器、FFplay、VLC等)进行拉流测试,拉流地址获取请参见生成推流地址和播放地址。
提交App Store审核失败
RtsSDK提供全平台的库,如需提交App Store,需将模拟器架构去除。您可使用lipo -remove
去除x86_64架构即可。
- 本页导读 (1)
- 功能特性
- 功能限制
- 使用流程
- 功能使用
- 注册SDK
- 配置推流参数
- 推流(摄像头推流)
- 录屏推流(屏幕共享推流)
- 预览显示模式
- 图片推流
- 推送外部音视频流
- 配置水印
- 设置视频质量
- 分辨率自适应
- 背景音乐
- 推流截图
- 配置美颜功能
- 配置直播答题功能
- iPhoneX适配
- 推流过程中改变view的大小
- 播放外部音效
- 退后台和接听电话
- 回调监听
- 常用方法和接口
- 调试工具
- 连麦互动(互动版)
- API文档
- 常见问题