在 IM 消息管理中,多种类型消息的传输处理是服务可靠性的关键。关注【融云全球互联网通信云】了解更多
通常,发送消息前,融云 IM 会将发送的媒体文件上传到默认文件服务器。
而在文本、表情、图片、语音、位置、小视频等各种消息中,以小视频的传输对网络等条件的要求最高,其文件更大、上传时间更长,而上传速度会直接影响收发消息的体验。
主流 IM 应用会将传输的视频文件整体做编码,用户收到视频后需要等待加载后才能查看,这显然会对用户体验造成一定影响。
在这一细节能力上,融云使用了分片压缩、分片上传的整体方案,对每个步骤做了深度优化,极大提升视频传输速度,让用户收到即可马上查看视频文件内容。
视频文件通常较大,在资源有限的移动设备硬件中传输,需要通过分片压缩的方式提升资源利用率和传输速度。
视频编码指通过特定技术对视频文件进行编码压缩,以便于网络传输和降低带宽压力。
常见的视频编码方式有 HEVC(H265)、AVC(H264)、DIVX 等,其中 H265 的质量是最高的,但因有些软件或硬件设备无法兼容,其并不是目前的主流编码格式。
我们通常选择 H264 的视频编码格式,同等大小的视频可以保持相对较高的清晰度。
视频编码的基本参数主要有码率、帧率、分辨率。
码率(比特率),指单位时间内传送的比特(bit)数,即每秒钟的视频所包含的数据量,在分辨率已经选定的情况下,调低码率能够有效降低视频的大小。码率越小,视频就会越小。
比特率编码主要有恒定比特率(CBR)、可变比特率(VBR)以及多比特率(MBR)编码模式三种编码方式,我们选择 CBR,并且调低数值(有些应用无法设置编码格式,只能调数值),一般来讲比特率越低则视频越小。
帧率,是视频每秒钟播放的图片数目,帧率越小,感受上看到的视频就越卡。一般而言,大于 24 帧每秒对于肉眼来说看到的就是流畅视频了。
通常,视频帧率保持在 25~35 即可,过高的帧率对视频质量的提高并不会有太大帮助,反而会影响导出的效率。
分辨率指视频的精细程度,分辨率越大,视频的内容就越精细。
在这方面,保留视频原有的分辨率即可,如果是高清视频想要舍弃一些清晰度来缩小,则可以按照宽高比例进行设置。
视频压缩的目标是:在确保清晰度的前提下最大程度降低视频大小。
我们可以围绕上述视频编码几大要素,反复尝试出一个清晰度较高且最大程度压缩视频大小的标准。
计算视频大小的公式为(音频码率 / 8+视频码率 / 8) x 视频时长。由此可见,通过删减视频长度或降低码率即可达成压缩视频的目标。
时长固定的情况下,控制码率便成为压缩视频的关键。当然,但码率也不可随意极限调低。假使我们把分辨率比作一个盒子,码率就是撑起这个盒子需要放置的物品,多则浪费,少则不满进而影响清晰度。
这就需要找到二者之间的最佳比例,常用的分辨率和码率的选择区间为:
NSInteger bitrate = videoSize.height * videoSize.width * 2;
session.videoSettings = @{
AVVideoCodecKey : AVVideoCodecH264,
AVVideoWidthKey : @(videoSize.width),
AVVideoHeightKey : @(videoSize.height),
AVVideoCompressionPropertiesKey : @{
AVVideoColorPrimariesKey : AVVideoColorPrimaries_ITU_R_709_2,
AVVideoAverageBitRateKey : @(bitrate), // 比特率
AVVideoProfileLevelKey : AVVideoProfileLevelH264High40, // 压缩算法
},
举例来说,融云默认允许上传 2 分钟时长的视频,通常分辨率 1280x720(720P)下,苹果设备录制视频的原文件大小为 120M 左右,经过压缩后,大小可降低至 44M,保障清晰度的情况下,有效压缩率为 37% 左右。
分片上传支持将一个文件切割为一系列特定大小的数据块,每个小数据块以一个独立的 HTTP 请求分别上传,以保证较大视频文件的传输速度。
所有小数据块都上传完成后,发送一个请求给服务端将这些小数据块组织成一个逻辑资源,即获得原始视频文件,整个分片上传过程就此完成。
☑适合尺寸较大的文件传输,通过分片来避免单个 HTTP 数据量过大而导致连接超时的现象。
☑在网络条件较差的环境下,较小尺寸的文件可以有较高的上传成功率,从而避免无休止的失败重试。
☑失败重传不需要整个文件从头开始,只需要重传此分片,有效提升上传效率。
☑并行分片上传,利用对象存储 OSS(Object Storage Service)的并行处理能力,网络环境影响可以降到最低。
☑移动端设备硬件资源优先,分片上传可以有效降低大文件上传时的内存占用,防止内存溢出。
在分片上传中,分片策略是一个重要的挑战点。
分片太大,片数少,上传的并发度不够,可能会降低上传效率,每个大的分片在失败后重传的成本会比较高;分片太小,片数多,并发需要的 TCP 连接太多,多条 TCP 连接的“窗口慢启动”会降低整体吞吐,两端拆分与合并分片的开销也相应增加,而且传输时的额外流量(HTTP 报头)也会更多。
融云采用的分片策略是,综合考虑 2 分钟时长的视频压缩后大小为 44M,每个分片大小 5M,大致可分为 9 片并行上传,采用 4 个线程,有效利用网络带宽。
这样,融云 IM 传输的视频文件,在经过第一步的分片压缩后,再通过并行分段上传实现多线程上传,充分利用可用带宽,大大缩短上传时长。
此外,针对国内和外海客户的不同需求,融云完成了与多家 OSS 厂商的对接,可根据客户市场需要,定制化配置最优 OSS 服务商,保障服务器资源的高可用,实现视频文件的高速传输。