首页 > 编程知识 正文

腾讯短视频sdk收费吗(sdk 视频)

时间:2023-05-03 12:22:41 阅读:78402 作者:2734

直播、短视频层出不穷,吸引了众多企业参与,音视频开发成为许多传统企业和中小企业最大的难点,而视频云客户端SDK无疑也是一个不错的选择。 本文由LiveVideoStackCon 2017全民快乐研发资深总监bmdty分享整理,主要涉及架构设计、模块分割实现、跨平台视频处理系统和流媒体系统的构建几个部分

演讲/bmdty

整理/实时视频堆栈

我来自全民幸福的bmdty。 就职于淘宝开发机票搜索,经历了歌唱酒吧上线之初加入,歌唱酒吧从上线到拥有4亿用户的全过程。 在此期间,我负责歌唱酒吧音视频的开发。 其中包括唱吧、唱吧直播室、火星等产品线。 目前,在全民负责直播产品线业务,主要面向海外市场。

在这次分享中,视频云包括音视频领域的发展、SDK的核心APP应用场景、录像机和视频播放器模块的分割、跨平台视频处理系统和流媒体系统的构建、未来的机遇和挑战等

视频云客户端SDK发展和核心场景

音视频架构和开发的发展经历了很长时间,大致可以分为以下几个过程: 最初为广电领域,也就是电视台提供直播和转码等服务; 之后,扩展到了PC端的音视频领域; 近年来,在移动终端音视频领域取得了发展。

除了为每个视频云制造商提供持续、稳定、高可用性的在线服务之外,实际上还提供了客户端的SDK,使客户端在不知道音视频细节的情况下快速构建自己的APP,也可以用于与自己的垂直领域相关的业务

SDK的中心场景是什么? 为了简化说明,将SDK的中心场景分为录像场景和实时场景。 对于录制场景,播音员或内容提供者必须录制视频。 稍后需要频繁添加主题、贴纸、混音、BGM等特效,最终将视频上传到服务器,观众需要使用播放器播放并进行社交交互。 另一方面,如果直播场景也包含这两个角色,主播端则需要实时直播内容,并根据观众的行为进行实时互动,观众端则需要使用个性化的播放器进行观看这个场景中的玩家并不是使用系统提供的玩家就可以了,必须进行定制。

对于录像和直播两个场景,他们的共同特征包括录像机和视频播放器; 区别主要在于是否具有实时交互性。他们需要在不同的场景中进行特殊的配置,例如直播中推送流的稳定性和抽取流的秒开,录制中后期视频处理和上传。

视频录制器的架构设计

模块分割

录像机分为输入、处理和输出三个部分。 输入是指使用照相机和麦克风等收集设备进行声音和画面的收集。 处理是对导入的影像和声音进行的,如众所周知的美颜、回声抑制、混响等。 最终的输出分为几个部分。 首先是预览。 例如,用手机录制视频时,屏幕上有预览屏幕。 第二部分是编码,安卓平台采用硬件编码软件,iOS平台兼容,只需硬件编码就能满足要求; 最后,将音频视频数据封装在容器——FLV或MP4中并进行IO输出。 IO输出可能将——实时场景推送至盘——记录场景或流媒体服务器。

音频体系结构设计

上图是音频体系结构图,因为处理器很复杂,所以没有出现在里面。 从图中可以看到,音频架构分为Input、Output、队列、Consumer几个部分,架构图的上下部分分别是安卓平台和iOS平台实现的结构。

用户需要在卡拉ok过程中混合伴奏音乐。 对于安卓平台来说,需要MP3解码器。 它可以在MAD、Lame或FFmpeg等开源库中实现,最终在audio track API或opensl es API中播放,同时将播放的PCM数据放入PCM队列。 在采集过程中,使用Audio Recoder或OpenSL ES采集人声,采集的人声也进入PCM队列。 在典型的体系结构设计中,队列一般负责生产者和消费者之间的解耦,因此Input和Output是上述两个队列的生产者,Consumer线程的Encoder由消费者——从队列中检索PCM数据并进行编码

iOS平台使用的是Au图形。 其基础使用了音频单元。 远程io类型的音频单元可以捕获人声,而音频文件播放器类型的音频单元可以播放伴奏。 然后,在混合器类型的音频单元中混合人声和伴奏入队,后面的消费者线程的编码器从队列中提取PCM数据并进行编码。

视频体系结构设计

视频部分的结构设计会比较简单。 安卓平台在Camera上收集视频,Output首先在EGL Display上前后显示预览界面,然后使用MediaCodec硬件代码和Libx264软件代码

