一文明白CDN加速是个啥
作者:IT王小二
博客:https://itwxe.com
不知不觉三个月没更新了,这三个月诸事繁忙啊!最近没那么忙了,开始恢复更新。
一、CDN简介
CDN(Content Delivery Network)是指内容分发网络,也称为内容传送网络,这个概念始于1996年,是美国麻省理工学院的一个研究小组为改善互联网的服务质量而提出的。为了能在传统IP网上发布丰富的宽带媒体内容,他们提出在现有互联网基础上建立一个内容分发平台专门为网站提供服务,并于1999年成立了专门的CDN服务公司,为Yahoo提供专业服务。由于CDN是为加快网络访问速度而被优化的网络覆盖层,因此被形象地称为“网络加速器”。
CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。
CDN的基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。 --摘自百度百科
二、通俗易懂理解CDN
看了上面的话不知道 CDN 用来干啥的?不要紧,这不是有小二在吗。小二这就给小伙伴们娓娓道来。
先不说 CDN,相信小伙伴们都在京东自营店买过东西吧,要是没有的话扣 1 哈。
相信用过京东自营的小伙伴都知道,购买的商品基本隔天就到我们手中,这是为啥呢?
细心的小伙伴都可以看到发货地址都离自己很近,京东将商品存储在全国的八个大仓库里面,当我们从就京东自营店购买一个商品,那么京东会从离你最近的仓库发货,就近发货减少了道路的拥堵和长距离运输,基本隔天就能收到商品,速度非常的快,再也不用漫长的等待。
那么我们访问一个网站时,如果站点服务器是在广州,而访问的用户在北京,那么不同时间段的运营商网络状态和经过长距离的网络传输,访问速度会变慢,那么访问网站时有没有办法类似京东买商品可以快速到货呢,当然有,解决办法之一就是 CDN。
所以说人话, CDN 就是一个你的网站缓存, 而 CDN 节点就类似京东在全国的八大仓库,提前把网站内容存到了 CDN 节点,然后每个请求网站的用户从就近节点获取网站数据,大大减短了网络的长距离传输和网络拥堵的状况下的访问速度,类似下图的效果。
同时不同 CDN 服务商还会针对电信、移动、联通等网络专门设置 CDN 节点,减少网络服务商之间的切换。
三、CDN的好处
- 隐藏服务器源ip。
- 连接所响应速度最快的节点提高访问速度。
- CDN节点缓存减少网站服务器访问压力。
四、CDN原理解析
因为小二是程序猿嘛,所以肯定要扯一扯 CDN 原理的。以我的域名 itwxe.com 为例看看一个请求走的解析路线,目前我的解析服务商是 DNSPod,CDN 使用的是百度云加速。
不使用 CDN 时
- 用户输入访问的域名 itwxe.com,操作系统向 LocalDNS 查询域名的 IP 地址。
- LocalDNS 向 RootDNS 查询域名的授权服务器 (这里假设 LocalDNS 缓存过期)。
- RootDNS 将域名授权 DNS 记录返回给 LocalDNS,我的是 DNSPod。
- LocalDNS 得到域名的授权 DNS 记录后,继续向域名授权 DNS (DNSPod)查询域名的 IP 地址。
- 域名授权 DNS (DNSPod)查询域名记录后,返回给 LocalDNS。
- LocalDNS 将得到的域名映射的 IP 地址,返回给用户端。
- 用户端得到域名 IP 地址后,访问站点服务器。
- 站点服务器接收请求,将内容返回给客户端。
使用 CDN 时
- 用户输入访问的域名 itwxe.com,操作系统向 LocalDNS 查询域名的 IP 地址。
- LocalDNS 向 RootDNS 查询域名的授权服务器 (这里假设 LocalDNS 缓存过期)。
- RootDNS 将域名授权 DNS 记录返回给 LocalDNS,我的是 DNSPod。
- LocalDNS 得到域名的授权 DNS 记录后,继续向域名授权 DNS (DNSPod)查询域名的 IP 地址。
- 域名授权 DNS (DNSPod)查询域名记录后(一般是CNAME,例如我的是itwxe.com.cname.yunjiasu-cdn.net.),返回给 LocalDNS。
- LocalDNS 得到域名记录后,向智能调度 DNS 查询域名的 IP 地址。
- 智能调度 DNS 根据一定的算法和策略,将最适合的 CDN 节点 IP 地址返回给 LocalDNS。
- LocalDNS 将得到的域名 IP 地址,返回给用户端。
- 用户得到域名 IP 地址后,访问站点服务器。
- 站点服务器接收请求,将内容返回给客户端。
使用 dig 命令可以看到请求的 cname 地址和 最终访问的 CDN 节点 IP,如下图访问我的博客访问的节点。
五、免费CDN服务商
有人说过:“免费的往往是最贵的”,所以...
下面列举的免费 CDN 使用时一定要注意免费版官方的使用说明,没有设置好 CDN 的情况下如果被 DDos 了可能一夜之间倾家荡产。
下面列举的免费 CDN 使用时一定要注意免费版官方的使用说明,没有设置好 CDN 的情况下如果被 DDos 了可能一夜之间倾家荡产。
下面列举的免费 CDN 使用时一定要注意免费版官方的使用说明,没有设置好 CDN 的情况下如果被 DDos 了可能一夜之间倾家荡产。
重要的事情说三遍,下面小二开始正式说说目前免费 CDN 有哪些比较好用的。
国外
- Cloudflare
官方网站:https://www.cloudflare.com/zh-cn/
国外最好用的 CDN,没有之一,如果你的服务器在国外且域名没有备案,那么需要使用 CDN 的市况下 Cloudflare 可以说是最好的选择了,免费套餐即不限流量,还能抗 DDos 攻击。当然如果你的服务器在国内且域名已经备案了,那么就使用国内的 CDN 吧,就不是加速 CDN,而是减速 CDN 了。
优点:免费套餐即不限流量,可以抗 DDos 攻击。
缺点:在国内访问速度不佳。
国内
如果需要使用国内的 CDN 服务商服务,那么前提就是域名需要备案了,备案了才能使用国内的 CDN,下面介绍几个常见的。
- 百度云加速
官方网站:https://su.baidu.com/
小二第一个使用的,也是目前正在使用的 CDN 服务商,几个月前还是 CDN 节点数量 6-9 个,流量10g/天,单个上传文件大小 100M,现在没想到都缩水这么多了,不过目前使用速度还可以,免费又大碗。
顺便说一下百度云 CDN,百度云 CDN 和百度云加速不是同一个产品,百度云 CDN 号称可以24小时极速收录,但是我试用了两个月的免费套餐之后还是切换回了百度云加速。原因是24小时极速收录效果不佳,我问了客服,客服说也只是把访问数据提交给收录部门进行处理。
优点:免费套餐缩水后流量5G/天,速度还不错。
缺点:随着免费套餐缩水,CDN节点数量减少,很多功能需要付费使用,同时个人认证需要手持身份证拍照(略麻烦)。
- 奇安信CDN
官方网站:https://wangzhan.qianxin.com/
这个是最近百度云加速免费版套餐缩水和加了很多限制后小二朋友推荐给我的,小二后面会考虑 CDN 从百度云加速切换到奇安信 CDN。因为目前奇安信 CDN 免费不限量,朋友博客测试访问速度还可以,妈妈再也不用担心我会因为 DDos 攻击倾家荡产了。
优点:免费不限量,安全,不用担心 DDos。
缺点:节点少,同时个人认证也需要手持身份证认证(不过朋友说上传个奥特曼都行,只要你网站备案了,个人认证没人审核的)。
- 又拍云
官方网站:https://www.upyun.com/
也是很多博主正在使用的 CDN,申请加入又拍云联盟后将又拍云链接附在网站底部,每个月就可以获得 15GB 的 CDN 流量和 10GB 的存储空间(即对象存储),对象存储自动走 CDN 流量,无需其他配置。
优点:速度快,节点多,有在线客服。
缺点:流量少,又拍云节点经常被打,每年得申请一次又拍云联盟。
其他比较常见的还有 上海云盾、多吉云、七牛云就不一一介绍了。
六、CDN的使用
每个服务商 CDN 的配置界面都不大一样,不好写怎么配置,所以我大致说下 CDN 配置的思路。
1、首先保证域名A记录解析源站IP可以正常访问。
2、接入CDN主要有两种方式,第一种是 NS 解析,第二种是 CNAME 解析,大部分情况使用 CNAME 解析就行了。
3、选择 CNAME 解析后在选择的 CDN 服务商处添加网站,然后添加解析记录,添加解析记录之后会生成一个 CNAME 域名值。
4、复制这个 CNAME 域名值,进入你的域名解析服务商界面处,将解析记录解析成 CDN 生成的 CNAME 域名值。
配置成功之后就可以愉快的使用 CDN 了,当然这只是最基本的配置,还有很多需要注意的地方,例如缓存策略,缓存时间,免费套餐的访问带宽阈值,免费流量使用完之后的策略...都是需要注意的地方。
因为百度云加速小二已经配置好了,不想还原设置重新设置,所以下面我就按上面的步骤以奇安信 CDN 为例说下怎么配置 CDN。
1、首先保证域名解析源站能访问这就不用说了吧。
2、奇安信 CDN 官网注册账号实名认证后,在域名列表页面,输入你的域名,选择 CNAME 解析,点击添加域名。
3、添加域名后点击添加子域名,添加记录,小二选择的是回源到 IP,所以添加两条A记录,如果是回源到域名,由别的域名提供IP,则添加 CNAME 记录。小二添加了 itwxe.com 和 www.itwxe.com 两条记录,配置结果如下图,最终会生成两条记录,这就是我们在域名解析处需要用到的两条记录。
4、在解析出得到两条解析记录后,进入域名解析配置界面,小二的域名是在腾讯云购买的,解析服务商是 DNSPod,复制步骤三的两条记录添加到 DNSPod 中,同时需要注意的是需要一一对应,这样就就完成了最简单的 CDN 配置了。小二的示例如下图。
等待 DNSPod 解析更改生效,腾讯云免费版DNS解析套餐更改记录生效时间是 10 分钟,此时可以再次使用 dig 命令,可以看到奇安信 CDN 已经生效了,不再是百度云加速。
...
等了10分钟,我也以为要成功了,毕竟小二可是老司机了,结果一访问网站,发现访问不了了!
以小二多年跳坑的经验,九成是CDN节点和源站SSL证书之间证书的问题,待我上传个 SSL 证书啥问题都解决了,当我以为故事到这里就结束了,结果...
不支持泛域名的话还是老老实实百度云加速吧,一个一个配置子域名可太累了...
当然配置 CDN 主要的流程就是上面的4个步骤,配置过程中有问题的客官欢迎留言评论。
都读到这里了,来个 点赞、评论、关注、收藏 吧!
推荐阅读
-
一文明白CDN加速是个啥
-
epoll简介及触发模式(accept、read、send)-epoll的简单介绍 epoll在LT和ET模式下的读写方式 一、epoll的接口非常简单,一共就三个函数:1. int epoll_create(int size);创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大。这个参数不同于select中的第一个参数,给出最大监听的fd+1的值。需要注意的是,当创建好epoll句柄后,它就是会占用一个fd值,在linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close关闭,否则可能导致fd被耗尽。2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);epoll的事件注册函数,它不同与select是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。第一个参数是epoll_create的返回值,第二个参数表示动作,用三个宏来表示:EPOLL_CTL_ADD:注册新的fd到epfd中;EPOLL_CTL_MOD:修改已经注册的fd的监听事件;EPOLL_CTL_DEL:从epfd中删除一个fd;第三个参数是需要监听的fd,第四个参数是告诉内核需要监听什么事,struct epoll_event结构如下:struct epoll_event { __uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */};events可以是以下几个宏的集合:EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭); EPOLLIN事件:EPOLLIN事件则只有当对端有数据写入时才会触发,所以触发一次后需要不断读取所有数据直到读完EAGAIN为止。否则剩下的数据只有在下次对端有写入时才能一起取出来了。现在明白为什么说epoll必须要求异步socket了吧?如果同步socket,而且要求读完所有数据,那么最终就会在堵死在阻塞里。 EPOLLOUT:表示对应的文件描述符可以写; EPOLLOUT事件:EPOLLOUT事件只有在连接时触发一次,表示可写,其他时候想要触发,那要先准备好下面条件:1.某次write,写满了发送缓冲区,返回错误码为EAGAIN。2.对端读取了一些数据,又重新可写了,此时会触发EPOLLOUT。简单地说:EPOLLOUT事件只有在不可写到可写的转变时刻,才会触发一次,所以叫边缘触发,这叫法没错的!其实,如果真的想强制触发一次,也是有办法的,直接调用epoll_ctl重新设置一下event就可以了,event跟原来的设置一模一样都行(但必须包含EPOLLOUT),关键是重新设置,就会马上触发一次EPOLLOUT事件。1. 缓冲区由满变空.2.同时注册EPOLLIN | EPOLLOUT事件,也会触发一次EPOLLOUT事件这个两个也会触发EPOLLOUT事件 EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);EPOLLERR:表示对应的文件描述符发生错误;EPOLLHUP:表示对应的文件描述符被挂断;EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里3. int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);等待事件的产生,类似于select调用。参数events用来从内核得到事件的集合,maxevents告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create时的size,参数timeout是超时时间(毫秒,0会立即返回,-1将不确定,也有说法说是永久阻塞)。该函数返回需要处理的事件数目,如返回0表示已超时。-------------------------------------------------------------------------------------------- 从man手册中,得到ET和LT的具体描述如下EPOLL事件有两种模型:Edge Triggered (ET)Level Triggered (LT)假如有这样一个例子:1. 我们已经把一个用来从管道中读取数据的文件句柄(RFD)添加到epoll描述符2. 这个时候从管道的另一端被写入了2KB的数据3. 调用epoll_wait(2),并且它会返回RFD,说明它已经准备好读取操作4. 然后我们读取了1KB的数据5. 调用epoll_wait(2)......Edge Triggered 工作模式:如果我们在第1步将RFD添加到epoll描述符的时候使用了EPOLLET标志,那么在第5步调用epoll_wait(2)之后将有可能会挂起,因为剩余的数据还存在于文件的输入缓冲区内,而且数据发出端还在等待一个针对已经发出数据的反馈信息。只有在监视的文件句柄上发生了某个事件的时候 ET 工作模式才会汇报事件。因此在第5步的时候,调用者可能会放弃等待仍在存在于文件输入缓冲区内的剩余数据。在上面的例子中,会有一个事件产生在RFD句柄上,因为在第2步执行了一个写操作,然后,事件将会在第3步被销毁。因为第4步的读取操作没有读空文件输入缓冲区内的数据,因此我们在第5步调用 epoll_wait(2)完成后,是否挂起是不确定的。epoll工作在ET模式的时候,必须使用非阻塞套接口,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死。最好以下面的方式调用ET模式的epoll接口,在后面会介绍避免可能的缺陷。 i 基于非阻塞文件句柄 ii 只有当read(2)或者write(2)返回EAGAIN时才需要挂起,等待。但这并不是说每次read时都需要循环读,直到读到产生一个EAGAIN才认为此次事件处理完成,当read返回的读到的数据长度小于请求的数据长度时,就可以确定此时缓冲中已没有数据了,也就可以认为此事读事件已处理完成。Level Triggered 工作模式相反的,以LT方式调用epoll接口的时候,它就相当于一个速度比较快的poll(2),并且无论后面的数据是否被使用,因此他们具有同样的职能。因为即使使用ET模式的epoll,在收到多个chunk的数据的时候仍然会产生多个事件。调用者可以设定EPOLLONESHOT标志,在 epoll_wait(2)收到事件后epoll会与事件关联的文件句柄从epoll描述符中禁止掉。因此当EPOLLONESHOT设定后,使用带有 EPOLL_CTL_MOD标志的epoll_ctl(2)处理文件句柄就成为调用者必须作的事情。然后详细解释ET, LT:LT(level triggered)是缺省的工作方式,并且同时支持block和no-block socket.在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表.ET(edge-triggered)是高速工作方式,只支持no-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了(比如,你在发送,接收或者接收请求,或者发送接收的数据少于一定量时导致了一个EWOULDBLOCK 错误)。但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知(only once),不过在TCP协议中,ET模式的加速效用仍需要更多的benchmark确认(这句话不理解)。在许多测试中我们会看到如果没有大量的idle -connection或者dead-connection,epoll的效率并不会比select/poll高很多,但是当我们遇到大量的idle- connection(例如WAN环境中存在大量的慢速连接),就会发现epoll的效率大大高于select/poll。(未测试)另外,当使用epoll的ET模型来工作时,当产生了一个EPOLLIN事件后,读数据的时候需要考虑的是当recv返回的大小如果等于请求的大小,那么很有可能是缓冲区还有数据未读完,也意味着该次事件还没有处理完,所以还需要再次读取: 这里只是说明思路(参考《UNIX网络编程》) while(rs) {buflen = recv(activeevents[i].data.fd, buf, sizeof(buf), 0);if(buflen < 0){// 由于是非阻塞的模式,所以当errno为EAGAIN时,表示当前缓冲区已无数据可读// 在这里就当作是该次事件已处理处.if(errno == EAGAIN)break; else return; }else if(buflen == 0) { // 这里表示对端的socket已正常关闭. } if(buflen == sizeof(buf) rs = 1; // 需要再次读取 else rs = 0; } 还有,假如发送端流量大于接收端的流量(意思是epoll所在的程序读比转发的socket要快),由于是非阻塞的socket,那么send函数虽然返回,但实际缓冲区的数据并未真正发给接收端,这样不断的读和发,当缓冲区满后会产生EAGAIN错误(参考man send),同时,不理会这次请求发送的数据.所以,需要封装socket_send的函数用来处理这种情况,该函数会尽量将数据写完再返回,返回-1表示出错。在socket_send内部,当写缓冲已满(send返回-1,且errno为EAGAIN),那么会等待后再重试.这种方式并不很完美,在理论上可能会长时间的阻塞在socket_send内部,但暂没有更好的办法. ssize_t socket_send(int sockfd, const char* buffer, size_t buflen) { ssize_t tmp; size_t total = buflen; const char *p = buffer; while(1) { tmp = send(sockfd, p, total, 0); if(tmp < 0) { // 当send收到信号时,可以继续写,但这里返回-1. if(errno == EINTR) return -1; // 当socket是非阻塞时,如返回此错误,表示写缓冲队列已满, // 在这里做延时后再重试. if(errno == EAGAIN) { usleep(1000); continue; } return -1; } if((size_t)tmp == total) return buflen; total -= tmp; p += tmp; } return tmp; } 二、epoll在LT和ET模式下的读写方式 在一个非阻塞的socket上调用read/write函数, 返回EAGAIN或者EWOULDBLOCK(注: EAGAIN就是EWOULDBLOCK) 从字面上看, 意思是: * EAGAIN: 再试一次 * EWOULDBLOCK: 如果这是一个阻塞socket, 操作将被block * perror输出: Resource temporarily unavailable 总结: 这个错误表示资源暂时不够, 可能read时, 读缓冲区没有数据, 或者, write时,写缓冲区满了 。 遇到这种情况, 如果是阻塞socket, read/write就要阻塞掉。 而如果是非阻塞socket, read/write立即返回-1, 同 时errno设置为EAGAIN. 所以, 对于阻塞socket, read/write返回-1代表网络出错了. 但对于非阻塞socket, read/write返回-1不一定网络真的出错了. 可能是Resource temporarily unavailable. 这时你应该再试, 直到Resource available. 综上, 对于non-blocking的socket, 正确的读写操作为: 读: 忽略掉errno = EAGAIN的错误, 下次继续读 写: 忽略掉errno = EAGAIN的错误, 下次继续写 对于select和epoll的LT模式, 这种读写方式是没有问题的. 但对于epoll的ET模式, 这种方式还有漏洞. epoll的两种模式 LT 和 ET
-
腾讯视频直播 02-推流-美颜滤镜 同样,腾讯云提供了 setBeautyFilter 方法来设置美颜风格、磨皮程度、美白程度和泛红程度 //style 磨皮风格:0:平滑 1:自然 2:朦胧 //美容级别:0-9。值为 0 时关闭美颜效果。默认值:0,关闭美颜效果。 //美白级别:取值 0-9。值为 0 时,将关闭美白效果。默认值:0,关闭美白效果。 //ruddyLevel:取值范围为 0-9。值为 0 时关闭美白效果。默认值:0,关闭美白效果。 public boolean setBeautyFilter(int style, int beautyLevel, int whiteningLevel, int ruddyLevel);; public boolean setBeautyFilter(int style, int beautyLevel, int whiteningLevel, int ruddyLevel) 滤镜 setFilter 方法可以设置滤镜效果,滤镜本身是一个直方图文件。setSpecialRatio 方法可以设置滤镜的程度,从 0 到 1,越大滤镜效果越明显,默认值为 0.5。 Bitmap bitmap = BitmapUtils.decodeResource(getResources, R.drawable.langman); if (mLivePusher) if (mLivePusher ! = null) { mLivePusher.setFilter(bmp); } 控制摄像头 腾讯云 sdk 默认为前置摄像头(可以通过修改 TXLivePushConfig 的配置函数 setFrontCamera 来修改默认值),调用一次 switchCamera 就切换一次,注意切换摄像头前要确保 TXLivePushConfig 和 TXLivePusher 对象已经初始化。 mLivePushConfig.setFrontCamera(true); // 默认前置摄像头。 mLivePusher.switchCamera; //切换摄像头。 ⑦ 设置徽标水印 腾讯视频云目前支持两种设置水印的方式:一种是在流媒体 SDK 中设置水印,原理是在 SDK 中对视频进行编码前在画面中设置水印。另一种方式是在云端设置水印,即由云端解析视频并添加水印标识。 建议使用 SDK 添加水印,因为在云端添加水印会有问题。下面是添加水印的 SDK 介绍: //设置视频水印 mLivePushConfig.setWatermark(BitmapFactory.decodeResource(getResources,R.drawable.watermark), 10, 10); // 最后两个参数是视频的水印。 //最后两个参数是水印位置的 X 轴和 Y 轴坐标。 mLivePusher.setConfig(mLivePushConfig); 如果需要对水印图像的位置进行模型适配,则需要调用水印规范化接口。 /设置视频水印 mLivePushConfig.setWatermark(mBitmap, 0.02f, 0.05f, 0.2f); //参数为水印图像。 //参数包括水印图像的位图、水印位置的 X 轴坐标、水印位置的 Y 轴坐标和水印宽度。后三个参数的范围是 [0,1]。 // 最后两个参数是水印位置的 X 轴坐标和 Y 轴坐标。 mLivePusher.setConfig(mLivePushConfig); TXLivePushConfig 中的 setHardwareAcceleration 方法可以启用或禁用硬件编码。 if (mHWVideoEncode){ if (mLivePushConfig ! = null) { if (Build.VERSION.SDK_INT < 18){ Toast.makeText(getApplicationContext, "Hardware acceleration failed, current phone API level is too low (min 18)"、 Toast.LENGTH_SHORT).show; mHWVideoEncode = false; } } } } mLivePushConfig.setHardwareAcceleration(mHWVideoEncode ? TXLiveConstants.ENCODE_VIDEO_HARDWARE : TXLiveConstants.ENCODE_VIDEO_SOFTWARE); mLivePusher.setConfig(mLivePushConfig); // 如果您不确定何时启用硬件加速,建议将其设置为 ENCODE_VIDEO_AUTO。 // 默认情况下启用软件编码,但如果手机的 CPU 使用率超过 80% 或帧速率为 10,SDK 将自动切换到硬件编码。 ⑨ 后台推流 在常规模式下,一旦应用程序进入后台,摄像头捕捉数据的能力就会被 Android 禁用,这意味着 SDK 无法继续捕捉和编码音频和视频数据。如果我们什么都不做,故事就会按照下面的脚本发展: 阶段 1(背景剪切后 10 秒 ->)- CDN 无法将视频流传输给观众,因为没有数据,观众看到的是主帧。 阶段 2(10 秒-> 70 秒)--观众一方的播放器因无法接收到直播流而退出,房间里空无一人。 第 3 阶段(70 秒后)--服务器直接断开了推送流媒体的 RTMP 链接,主播需要重新打开直播才能继续。 主播可能只是短暂地接了一个紧急电话,但各云提供商的安全措施会迫使主播的直播提前结束。 1) 设置 setPauseFlag 在开始推流之前,使用 TXLivePushConfig 的 setPauseImg 接口设置一个等待图像,其含义建议为 "主播将暂时离开,稍后再回来"。