噪点与烟雾效果,利用分层优化

2019-11-22 01:25栏目:人才招聘
TAG:

canvas图形绘制之星空、噪点与烟雾效果

2016/06/07 · HTML5 · 1 评论 · Canvas

原文出处: 张鑫旭(@张鑫旭)   

H5直播起航

2016/10/31 · HTML5 · 开发

原文出处: 凹凸实验室   

图片 1

利用分层优化 HTML5 画布渲染

2015/02/02 · HTML5 · HTML5

原文出处: IBM developerworks   

一、三合一

三个效果合成一篇文章。

有多个小伙伴问我,为何不开个公众号,现在都是移动时代,你博客文章写好后,公众号再复制一份,花不了多长时间,同时传播方便迅速,打赏方便快捷,显然低成本高收益。

从眼前来看,似乎确实如此。

但是,就我个人而言,行为和处事准则总是遵循内心的直觉和大方向的指引。说不上具体的道理,就是觉得,作品的输出源如果不止一个,久远来看,带来的未知损耗一定要大于短期的已知收益。

取巧的事情多慎思而克己,就好比本文内容,实际上,三个不同的canvas效果,直接分3篇来写,凑个文章数,增加点浏览量其实也是无可厚非的。然,想了想,有点不像自己的style,内心真实的自己并不希望自己这么做,于是,就3个效果合体为一篇文章。

拒绝小部分的诱惑,让自己过得更轻松。

本文的3个效果都是源自我最近做的几个真实的项目,是canvas领域基本入门的一些效果。代码我都专门重新梳理了下,必要注释也都加上去了,方便大家的学习。然后,如果你有不懂的地方,请不要来问我,没错,是不要,我并不欢迎你找我来交流,自己一点一点去弄明白。因为,如果连这么基本的canvas效果都不理解,我真的也帮不了你什么。倒不是说腾不出时间,而是腾不出精力,每天微博私信还有邮箱找我的人还挺多,实在应接不暇。

前言

前不久抽空对目前比较火的视频直播,做了下研究与探索,了解其整体实现流程,以及探讨移动端HTML5直播可行性方案。

发现目前 WEB 上主流的视频直播方案有 HLS 和 RTMP,移动 WEB 端目前以 HLS 为主(HLS存在延迟性问题,也可以借助 video.js 采用RTMP),PC端则以 RTMP 为主实时性较好,接下来将围绕这两种视频流协议来展开H5直播主题分享。

简介

通常情况下,在玩 2D 游戏或渲染 HTML5 画布时,需要执行优化,以便使用多个层来构建一个合成的场景。在 OpenGL 或 WebGL 等低级别渲染中,通过逐帧地清理和绘制场景来执行渲染。实现渲染之后,需要优化游戏,以减少渲染的量,所需成本因情况而异。因为画布是一个 DOM 元素,它使您能够对多个画布进行分层,以此作为一种优化方法。

二、canvas图形效果之旋转星空

图片 2

图是死的,效果是活的,IE9+浏览器下,您可以狠狠地点击这里:canvas实现的旋转星空效果demo

会看到地球上方会有很多星星在慢慢地绕着地球转啊转,星星在闪啊闪。

像这类密集型canvas效果,一般离不开下面这几个关键字:实例,随机,变化与重绘,requestAnimationFrame。

原理就是:

  1. 先画一个位置透明度随机的静态的星星实例对象;
  2. 有一个可以改变星星位置和透明度的draw方法;
  3. 定时器跑起来,画布不停地清除与绘制,动画效果完成!

原理很简单。

本例子实现的2个难点在于:

  1. 月明星稀
    星星垂直方向实际上是个伪随机,越靠近地球,星星越密集,而越往上,越稀疏。其算法如下:
JavaScript

