CDN加速

FAQ

更新时间:2021-07-01 17:10:23

1. (全平台)推流地址如何填写

通常该URL规则由CDN直播或点播团队提供,常规推流地址格式为:

rtmp://推流域名/发布点/流id

可联系相关客服确认。

2. (移动端)取日志的方法

2.1. Android
未进行root的手机也可获取到日志,一般在SD卡下的应用缓冲目录里,路径为:/sdcard/Android/data/应用包名/files/Log。

2.2. iOS
调试日志可以通过 xcode->window->devices菜单 设置下的Download Containers 获取。具体存放路径是 /应用沙盒/documents/cnc_play_log/

3. (移动端)系统要求

3.1. Android
推流器支持的系统最低版本为4.0以上。

3.2. iOS
推流器支持的系统最低版本为8.0以上。提交Appstore之前请打开framework的Info.plist文件,MinimumOSVersion选择最低支持版本为8.0,然后打包提交。

4. (移动端)混淆规则如何添加

假设您项目中某xx模块引用我们网宿的 SDK,那么该xx模块需要过滤混淆,有引用该xx的模块也需要过滤。

5. (移动端)主播切后台,是否可以后台继续推流

5.1. Android
只要不调用停止推流的方法stopPushStream,默认切后台是继续推流。
注意:onPause()方法会停止视频和音频的采集,预览SPSurfaceView未显示在ui中的情况下,即使开启采集也不会进行视频编码。

5.2. iOS
默认关闭后台推流,如需开启,接口调用方法请查看嵌入文档。

iOS系统切后台时回收摄像头权限,推流都仅能推音频。

6. (移动端)主播端网络异常,SDK如何处理

当推流包因网络异常不断丢包后,SDK会抛出

4301 网络环境差

的警告,App可根据此对主播给出相应提示。
android sdkn内部4301错误码抛出时间间隔为5秒。

7. (移动端)镜像功能介绍

网宿 SDK 支持如下各种情况的 镜像/非镜像 设置
前置/后置摄像头
预览/推流
以拍摄如下图片作为原像:

公安部十九大重保嘉奖令来了!
其对应的不同条件下进行拍摄的方式和对应播放效果为:

公安部十九大重保嘉奖令来了!

8. (移动端)推流中是否可动态切换分辨率

不支持。
推流前在初始化时,就必须确定好分辨率。
如推流过程中需切换分辨率,需要断流。

9. (移动端)参数参考值

9.1. 分辨率
当采用硬编,检查主播的分辨率、码率,确认对应分辨率下的码率是否符合(如下表)。

分辨率 码率范围(kbps)
360P 400~700
480P 500~800
540P 600~1000
720P 800~1500

当采用软编,初始化配置时可选择自己的软编策略为质量优先,较多客户选择480P的分辨率。根据业务需要,也可以考虑低端机型固定一个较低的分辨率,其它机型固定一个优质点的分辨率。因为分辨率越大,对码率的要求就高,才能获得清晰的画质,因此对网络要求就高,从而会增加带宽成本。

9.2. 码率
不同分辨率对应的码率不同,可参见上个问题下的附表。

9.3. 帧率
安卓机型较多且复杂,建议帧率在20 ~ 25fps左右调试。iOS可在25 ~ 30fps左右调试。

9.4. 其他参数
缓冲阈值可设 1000 ms 调试,越低越有可能卡顿。
延时追赶必须大于缓冲阈值至少1000ms以上,如果对时延要求不高,设大一点播放会更流畅。

10. (移动端)使用第三方的美颜/滤镜/变脸功能

如果仅使用第三方的美颜滤镜功能,可使用网宿的自定义视频滤镜接口。

如果需使用第三方的变脸功能,我们可以抛出采集的 YUV 数据,第三方厂商经过处理后,抛回 YUV 数据,我们再继续编码推流,但此种方案效率较低。更多建议使用自定义视频源接口,自行完成采集后,将处理好的视频源传给我们进行编码。

10.1. Android
方案一:使用自定义视频源方式(需要自己管理摄像头采集和预览)
自定义视频源使用方法参考文档 “自定义视频源”部分,然后将第三方处理好的yuv视频数据使用pushYuvFrame接口或texture纹理数据使用pushTextureFrame接口送入sdk内部直接编码推流

