zoukankan      html  css  js  c++  java
  • 关于直播,所有的技术细节都在这里了(4)《转载》

    本文转载置顶:http://blog.ucloud.cn/archives/796

    感谢作者无私的奉献精神!

    上篇《关于直播,所有的技术细节都在这里了(3)《转载》》我们讲述了直播后端系统的原理及优化,那么直播推流、播放端是否就没有可以优化的点呢? 答案是否定的。客户端的优化对直播秒开、延迟体验的实现至关重要,这里重点介绍移动终端的情况。

    解析优化

    参见之前介绍的DNS过程,如下图:

    基于可控和容灾的需要,移动端代码一般不会hardcode 推流、播放的服务器IP地址,而选用域名代替。在IP出现宕机或网络中断的情况下,还可以通过变更DNS来实现问题IP的剔除。而域名的解析时间需要几十毫秒至几秒不等,对于新生成热度不高的域名,一般的平均解析延迟在300ms,按上图的各个环节只要有一个通路网络产生波动或者是设备高负载,会增加至秒级。几十毫秒的情况是ISP NS这一层在热度足够高的情况下会对域名的解析进行缓存。如下图:

    按我们上面分析的情况,本省延迟大概是15ms左右,那么域名解析最低也可以做到15ms左右。但由于直播场景的特殊性,推流和播放使用的域名使用的热度较难达到ISP NS缓存的标准,所以经常需要走回Root NS进行查询的路径。

    那客户端解析优化的原理就出来了:本机缓存域名的解析结果,对域名进行预解析,每次需要直播推流和播放的时候不再需要再进行DNS过程。此处节省几十到几百毫秒的打开延迟。

    播放优化

    直播播放器的相关技术点有:直播延时、首屏时间(指从开始播放到第一次看到画面的时间)、音视频同步、软解码、硬解码。参考如下播放流程:

    播放步骤描述:

    1. 根据协议类型(如RTMP、RTP、RTSP、HTTP等),与服务器建立连接并接收数据;
    2. 解析二进制数据,从中找到相关流信息;
    3. 根据不同的封装格式(如FLV、TS)解复用(demux);
    4. 分别得到已编码的H.264视频数据和AAC音频数据;
    5. 使用硬解码(对应系统的API)或软解码(FFMpeg)来解压音视频数据;
    6. 经过解码后得到原始的视频数据(YUV)和音频数据(AAC);
    7. 因为音频和视频解码是分开的,所以我们得把它们同步起来,否则会出现音视频不同步的现象,比如别人说话会跟口型对不上;
    8. 最后把同步的音频数据送到耳机或外放,视频数据送到屏幕上显示。

    了解了播放器的播放流程后,我们可以优化以下几点:

    首屏时间优化

    1. 从步骤2入手,通过预设解码器类型,省去探测文件类型时间;
    2. 从步骤5入手,缩小视频数据探测范围,同时也意味着减少了需要下载的数据量,特别是在网络不好的时候,减少下载的数据量能为启动播放节省大量的时间,当检测到I帧数据后就立马返回并进入解码环节。
    延时优化

    视频缓冲区或叫视频缓存策略,该策略原理是当网络卡顿时增加用户等待时间来缓存一定量的视频数据,达到后续平滑观看的效果,该技术能有效减少卡顿次数,但是会带来直播上的内容延时,所以该技术主要运用于点播,直播方面已去掉该策略,以此尽可能去掉或缩小内容从网络到屏幕展示过程中的时间;(有利于减少延时)。

    下载数据探测池技术,当用户下载速度不足发生了卡顿,然后网络突然又顺畅了,服务器上之前滞留的数据会加速发下来,这时为了减少之前卡顿造成的延时,播放器会加速播放探测池的视频数据并丢弃当前加速部分的音频数据,以此来保证当前观看内容延时稳定。

    推流优化

    推流步骤说明:很容易看出推流跟播放其实是逆向的,具体流程就不多说了。

    优化一:适当的Qos(Quality of Service,服务质量)策略。

    推流端会根据当前上行网络情况控制音视频数据发包和编码,在网络较差的情况下,音视频数据发送不出去,造成数据滞留在本地,这时,会停掉编码器防止发送数据进一步滞留,同时会根据网络情况选择合适的策略控制音视频发送。

    比如网络很差的情况下,推流端会优先发送音频数据,保证用户能听到声音,并在一定间隔内发关键帧数据,保证用户在一定时间间隔之后能看到一些画面的变化。

    优化二:合理的关键帧配置。

    合理控制关键帧发送间隔(建议2秒或1秒一个),这样可以减少后端处理过程,为后端的缓冲区设置更小创造条件。

    软硬编解选择

    网上有不少关于选择软解还是硬解的分析文章,这里也介绍一些经验,但根本问题是,没有一个通用方案能最优适配所有操作系统和机型。

    推流编码: 推荐Andorid4.3(API18)或以上使用硬编,以下版本使用软编;iOS使用全硬编方案;

    播放解码:Andorid、iOS播放器都使用软解码方案,经过我们和大量客户的测试以及总结,虽然牺牲了功耗,但是在部分细节方面表现会较优,且可控性强,兼容性也强,出错情况少,推荐使用。

    附软硬编解码优缺点对比:

    云端机型及网络适配

    上面分析了很多针对视频编解码的参数,但实际情况最好的编解码效果是需要根据机型的适配的,由于iOS的设备类型较少,可以做到每个机型针对性的测试和调优,但是对于Android就非常难做到逐款机型针对性调优,并且每年都会出产不少的新机器,如果代码中写死了配置或判断逻辑将非常不利于维护和迭代。

    所以我们就诞生了一个想法,这些判断逻辑或配置是否可以放在云上呢?  这样就产生了云端机型与网络适配的技术。

    终端在推流、播放前会获取通过协议上报当前的机型配置、网络情况、IP信息。云端会返回一个已最适合的编解码策略配置:走软编还是硬编、各项参数的配置,就近推流服务的IP,就近播放服务的IP。 终端获取一次即可,不需要每次推流、播放前都去获取一次。

    这样,在我们不断的迭代和完善机型编解码适配库的同时,所有使用该技术的直播APP都将收益。

    总结

    分析很多直播后端、终端的关于低延迟、秒开的优化技术,在UCloud直播云上都已有了相关的实践,都是一些较“静态”的技术。实际提供稳定、低延迟、流畅的直播服务,是日常中非常大量细致的监控、算法和动态运营的结果,并不是实现了某些的技术点,就能坐享一套稳定的直播服务,只能说是完成了万里长城的第一道砖。

    -------------------------------------------------------

    转载:http://blog.ucloud.cn/archives/796

  • 相关阅读:
    多线程中,上锁的理解
    sql server 2008 联机丛书
    序列化是线程安全的么
    对象化下的编程——字段
    Dic实现工厂模式
    design principle:java 回调与委派/委托机制(转)
    风筝数据结构学习笔记(2)后序遍历二叉树(非递归)
    风筝数据结构学习笔记(1)利用链式存储结构和递归构建二叉树
    吕震宇老师《设计模式系列》
    吕震宇老师《设计模式随笔系列》
  • 原文地址:https://www.cnblogs.com/wainiwann/p/6080956.html
Copyright © 2011-2022 走看看