var getMinRandom = function() { var rand = Math.random(); //
step的大小决定了星星靠近地球的聚拢程度, // step = Math.ceil(2 /
(1 - rand))就聚拢很明显 var step = Math.ceil(1 / (1 - rand)); var
arr = []; for (var i=0; i<step; i++) { arr.push(Math.random());
} return Math.min.apply(null, arr); };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-12">
12
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4a6436b2b195965046-1" class="crayon-line">
var getMinRandom = function() {
</div>
<div id="crayon-5b8f4a6436b2b195965046-2" class="crayon-line crayon-striped-line">
    var rand = Math.random();
</div>
<div id="crayon-5b8f4a6436b2b195965046-3" class="crayon-line">
    // step的大小决定了星星靠近地球的聚拢程度,
</div>
<div id="crayon-5b8f4a6436b2b195965046-4" class="crayon-line crayon-striped-line">
    // step = Math.ceil(2 / (1 - rand))就聚拢很明显
</div>
<div id="crayon-5b8f4a6436b2b195965046-5" class="crayon-line">
    var step = Math.ceil(1 / (1 - rand));
</div>
<div id="crayon-5b8f4a6436b2b195965046-6" class="crayon-line crayon-striped-line">
    var arr = [];
</div>
<div id="crayon-5b8f4a6436b2b195965046-7" class="crayon-line">
    for (var i=0; i&lt;step; i++) {
</div>
<div id="crayon-5b8f4a6436b2b195965046-8" class="crayon-line crayon-striped-line">
        arr.push(Math.random());
</div>
<div id="crayon-5b8f4a6436b2b195965046-9" class="crayon-line">
    }
</div>
<div id="crayon-5b8f4a6436b2b195965046-10" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f4a6436b2b195965046-11" class="crayon-line">
    return Math.min.apply(null, arr);       
</div>
<div id="crayon-5b8f4a6436b2b195965046-12" class="crayon-line crayon-striped-line">
};
</div>
</div></td>
</tr>
</tbody>
</table>

很大概率会返回一个数值偏小的值,于是,就可以有“月明星稀”的分布效果了。
  1. 圆弧轨迹
    其实很简单,我们套用高中时候学的圆方程式就可以了,如下注释截图所述:
    图片 3这下题目就简单了,已知a,b, 求y相对于x的函数表达式……

一、视频流协议HLS与RTMP

常用的缩写

  • CSS: Cascading Style Sheets(级联样式表)
  • DOM: Document Object Model(文档对象模型)
  • HTML: HyperText Markup Language(超文本标记语言)

本文将探讨对画布进行分层的合理性。了解 DOM 设置,从而实现分层的画布。使用分层进行优化需要各种实践。本文还将探讨一些优化策略的概念和技术,它们扩展了分层方法。

您可以下载在本文中使用的示例的源代码。

三、canvas图形效果之雪花噪点效果

图片 4

图是死的,效果这里也是死的,但并不妨碍我们零距离围观,您可以狠狠地点击这里:canvas实现的噪点效果demo

由于这里是静态的,所以但从这一点来看,似乎比上面星空简单。但是,如果仅仅看绘制一帧,那这里的噪点要比上面的星空要困难些,最大的难点在于对性能的把控。

这么说吧,上面的星空,总共最多就400个点(白色的星星),但是,这里的噪点,例如,demo中画布大小(那我的机子举例)是1920*500,其中,噪点大小是1像素*1像素,总共就有960000个绘制点,显然跟400个点完全不是一个数量级的,如果我们真的一个一个绘制下来,肯定,就连Chrome这么牛步的浏览器也会感觉到明显的卡顿,如何优化如何绘制呢?

这就是本例子实现的难点:

  1. 数量与性能
    我这里是这么处理的,虽然最终的噪点大小是1920*500,但是,我们实际上是由N块300*150的小的像瓷砖一样的小方块拼起来的。话句话说,我实际只绘制了45000个点,比960000显然要小了20倍还不止。这样,既满足了效果,又保证了性能。

具体实现原理为:

  1. 创建一个canvas,绘制一个300*150随机噪点图形;
  2. 把这里具有噪点的canvas以画布形式在绘制到页面上的大canvas上;

说得canvas绘图,不得不提一下非常常用的一个drawImage()方法,语法如下:

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

1
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

各个参数示意为(网上的描述都是直译,很生涩,我这里重新陈述了下):

参数 描述
img 用来被绘制的图像、画布或视频。
sx 可选。img被绘制区域的起始左上x坐标。
sy 可选。img被绘制区域的起始左上y坐标。
swidth 可选。img被绘制区域的宽度。
sheight 可选。img被绘制区域的高度。
x 画布上放置img的起始x坐标。
y 画布上放置img的起始y坐标。
width 可选。画布上放置img提供的宽度。(伸展或缩小图像)
height 可选。画布上放置img提供的高度。(伸展或缩小图像)