方案二:使用自定义滤镜
自定义视频滤镜使用方法参考文档“自定义视频滤镜”部分,
继承SPVideoFilter实现自己的美颜逻辑,
通过复写onDrawFrame方法拿到摄像头采集后的纹理图像,并将处理好的纹理id通过return方法返回,
如果需要yuv数据进行人脸识别等操作,需要另外实现SPVideoFilter.CameraPreviewFrameListener接口,
sdk会回调onCameraPreviewFrameCaptured方法,返回摄像头采集的yuv数据。

10.2. iOS
使用SDK内部采集+三方美颜的使用方法
注:rtmp推流前需要发送

- (void)send_meta_data:(CGSize)videoSize frame_rate:(int)fps video_bit_rate:(int)video_bit_rate audio_rate:(int)rate audio_channel:(int)channel;(发送meta data 头)
- (void)send_video_header:(NSData *)spsData PPS:(NSData *)ppsData;(发送视频头)
- (void)send_acc_header:(int)rate channel:(int)channel;(发送音频头)

正确初始化需要使用的各组件,并开启音视频采集(详见工程内各成员变量的初始化函数)。

公安部十九大重保嘉奖令来了!

video相关:
a.启动摄像头采集并输出数据

///采集buf输出回调代理
- (void)video_capture_buf:(void *)buf pix_width:(int)pix_width pix_height:(int)pix_height format:(CNCENM_Buf_Format)format time_stamp:(long long)ts;

b.在video采集数据回调中转成三方需要的数据格式(如yuv、rgba等)传入三方美颜进行预处理

c.获取三方美颜预处理结果((void *)buffer或pixbuffer)传入encoder(编码器)

- (void)inputFrameBuffer:(void *)buffer pix_width:(int)pix_width pix_height:(int)pix_height format:(CNCENM_Buf_Format)format time_stamp:(unsigned int)ts;
- (void)send_frame_pixelBufferRef:(CVPixelBufferRef)pixelBuffer format:(CNCENM_Buf_Format)format time_stamp:(long long)ts;

预览显示
根据预处理结果选择合适方法进行预览,如:

- (void)processVideoImageBuffer:(CVPixelBufferRef)pixelBuffer;//预览视频帧样本
- (void)processVideoBufferData:(void *)buf bytesPerRow:(int)bytesPerRow planeHeight:(int)pHeight;//数据buf预览

d.获取encoder(编码器)完成编码后数据

///H264编码数据回调
- (void)didEncodedCallBack:(char *)compressData dataLength:(int)length frameSize:(CGSize)size isKey:(BOOL)isKey timestamp:(unsigned int)timestamp;

f.将编码结果进行数据发送

- (void)send_video:(char *)sz len:(unsigned int)len is_key:(bool)is_key width:(int)width height:(int)height time_stamp:(unsigned int)time_stamp;

audio相关:
a.设置音频代理并开始采集音频数据详见(initialMobStreamAudioEngine方法)
b.实现音频代理其中

///音频帧时间戳获取
- (unsigned int)timestampForCurrentAudioFrame;
///获取 静音状态、后台是否推流、是否正在推流状态 参数返回值
- (BOOL)audioEngine:(CNCMobStreamAudioEngine *)audioEng valueForOption:(AudioEngineOption)option withDefault:(BOOL)defaultValue;
///请求发送audio header
- (void)audioEngine:(CNCMobStreamAudioEngine *)audioEng sendAudioHeaderRate:(int)rate channel:(int)channel time_stamp:(unsigned int)time_stamp;
///编码后的AAC数据回调接口
- (void)audioEngine:(CNCMobStreamAudioEngine *)audioEng sendAudioBufferData:(char *)src_sz len:(unsigned int)len time_stamp:(unsigned int)time_stamp;

上述所有回调代理及成员方法在各.h中有方法说明,在demo中皆有详细的代码使用范例(包含各组件的初始化)。

11. (Android)底层库与自身App冲突时哪些库可以重命名

可以重命名的库仅有 libcrypto.so 和 libssl.so 。