结合的实现方式(由于安卓平台硬件编码有可能出现兼容性问题)。而在iOS平台则会更简单,直接使用Camera采集,然后通过GLImageView来进行渲染——GLImageView的实现方式是继承自UIView,在LayerClass中返回CAEAGLLayer,然后构造出OpenGL环境用来渲染纹理,最终再用VideoToolbox进行编码输出。编码后的数据会放到H.264队列中,那么这里的生产者就是编码器,消费者实际上是Consumer模块,它把H.264队列中数据Mux后再进行IO操作(输出到磁盘成为mp4文件或者输出到流媒体服务器)。

视频播放器架构设计

模块拆分

视频播放器的模块拆分和视频录制器非常相似,同样分为输入、处理和输出三部分。首先是IO输入——本地磁盘或远程拉流,拿到码流后需要进行解封装(Demux)过程,也就是封装(Mux)的逆过程,它会把FLV中音频轨、视频轨以及字幕轨拆解出来,然后进行解码过程,一般采用采用硬件+软件解码的方案。

视频播放器中中间处理过程使用的并不算很多,音频处理上可以做一些混音或伴奏,画面处理则是画质增强,如自动对比度、去块滤波器等,当然播放器处理中非常重要的一环就是音视频同步,目前一般有三种模式:音频向视频同步、视频向音频同步以及统一向外部时钟同步。我们一般会选择视频向音频同步,这主要是由于两方面的原因:一方面是由人的生理特性决定的,相比于画面,人对声音的感受会更加强烈;另一方面音频PCM是线性的,我们可以信赖播放器也是线性的播放,因此在用视频帧向音频帧同步时,我们允许对视频帧进行丢帧或重复帧渲染。最后,输出则主要包含音频渲染和视频渲染两部分。

运行流程

对一个多媒体文件,视频播放器会对其进行Demux和Decoder处理,当解码器解码出一帧视频后给到队列,这时如果是软件解码则一般解码出来的是YUV格式,然后放入到内存队列中;如果是硬件解码则一般是显存中的纹理ID,会放到循环显存队列中。解码出音频的PCM数据也会入队。

对于这两个队列来说也同样存在生产者和消费者,解码器就是生产者,右边的Output则是消费者。这里值得一提的是,可以通过设置两个游标值来做队列的控制——minSize和maxSize,当队列中的音频大小到达minSize时,消费者则会开始工作,而当音频大小到达maxSize时,解码线程就要暂停工作(wait住),当消费者消费了队列中的内容后,队列中音频大小小于maxSize之后,会让解码线程继续工作(发出Singal指令)。而消费者的工作流程为:从音频队列中取出一帧音频帧给音频播放模块进行播放,然后会通过AVSync音视频同步模块取出一帧对应的视频帧给视频播放模块进行播放。当生产者、消费者周而复始的运转起来,整个播放器也就运行起来了。

音视频同步策略

前面提到我们音视频同步策略是采取视频向音频同步,也就是说假设我们在播放音频第一帧时,对应的第一帧视频没有过来,而此时马上要播放音频第二帧,那么我们就会选择放弃第一帧视频,继续播放第二帧从而保证用户感受到音视频是同步的;那么假设当没有播放第三帧音频时已经接收到对应的视频帧时,则会将视频帧返回,直到对应音频播放的时候再取出对应的视频帧。

那么对于普通开发者而言,想要实现播放器每一个细节其实是非常复杂的,尤其对于一些创业公司或者对于音视频积累比较薄弱的公司来说,所以直接接入CDN厂商提供的SDK是不错的选择,这样可以尽快实现自身业务逻辑,而伴随着业务的发展,后期可以针对特殊需求基于SDK进行二次开发。

从个人经验来讲,我认为SDK中技术含量较高的主要有两点:跨平台的视频处理系统和跨平台的推流系统构建,接下来我会做重点介绍。

跨平台的视频处理系统

跨平台的视频处理系统实际可以说是跨平台的复杂滤镜系统,它所应用的场景主要有实现美颜、瘦脸这种单帧图片的处理,也有如雨天、老照片等主题效果,以及贴纸效果这几种。为了达到效果,我们通过OpenGL ES来实现,如果用软件(CPU中计算)做视频处理是非常消耗性能的,尤其在移动端无法接受。因此它的输入是纹理ID和时间戳,时间戳主要用于主题和贴纸场景的处理。输出则是处理完毕的纹理ID。

GPUImage