本例的小的噪点区块就是通过drawImage()方法被平铺到大的canvas元素上的。

1. HTTP Live Streaming

HTTP Live Streaming(简称 HLS)是一个基于 HTTP 的视频流协议,由 Apple 公司实现,Mac OS 上的 QuickTime、Safari 以及 iOS 上的 Safari 都能很好的支持 HLS,高版本 Android 也增加了对 HLS 的支持。一些常见的客户端如:MPlayerX、VLC 也都支持 HLS 协议。

HLS 协议基于 HTTP,而一个提供 HLS 的服务器需要做两件事:

  • 编码:以 H.263 格式对图像进行编码,以 MP3 或者 HE-AAC 对声音进行编码,最终打包到 MPEG-2 TS(Transport Stream)容器之中;
  • 分割:把编码好的 TS 文件等长切分成后缀为 ts 的小文件,并生成一个 .m3u8 的纯文本索引文件;

浏览器使用的是 m3u8 文件。m3u8 跟音频列表格式 m3u 很像,可以简单的认为 m3u8 就是包含多个 ts 文件的播放列表。播放器按顺序逐个播放,全部放完再请求一下 m3u8 文件,获得包含最新 ts 文件的播放列表继续播,周而复始。整个直播过程就是依靠一个不断更新的 m3u8 和一堆小的 ts 文件组成,m3u8 必须动态更新,ts 可以走 CDN。一个典型的 m3u8 文件格式如下:

#EXTM3U

#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000
gear1/prog_index.m3u8

#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=311111
gear2/prog_index.m3u8

#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=484444
gear3/prog_index.m3u8

#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=737777
gear4/prog_index.m3u8

可以看到 HLS 协议本质还是一个个的 HTTP 请求 / 响应,所以适应性很好,不会受到防火墙影响。但它也有一个致命的弱点:延迟现象非常明显。如果每个 ts 按照 5 秒来切分,一个 m3u8 放 6 个 ts 索引,那么至少就会带来 30 秒的延迟。如果减少每个 ts 的长度,减少 m3u8 中的索引数,延时确实会减少,但会带来更频繁的缓冲,对服务端的请求压力也会成倍增加。所以只能根据实际情况找到一个折中的点。

对于支持 HLS 的浏览器来说,直接这样写就能播放了:

XHTML

<video src="" height="300" width="400" preload="auto" autoplay="autoplay" loop="loop" webkit-playsinline="true"></video>

1
2
<video src="http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"
height="300" width="400" preload="auto" autoplay="autoplay" loop="loop" webkit-playsinline="true"></video>

注意:HLS 在 PC 端仅支持safari浏览器,类似chrome浏览器使用HTML5 video标签无法播放 m3u8 格式,可直接采用网上一些比较成熟的方案,如:sewise-player、MediaElement、videojs-contrib-hls、jwplayer。

选择优化策略

选择最佳优化策略可能很难。在选择分层的场景时,需要考虑场景是如何组成的。大屏幕上固定物的渲染经常需要重用若干个组件,它们是进行研究的极佳候选人。视差或动画实体等效果往往需要大量的变化的屏幕空间。在探索您的最佳优化策略时,最好注意这些情况。虽然画布的分层优化需要采用几种不同的技术,但在正确应用这些技术后,往往会大幅提升性能。

四、canvas图形效果之烟雾缭绕效果

图片 5

图是死的,效果是活的,IE9+浏览器下,您可以狠狠地点击这里:canvas实现的烟雾缭绕效果demo

本例子,效果看上去要更酷一些,实际上,从技术层面讲,跟上面的星空旋转效果几乎如出一辙,可能还要比星空更简单一些,因为其运动轨迹直来直往,不需要转圈圈。

那为何看上去更酷呢,主要在于感觉烟雾很难去模拟。

没错,烟雾确实很难用代码直接绘制出来,实际上,这里的烟雾,是一个png图片,是使用画笔在PS里绘制导出来的。

旋转星空的例子,我们是使用canvas的fillRect方法绘制了星星,而本例子,则是使用上面提到的drawImage()方法把烟雾图片绘制进来了。