12. (Android)集成网宿 SDK 编译时,很多第三方类报 No ClassDefException

Android 推流 SDK 从1.8.6版本开始需 java 8编译,如仍使用 java 7 编译,那么定义了没有使用的类就会有此报错。
因 java 7和 java 8的优化方案不同,建议仍使用 java 7的环境升级为 java 8。

13. (移动端)调试时如何设置log打印方法

logLevel:设置输出log等级,有三种可选:
LOG_LEVEL_ALL(输出全部)、
LOG_LEVEL_WARN(输出warning以上)、
LOG_LEVEL_NONE(关闭log)。
默认为LOG_LEVEL_ALL

14. (iOS)编译时反馈文件丢失

公安部十九大重保嘉奖令来了!
此时请确认指向的target,务必选用第一项,CNCMobStreamLibDemo

公安部十九大重保嘉奖令来了!
若对FaceUnity和SenseTime的美颜版本有需求,请联系产品经理另行申请

15. (iOS)报CUICatalog: Invalid asset name supplied错误

首先该问题并非由于SDK造成,而是系统接口层面的问题,产生原因就是因为在使用的时候 [UIImage imageNamed:]时,图片不存在或者传入的图片名为nil。
通常可通过添加一个系统断点,来判断如果图片名字为nil或者@""的时候,来拦截掉。完整步骤为:
1.在Xcode的Breakpoint Navigator点击加号, 选择Add Symbolic Breakpoint;
2.右键选择Breakpoint选择Edit Breakpoint, 在Symbol填入+[UIImage imageNamed:], 在Condition填入[(NSString *)\(arg3 length] == 0或者\)arg3 == nil. 可以自己尝试po \(arg1,po \)arg2试试看;
3.运行程序, 直到程序进入断点. 打开Debug Navigator观察调用栈, 最顶部的一定是+[UIImage imageNamed:], 点击调用栈下一条, 能够看到有调用到imageNamed的代码, 就是name为nil的地方;
4.如果找到的地方显示的是地址,而不是代码,这时候不妨查看下一个断点,不错应该就是下个断点哪里。

公安部十九大重保嘉奖令来了!

16. (Android)推流监听中, SPManager.STATE_VIDEO_BITRATE这种类型的消息始终没有回调

这一项是开启自动码率才会有回调的,值为实时码率,单位bps,在没有开启码率自适应的情况下,只有 STATE_FRAME_RATE、STATE_ENCODE_FRAME_RATE和STATE_PUSH_SPEED会回调

17. (iOS)推流断开释放推流器后再次创建出现推流无音频现象

公安部十九大重保嘉奖令来了!
若只使用网宿推流,应当不会出现该问题,需明确是否使用其他厂商类似产品,以该客户为例同时使用了其他连麦产品。

在两个都需要音视频权限的产品切换过程中,由于资源释放需要一定时间,而这里延时只是推流,音频初始化并没有延时,实际在连麦占用的资源尚未释放完就执行了RTMP推流初始化。

可以通过加长延时或获取其他产品的资源释放回调后再创建RTMP推流确保资源的切换过程顺利。

18. (iOS)普通推流、分层采集和分层推流分别是什么意思?

普通推流是完整的流程,包括采集、预处理、编码、推流,对于客户来说接入代码完整性较强
分层推流是把采集层开放到APP层去,允许客户自定义操作
分层采集是把所有功能都独立出来,包括采集、预览、编码、推流、时间戳各自成为一个独立可用的的结构,客户可用自行定义和更换某个功能模块,实现灵活的嵌套(不过这个相对初始化的过程来说就会比较多)

19. (iOS)控制台输出主线程警告