这里特别介绍下GPUImage框架(以iOS平台作为讲解),它的整个流程分为Input、Processor和Output。首先通过GPUImageVideoCamera采集画面;然后转化为纹理ID就可以通过模糊、混合、边缘检测、饱和度等一系列处理进行优化;最终Output中使用GPUImageView把处理完的视频帧渲染到屏幕上,而对于录制则提供了GPUImageMovieWriter,它可以将纹理ID硬件编码到本地文件。除了视频录制过程,它对视频播放器和离线处理场景提供了GPUImageMovie作为Input的实现。

跨平台的视频处理系统构建

对于搭建跨平台的视频处理系统,我们需要搭建两个客户端的OpenGL环境,安卓平台使用EGL来提供上下文环境与窗口管理,iOS使用EAGL来提供上下文环境与窗口管理,然后我们抽象出统一接口服务于两个平台。

这是结构图,左边是根据平台搭建的环境——Platform OpenGL Environment,右边是视频处理系统—VideoEffectProcessor。整个过程为:首先通过Camera或者Decoder采集或者解码出视频帧纹理,将纹理ID交给VideoEffectProcessor完成视频处理功能,而这里面可能需要很多支持,比如集成一些第三方库解析XML、解析Json、libpng等等,同时我们也要暴露一些可以动态添加和删除Filter的功能。当处理完成后会输出一个Output TexId做渲染,最终呈现到界面上,或者给到Encoder做离线保存。

跨平台的推流系统

我们先来看跨平台推流系统的应用场景,首先无论网络是否抖动都要维持交互的实时性,其次要保证正常直播的流畅性,并能根据网络条件的好坏来决定清晰度,最后要有统计数据来帮助产品运营做策略优化,比如提升码率、分辨率等等。针对这三点场景分析,如何从技术角度实现?首先在弱网下做出丢帧,第二是码率自适应,第三为了保证主播端持续直播,需要做到自动断线重连。

那为什么要做跨平台的推流系统?这主要考虑到开发成本和效率的问题,从开发策略制定和测试的角度来看都可以节省一部分成本,而且一套代码在后期维护中也有很多好处。那么跨平台推流系统应该如何实现?我们使用FFmpeg将AAC和H.264封装成FLV格式,然后使用RTMP协议推到流媒体服务器上就可以。

弱网丢帧

当检测到H.264或AAC队列的大小超过一定域值时,我们要做丢帧处理,因为此时可能会导致现在的数据很长时间发不出去,从而交互的实时性就无法得到保证。当我们需要进行丢帧处理时,对于视频帧要明确丢弃的是否为I帧或P帧;对于音频帧则有多种策略,可以简单丢弃与视频丢帧相同时间长度的音频帧。

码率自适应

对于码率自适应,我们需要检测上行网络带宽的情况,准确的说是上行网络到推流的流媒体服务器节点的情况。当需要降低码率,我们要把现在编码队列中高码率的视频帧丢掉,并让编码器强制产生关键帧,以保证最新的视频以低码率推到服务器上完成整场直播的交互性。改变编码器的输出码率,对于libx264来说,需要在它的客户端代码中改变vbv buffer size,并Reconfig X264编码器才可以;而对于FFmpeg的API则是需要改变rc buffer size,并且需要ffmpeg 2.8版本以上才能支持;对于MediaCodec和VideoToolbox则使用各个平台硬件编码设置。

这张图是通过当前发送的码率调整实际编码器产生的视频码率,这里调整的不仅仅是码率,同时也包括帧率。当帧率较低时,单纯提升码率也无法达到视频质量提升的效果,因此两者会一起做调整。

链路选择与自动重连策略

在链路选择方面,尤其在某一些特殊场景下,DNS解析不一定能找到最佳链路,我们可以选择直接接入CDN提供的接口,在主播推流前向CDN厂商请求一个最优节点,而不依赖Local DNS去解析IP地址;对于主播端,也可以POST一个500KB的flv文件,在多个推流节点测试网络链路情况,从中选择最优链路。再者推流一段时间后,网络链路有可能会出现拥塞的情况,IDC机房节点也有可能出现问题,因此SDK底层需要有自动重连机制来保证重新分配更优的链路和CDN节点,从而保证主播持续推流不受影响。

数据收集

最后是数据收集,数据收集涉及到后期调优、评判链路节点等等,因此非常重要,而这也是用定制播放器的原因。基本统计的点包括连接时长、发布时长、丢帧比例、平均速率、设置速率和码率自适应的变化曲线等等。

以上是本次分享的全部内容。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。