其他的位移啊,透明度变化什么的,原理都是类似。

本例子的难点主要在于模拟是否足够真实:

  1. 高处不胜寒
    越往上,烟雾越淡,实际上就是越靠近上方,透明度越低;
// 越靠近边缘,透明度越低 // 纵向透明度变化要比横向的明显 this.alpha
= (1 - Math.abs(canvasWidth*0.5 - this.x) / canvasWidth) * (0.7 -
Math.abs(canvasHeight*0.5 - this.y) / canvasHeight);

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4a6436b3d419634939-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b3d419634939-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b3d419634939-3">
3
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4a6436b3d419634939-1" class="crayon-line">
// 越靠近边缘,透明度越低
</div>
<div id="crayon-5b8f4a6436b3d419634939-2" class="crayon-line crayon-striped-line">
// 纵向透明度变化要比横向的明显
</div>
<div id="crayon-5b8f4a6436b3d419634939-3" class="crayon-line">
this.alpha = (1 - Math.abs(canvasWidth*0.5 - this.x) / canvasWidth) * (0.7 - Math.abs(canvasHeight*0.5 - this.y) / canvasHeight);
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 缭绕
    所谓“缭绕”,就是运动看似不具有规律性。要知道,凡事有轨迹有套路的运动都是有规律性地,你说这烟雾上上下下,左左右右运动太过于规律,效果就会打折扣,但是,真的没有规律又不好通过代码控制运动轨迹。因此,为了搞到一个接近缭绕效果的运动函数,还真是烧了不少脑细胞。

2. Real Time Messaging Protocol

Real Time Messaging Protocol(简称 RTMP)是 Macromedia 开发的一套视频直播协议,现在属于 Adobe。这套方案需要搭建专门的 RTMP 流媒体服务如 Adobe Media Server,并且在浏览器中只能使用 Flash 实现播放器。它的实时性非常好,延迟很小,但无法支持移动端 WEB 播放是它的硬伤。

虽然无法在iOS的H5页面播放,但是对于iOS原生应用是可以自己写解码去解析的, RTMP 延迟低、实时性较好。

浏览器端,HTML5 video标签无法播放 RTMP 协议的视频,可以通过 video.js 来实现。

XHTML

<link href="" rel="stylesheet">   <video id="example_video_1" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264" loop="loop" webkit-playsinline> <source src="rtmp://10.14.221.17:1935/rtmplive/home" type='rtmp/flv'> </video>   <script src="; <script> videojs.options.flash.swf = 'video.swf'; videojs('example_video_1').ready(function() { this.play(); }); </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
<link href="http://vjs.zencdn.net/5.8.8/video-js.css" rel="stylesheet">
 
<video id="example_video_1" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264" loop="loop" webkit-playsinline>
<source src="rtmp://10.14.221.17:1935/rtmplive/home" type='rtmp/flv'>
</video>
 
<script src="http://vjs.zencdn.net/5.8.8/video.js"></script>
<script>
videojs.options.flash.swf = 'video.swf';
videojs('example_video_1').ready(function() {
this.play();
});
</script>

设置层

在使用分层的方法时,第一步是在 DOM 上设置画布。通常情况下,这很简单,只需定义画布元素,将其放入 DOM 中即可,但画布层可能需要一些额外的样式。在使用 CSS 时,成功地实现画布分层有两个要求:

  • 各画布元素必须共存于视区 (viewport) 的同一位置上。
  • 每个画布在另一个画布下面必须是可见的。

图 1显示了层设置背后的通用重叠概念。

五、canvas动效与结语

本文三个例子都是canvas 2D效果,是入门学习非常好的例子。

canvas非常适合实现密集型图形和动画,可以把性能优势给发挥出来,因为就是一块画布渲染;另外一点就是省流量,比方说第2个例子的噪点效果,如果是同样效果1920*500的png图片,科科,我特意保存了下,286K,1K的代码PK 286K的图片,显然是完爆啊!

canvas还支持3D效果,也就是webGL, 亦称3D Canvas graphics, IE11+支持,目前Android 4.*任意版本都还不支持,业内著名的相关库就是threejs了。

不过,我没研究过,也没兴趣,不是我的方向。

好了,就这些,感谢阅读。

1 赞 7 收藏 1 评论

图片 6