Main Thread Checker: UI API called on a background thread: -[UIView bounds]
PID: 13938, TID: 3661364, Thread name: (none), Queue name: com.sunsetlakesoftware.GPUImage.openGLESContextQueue, QoS: 21
Backtrace:
4   CNCMobStreamFramework               0x0000000105660f98 __39-[GPUImageView recalculateViewGeometry]_block_invoke + 44
5   CNCMobStreamFramework               0x00000001055dcc84 runSynchronouslyOnVideoProcessingQueue + 100
6   CNCMobStreamFramework               0x0000000105660f60 -[GPUImageView recalculateViewGeometry] + 68
7   CNCMobStreamFramework               0x00000001055dcc84 runSynchronouslyOnVideoProcessingQueue + 100
8   CNCMobStreamFramework               0x00000001056613b4 -[GPUImageView setInputSize:atIndex:] + 72
9   CNCMobStreamFramework               0x0000000105647418 -[GPUImageFilter informTargetsAboutNewFrameAtTime:] + 508
10  CNCMobStreamFramework               0x0000000105664054 -[GPUImageCropFilter newFrameReadyAtTime:atIndex:] + 92
11  CNCMobStreamFramework               0x0000000105607178 -[GPUImageVideoCamera updateTargetsForVideoCameraUsingCacheTextureAtWidth:height:time:] + 1012
12  CNCMobStreamFramework               0x000000010560770c -[GPUImageVideoCamera processVideoPixelBuffer::] + 1312
13  CNCMobStreamFramework               0x0000000105607824 -[GPUImageVideoCamera processVideoSampleBuffer:] + 84
14  CNCMobStreamFramework               0x0000000105607dec __74-[GPUImageVideoCamera captureOutput:didOutputSampleBuffer:fromConnection:]_block_invoke + 152
15  libdispatch.dylib                   0x0000000106042c28 _dispatch_call_block_and_release + 32
16  libdispatch.dylib                   0x00000001060441c0 _dispatch_client_callout + 20
17  libdispatch.dylib                   0x000000010604c2f4 _dispatch_lane_serial_drain + 708
18  libdispatch.dylib                   0x000000010604cff8 _dispatch_lane_invoke + 420
19  libdispatch.dylib                   0x0000000106056bfc _dispatch_workloop_worker_thread + 1168
20  libsystem_pthread.dylib             0x0000000183259b20 _pthread_wqthread + 316
21  libsystem_pthread.dylib             0x000000018325fdd4 start_wqthread + 4

XCode Console(控制台)输出Main Thread警告,此警告仅对非主线程内的view操作进行警告,可以将edit scheme中Main Thread Checker关闭

公安部十九大重保嘉奖令来了!

20. (Mobile)如何实现预览全屏?

20.1. iOS

//preview是用于放置预览的view
self.preview = [[[UIView alloc] init] autorelease];

//采集视频的宽高比
CGFloat videoWidthXHeight = 3.0 / 4.0;

//手机屏幕的宽高比
CGFloat screanWidthXHeight = screen_w_ / screen_h_;

CGFloat videoWidth = 0.0;
CGFloat videoHeight = 0.0;
CGFloat offsetX = 0.0;//横坐标起始值
CGFloat offsetY = 0.0;//纵坐标起始值

if (videoWidthXHeight >= screanWidthXHeight) {
//画面比较宽 那就是上下会留黑边
//那就以屏幕的高度为画面的高度 画面的宽度按比例变大
//最终结果就是上下铺满 宽度多出屏幕部分会被裁剪
videoHeight = screen_h_;
videoWidth = videoHeight * videoWidthXHeight;

offsetY = 0.0;
//横坐标起始点往左移 才能保证左右裁剪对称
offsetX = (screen_w_ - videoWidth) / 2;
} else {
//画面比较窄 那就是左右会留黑边
//那就以屏幕的宽度为画面的宽度 画面的高度按比例变大
//最终结果就是左右铺满 高度多出屏幕部分会被裁剪
videoWidth = screen_w_;
videoHeight = videoWidth * (1 / videoWidthXHeight);

offsetX = 0.0;
//纵坐标起始点往上移 才能保证上下裁剪对称
offsetY = (screen_h_ - videoHeight) / 2;
}

self.preview.frame = CGRectMake(offsetX, offsetY, videoWidth, videoHeight);
[self.view addSubview:self.preview];

21. (iOS)App启动crash报image not found

dyld: Library not loaded: @rpath/***
Referenced from: /private/var/containers/Bundle/Application/***
Reason: image not found

此问题为xcode工程设置问题,需在工程设置→General标签页中 将相应的framework设置为Embed & Sign