全部产品
Search
文档中心

视频直播:错误异常及特殊场景处理

更新时间:Jan 29, 2024

本文介绍使用iOS推流SDK可能出现的异常情况、特殊情况,及其处理办法。

异常与错误处理

推流SDK主要包含以下回调:

回调类型

回调类名

推流回调

AlivcLivePusherInfoDelegate

网络回调

AlivcLivePusherNetworkDelegate

错误回调

AlivcLivePusherErrorDelegate

背景音乐回调

AlivcLivePusherBGMDelegate

外置美颜、滤镜处理相关回调

AlivcLivePusherCustomFilterDelegate

推流回调

推流回调用于向App通知SDK相应状态,包括预览开始、渲染第一帧视频、发送第一帧音视频流、推流开始、推流停止等回调。

  • onPushStarted、onFirstFramePushed:表示SDK推流成功。

  • onPushStarted:表示连接服务端成功。

  • onFirstFramePushed:表示发送第一帧音视频流成功。

网络相关回调

网络相关回调用于向App通知SDK相应网络状态和链接状态,其中有一些回调是App必须要对接的。

基础模式:基础直播场景

  • onConnectFail:表示推流失败,建议检查推流地址是否非法、是否存在非法字符、鉴权是否有问题、是否超过最大推流并发限制、是否在禁推黑名单中等,确定推流地址合法且可用后再尝试推流。其中具体错误码有0x30020901 ~ 0x30020905, 0x30010900 ~ 0x30010901。

  • onConnectionLost:链接断开回调,链接断开后SDK内部会自动重连,回抛onReconnectStart,如果超过最大重连次数(config.connectRetryCount)后推流链接还是没有恢复,会回抛onReconnectError。

  • onNetworkPoor:网络慢回调,当收到此回调说明当前网络对于推流的支撑度不足,此时推流仍在继续、没有中断。您可以在此处理自己的业务逻辑,比如UI提醒用户。

  • onNetworkRecovery:网络恢复回调。

  • onReconnectError:重连失败回调,表示重连失败,建议检查当前网络,待网络恢复时,重新推流。

  • onSendDataTimeout:送数据超时回调,建议检查当前网络,待网络恢复时,结束推流后重新开始推流。

  • onPushURLAuthenticationOverdue:推流地址鉴权即将过期会回调,如果您的推流开启了推流鉴权功能(推流URL中带有auth_key),我们会对推流URL做出校验。在推流URL过期前约1min,您会收到此回调,实现该回调后,您需要回传一个新的推流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重新播放。

对接美颜SDK

通过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数据回调。

特殊场景处理

当网络中断时

  • 短时间断网和网络切换:即短时间的网络波动或者网络切换。一般情况下,中途断网时长在AlivcLivePushConfig设置的重连超时时长和次数范围之内,SDK会进行自动重连,重连成功之后将继续推流。若您使用阿里云播放器,建议播放器收到超时通知AliVcMediaPlayerPlaybackDidFinishNotification之后,短暂延时5s后再做重连操作。

  • 长时间断网:断网时长超出AlivcLivePushConfig设置的重连超时时长和次数范围时,SDK自动重连失败,此时会回调onReconnectError:error:,等到网络恢复之后调用reconnectAsync接口进行重连。同时播放器也要配合做重连操作。

    • 建议您在SDK外部做网络监测。

    • 主播端和播放端在客户端无法进行直接通信,需要配合服务端使用。比如主播端断网,服务端会收到CDN的推流中断回调,此时可以推送给播放端,主播推流中断,播放端再做出相应处理。恢复推流同理。

    • 阿里云播放器重连需要先停止播放再开始播放。调用接口顺序stop>prepare>play。

      [self.mediaPlayer stop];
      AliVcMovieErrorCode err = [self.mediaPlayer prepareToPlay:[NSURL URLWithString:@"播放地址"]];
      if(err != ALIVC_SUCCESS) {
       NSLog(@"play failed,error code is %d",(int)err);
       return;
      }
      [self.mediaPlayer play];
      说明

      关于播放器请参见阿里云播放器SDK使用说明

退后台和接听电话

SDK内部已经做好退后台相关处理,无需您做操作。退入后台SDK默认继续推流音频,视频保留在最后一帧。您需要在App的Capabilities中打开Background Mode选项,选中Audio,AirPlay and Picture in Picture。保证App退后台可以正常采集音频。如图:退后台和接听电话

如果退后台时不需要保持音频推流,即退入后台停止推流且返回前台继续推流,您可以在退后台时将推流引擎销毁,在前台后重新创建推流引擎继续推流。

说明

在此方式下,退后台必须监听UIApplicationWillResignActiveNotification和UIApplicationDidBecomeActiveNotification,其他方式存在风险。

播放外部音效

如果您需要在推流页播放音效音乐等,由于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];
}

推流过程中改变view的大小

请遍历您在调用startPreview或者startPreviewAsync接口时赋值的UIView。更改预览view的所有subView的frame。例如:

[self.livePusher startPreviewAsync:self.previewView];
for (UIView *subView in [self.previewView subviews]) {
 // ...
}

iPhoneX适配

一般场景下,预览view的frame设置为全屏可以正常预览,由于iPhoneX屏幕比例的特殊性,所以iPhoneX下预览view设置为全屏大小会有画面拉伸的现象。建议iPhoneX不要使用全屏大小的view来预览。

码率设置

SDK内部有动态变化码率策略,您可以在AlivcLivePushConfig中修改码率预设值。根据产品需求对于视频分辨率、视频流畅度、视频清晰度的要求不同,对应设置的码率范围也不同,具体参考如下:

  • 视频清晰度:推流码率越高,则视频清晰度越高,所以推流分辨率越大,所需要设置的码率也就越大,以保证视频清晰度。

  • 视频流畅度:推流码率越高,所需要的网络带宽越大,所以在较差的网络环境下,设置较高的码率有可能影响视频流畅度。

编译报错

当您收到Building for iOS, but the linked and embedded framework XXX.framework' was built for iOS + iOS Simulator编译报错时,请参见如下操作:

  1. 单击Xcode菜单。

  2. 选择File > Workspace Settings进入对话框设置。

  3. 选择将build System更改为Legacy build system即可。

当编译缺少Queen的依赖库时

手动集成的情况下,出现Queen缺少依赖库的情况时,可以参见Queen_SDK_iOS文档添加对应的依赖库。

提交App Store审核失败

RtsSDK提供全平台的库,如需提交App Store,需将模拟器架构去除。您可使用lipo -remove去除x86_64架构即可。