3. 视频流协议HLS与RTMP对比

协议 原理 延时 优点 使用场景
HLS 短链接Http 集合一段时间数据生成ts切片文件更新m3u8文件 10s – 30s 跨平台 移动端为主
RTMP 长链接Tcp 每个时刻的数据收到后立即发送 2s 延时低、实时性好 PC+直播+实时性要求高+互动性强
图 1. 层示例

图片 7

设置层的步骤如下:

  1. 将画布元素添加到 DOM。
  2. 添加画布元素定位样式,以便支持分层。
  3. 样式化画布元素,以便生成一个透明的背景。

二、直播形式

图片 8

目前直播展示形式,通常以YY直播、映客直播这种页面居多,可以看到其结构可以分成三层:① 背景视频层 ② 关注、评论模块 ③ 点赞动画

而现行H5类似直播页面,实现技术难点不大,其可以通过实现方式分为:① 底部视频背景使用video视频标签实现播放 ② 关注、评论模块利用 WebScoket 来实时发送和接收新的消息通过DOM 和 CSS3 实现 ③ 点赞利用 CSS3 动画

了解完直播形式之后,接下来整体了解直播流程。

设置画布重叠堆栈

在 CSS 中创建一个重叠堆栈 (overlay stack) 可能需要少量的样式。使用 HTML 和 CSS 有许多方法进行重叠。本文中的示例使用一个<div>标签来包含画布。<div>标签指定了一个惟一 ID,它将样式应用于其子 HTML5 画布元素,如清单 1所示。

三、直播整体流程

直播整体流程大致可分为:

  • 视频采集端:可以是电脑上的音视频输入设备、或手机端的摄像头、或麦克风,目前以移动端手机视频为主。
  • 直播流视频服务端:一台Nginx服务器,采集视频录制端传输的视频流(H264/ACC编码),由服务器端进行解析编码,推送RTMP/HLS格式视频流至视频播放端。
  • 视频播放端:可以是电脑上的播放器(QuickTime Player、VLC),手机端的native播放器,还有就是 H5 的video标签等,目前还是以手机端的native播放器为主。

图片 9

清单 1. 画布定位样式

CSS

#viewport { /** * Position relative so that canvas elements * inside of it will be relative to the parent */ position: relative; } #viewport canvas { /** * Position absolute provides canvases to be able * to be layered on top of each other * Be sure to remember a z-index! */ position: absolute; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#viewport {
    /**
     * Position relative so that canvas elements
     * inside of it will be relative to the parent
     */
    position: relative;
}
 
#viewport canvas {
    /**
     * Position absolute provides canvases to be able
     * to be layered on top of each other
     * Be sure to remember a z-index!
     */
    position: absolute;
}

容器<div>通过将所有子画布元素样式化为使用绝对定位来完成重叠要求。通过选择让#viewport使用相对定位,您可以适应未来的发展,因此,应用于子样式的绝对布局样式将会是相对于#viewport容器的样式。

这些 HTML5 画布元素的顺序也很重要。可以按元素出现在 DOM 上的顺序进行顺序管理,也可以按照画布应该显示的顺序来样式化 z-index 样式,从而管理顺序。虽然并非总是如此,但其他样式可能也会影响渲染;在引入额外的样式(比如任何一种 CSS 转换)时要小心。

四、H5 录制视频

对于H5视频录制,可以使用强大的 webRTC (Web Real-Time Communication)是一个支持网页浏览器进行实时语音对话或视频对话的技术,缺点是只在 PC 的 Chrome 上支持较好,移动端支持不太理想。

透明的背景

通过使用重叠可见性来实现层技术的第二个样式要求。该示例使用这个选项来设置 DOM 元素背景颜色,如清单 2所示。

1. 使用 webRTC 录制视频基本流程

① 调用 window.navigator.webkitGetUserMedia() 获取用户的PC摄像头视频数据。
② 将获取到视频流数据转换成 window.webkitRTCPeerConnection (一种视频流数据格式)。
③ 利用 WebScoket 将视频流数据传输到服务端。

注意:虽然Google一直在推WebRTC,目前已有不少成型的产品出现,但是大部分移动端的浏览器还不支持 webRTC(最新iOS 10.0也不支持),所以真正的视频录制还是要靠客户端(iOS,Android)来实现,效果会好一些。
图片 10

清单 2. 设置透明背景的样式表规则

JavaScript

canvas { /** * Set transparent to let any other canvases render through */ background-color: transparent; }

1
2
3
4
5
6
canvas {
    /**
     * Set transparent to let any other canvases render through
     */
    background-color: transparent;
}

将画布样式化为拥有一个透明背景,这可以实现第二个要求,即拥有可见的重叠画布。现在,您已经构造了标记和样式来满足分层的需要,所以您可以设置一个分层的场景。

2. iOS原生应用调用摄像头录制视频流程

① 音视频的采集,利用AVCaptureSession和AVCaptureDevice可以采集到原始的音视频数据流。
② 对视频进行H264编码,对音频进行AAC编码,在iOS中分别有已经封装好的编码库(x264编码、faac编码、ffmpeg编码)来实现对音视频的编码。
③ 对编码后的音、视频数据进行组装封包。
④ 建立RTMP连接并上推到服务端。

图片 11

分层方面的考虑因素

在选择优化策略时,应该注意使用该策略时的所有权衡。对 HTML5 画布场景进行分层是一个侧重于运行时内存的策略,用于获得运行时速度方面的优势。您可以在页面的浏览器中增加更多的权重,以获得更快的帧速率。一般来说,画布被视为是浏览器上的一个图形平面,其中包括一个图形 API。

通过在 Google Chrome 19 进行测试,并记录浏览器的选项卡内存使用情况,您可以看到内存使用的明显趋势。该测试使用了已经样式化的<div>(正如上一节中讨论的那样),并生成了放置在<div>上的用单一颜色填充的画布元素。画布的大小被设定为 1600 x 900 像素,并从 Chrome1 的任务管理器实用程序收集数据。表 1显示了一个示例。

在 Google Chrome 的 Task Manager 中,您可以看到某个页面所使用的内存量(也称为 RAM)。Chrome 也提供 GPU 内存,或者是 GPU 正在使用的内存。这是常见信息,如几何形状、纹理或计算机将您的画布数据推送到屏幕可能需要的任何形式的缓存数据。内存越低,放在计算机上的权重就会越少。虽然目前还没有任何确切的数字作为依据,但应始终对此进行测试,确保您的程序不会超出极限,并使用了过多的内存。如果使用了过多的内存,浏览器或页面就会因为缺乏内存资源而崩溃。GPU 处理是一个远大的编程追求,已超出本文的讨论范围。您可以从学习 OpenGL 或查阅 Chrome 的文档(请参阅参考资料)开始。

五、搭建Nginx+Rtmp直播流服务

表 1. 画布层的内存开销
层数 内存 GPU 内存
0 30.0 11.9
1 37.6 28.9
1 37.6 28.9
2 49.0 46.6
3 52.2 59.6
8 58.4 98.0
16 65.0 130
32 107 187

在表 1中,随着在页面上引入和使用了更多的 HTML5 画布元素,使用的内存也越多。一般的内存也存在线性相关,但每增加一层,内存的增长就会明显减少。虽然这个测试并没有详细说明这些层对性能带来的影响,但它确实表明,画布会严重影响 GPU 内存。一定要记得在您的目标平台上执行压力测试,以确保平台的限制不会导致您的应用程序无法执行。

当选择更改某个分层解决方案的单一画布渲染周期时,需考虑有关内存开销的性能增益。尽管存在内存成本,但这项技术可以通过减小每一帧上修改的像素数量来完成其工作。

下一节将说明如何使用分层来组织一个场景。

1. 安装nginx、nginx-rtmp-module

① 先clone nginx项目到本地:

Shell

brew tap homebrew/nginx

1
brew tap homebrew/nginx

② 执行安装nginx-rtmp-module

Shell

brew install nginx-full --with-rtmp-module

1
brew install nginx-full --with-rtmp-module

对场景进行分层:游戏

在本节中,我们将通过重构一个滚动平台跑步风格的游戏上的视差效果的单画布实现,了解一个多层解决方案。图 2显示了游戏视图的组成,其中包括云、小山、地面、背景和一些交互实体。

版权声明:本文由ag真人发布于人才招聘,转载请注明出处:噪点与烟雾效果,利用分层优化