一起自学前端开发!

你不知道的前端音视频知识

来源:原创    更新时间:2021-12-12 16:45:22    编辑:前端网    浏览:148

Web 音视频的发展史

刀耕火种的年代——早期 HTML

在早期的 HTML,由于带宽、技术等各种因素限制,网页主要以简单的静态内容为主,只支持一些文字图片内容和简单的排版,不支持在线观看音视频。

139.jpg

(图为 1994 年的 Yahoo!)

迭起兴衰——Flash 的兴起与淘汰

20 世纪初,随着互联网的发展,各种 Web 应用和门户网站不断出现,人们渴望在网页上看到更加丰富多彩的内容,比如视频、动画等等,于是 Flash 进入了人们的视野。

彼时的 Flash 没有像现在大家印象中的那么臃肿,刚诞生的 Flash 小巧、高效、跨平台,同时凭借几十 K 的体积做出放大也不会失真的各种矢量彩色动画,在还是拨号上网,带宽条件受限,加载一个在线视频需要好几分钟的年代脱颖而出,甚至可以做出各种令人沉迷的 Flash 小游戏。

20211211235346.jpg

(Flash 塑造了很多经典的小游戏角色,火柴人就是其中之一)

Flash 的兴起,得益于当时 HTML 对于媒体文件支持的匮乏。Flash 以插件的形式,干着平台才需要负担的繁重工作,并得益于 Adobe 的大力推广,Flash 先后增加了对 Javascrip、HTML、XML 的支持,并增强了影音方面的功能。同时由于 Flash 跨平台的特性,非常容易被移植,市面上稍微高端点的设备,也得乖乖地给 Adobe 交授权费。

然而 2007 年推出的 iPhone 并不买账,他们以增加续航、安全为由抛弃了 Flash,很多人一开始对此嗤之以鼻,但事实证明苹果对此确实有远见,大量低质量的 Flash 使当时续航本就有限的移动设备更加不堪重负。2012 年,Android 也宣布不再支持 Flash,Flash 在移动市场不再有立足之地。

在桌面市场上,Flash 的日子也并不好过。Chrome 从的 Chrome 42 开始,就已经强制把 Flash 装入沙箱,以 PPAPI 的形式运行;而从 Chromium 版本号 88 开始,已经彻底不再支持 Flash 技术了。微软的 Edge 浏览器也同步不支持 Flash。Chrome 的前辈 Firefox 更加激进,从 2016 年就已经默认禁止 Flash 运行了。

至于 Flash 为什么走向了淘汰,除了它的效率变低,不安全因素过多,稳定性不足外,还有一个重要原因:Web 音视频解决方案有了更好的替代品—— HTML5。

新时代的潮流——HTML5 的到来

其实,对于 HTML5 是否可以真正替代 Flash,尤大在 2011 年已经给出了预言:

20211211235403.jpg

事实正如预言所预料,HTML5 在 2008 年发布后,经过不断改进完善,基本上能包办 Flash 所有能干的事情了。HTML5 引入了许多新特性和新功能,其中就包含了 video 和 audio 标签,也就是对音视频的支持。使用了支持 HTML5 标准的网络浏览器访问 HTML5 站点,用户无需在电脑上安装 Flash 插件就可以在线观看视频,摆脱了对 Flash 的依赖。

<!-- 一个简单的video标签 -->
<video src="movie.mp4" poster="movie.jpg" controls></video>

同时,各大视频门户网站也加入了对 HTML5 的支持,并默认推荐以 HTML5 的方式来播放视频。

20211211235413.jpg

2021 年 1 月 20 日,chrome 88 正式发布,彻底的禁止使用 Flash。自此,Flash 算是彻底退出了历史舞台。

到底什么是视频

视频,其实就是一系列连续播放的图片,如果一秒钟播放 24 张图片,那么人眼看到的就不再是一张张独立的图片,而是动起来的画面。其中一张图片称为一帧,1s 播放的图片数称为帧率。由于人类眼睛的特殊生理结构,如果所看画面之帧率高于每秒约 10-12 帧的时候,就会认为是连贯的;当看到帧率为 24 fps 以上时,大脑会认为这是流畅播放的视频。所以一般有声电影的拍摄及播放帧率大约为每秒 24 帧,欧美、日本那边由于电视制式不同,大约为 30 帧。

电影的帧率与游戏的帧率

为什么 24 帧的电影比 30 帧的游戏要流畅许多?

这其中的原因就在于,电影和游戏的图像生成原理不同。

电影的 24 fps,是每 1/24 秒拍摄一副画面,如果你玩过相机的手动设置,你应该知道如果以 1/24 秒的快门速度拍摄一个运动的物体会“糊”掉,而正是这样“糊”掉的画面连起来才让我们的眼睛看上去很“流畅”。

而游戏画面不是按 1/24 秒快门拍出来的,而是每一幅画面都是独立渲染出来的,之所以跑成 24fps 是因为显卡处理能力不够而“丢弃”了其中的一些画面,这样一来每两幅画面之间就不连续了,自然看上去会“卡”。

举个例子,一个圆从左上角移动到右下角,如果是电影,第一帧与第二帧可能是类似下图这样的:

20211212164024.jpg

如果是游戏画面,第一帧与第二帧会类似下面这两张图:

20211212164052.jpg

此外,帧与帧之间间隔恒定:人眼对于动态视频的捕捉是非常敏感的,电影帧率是固定不变,肉眼很难察觉出异常。

而游戏的帧率却是很容易变化的——如果手动锁定帧数,显卡会默认渲染最高帧率。

玩家触发的很多剧情往往伴随剧烈的画面变动,这时显卡的帧率就会出现下降,前后不一致的帧率很容易被肉眼捕捉,这时我们就会觉得,游戏变“卡”了。

视频的编码

视频是由图片构成的,图片是由像素构成的,假设尺寸为 1980*1080。每个像素由 RGB 构成,每个 8 位,共 24 位。

假设帧率是 24,那么每秒钟的视频的尺寸如下:

20211212164140.jpg

一分钟视频的尺寸就是 9237888000 Bytes 已经是 8.8 个 G 了。

可以看到,如果是不对视频做任何处理,是非常不方便对于视频做传输与存储的,所以需要对视频进行压缩,也就是编码。

视频编码

视频图像数据有很强的相关性,也就是说有大量的冗余信息。其中冗余信息可分为空域冗余信息时域冗余信息。压缩技术就是将数据中的冗余信息去掉(去除数据之间的相关性),压缩技术包含帧内图像数据压缩技术、帧间图像数据压缩技术和熵编码压缩技术。

经过编码之后,视频由一帧帧的图片,变成了一串串让人看不懂的二进制代码,因为编码的方式(算法)的不同,所以就有了编码格式的区分。常见的编码格式有 H.264,MPEG-4,VP8 等。

我们前端开发只需要记住一点,主流浏览器支持的视频编码格式是 H.264

音频编码

CD 音质的音频,存放一分钟数据需要的大小为 10M,太大了,也需要压缩(编码)。

常见的编码方式有:WAV、MP3 和 AAC 格式。

音频的编码方式不像视频那样那么多,而且音频在各个浏览器基本上都可以播放。

具体的每种编码格式包含的音频是怎么构成的,这里就不讲了。

20211212164222.jpg

封装格式

我们把视频数据、音频数据打包到一起,然后再添加一些基本信息,例如分辨率、时长、标题等,构成一个文件,这个文件称为封装格式。常见的封装格式有 MP4, AVI, RMVB 等。

20211212164259.jpg


可以看出,视频的封装格式和视频的编码格式往往是无关的,一个 mp4 文件,里面的视频流编码可以是 h264,也可以是 mpeg-4,所以就会出现,同样都是 mp4 文件,有的浏览器可以放,有的浏览器就放不了的问题,因为能不能放是由视频码流的编码格式决定的。

码率

码率,也叫比特率,帧率是 1s 播放多少帧,类比一下,比特率就是 1s 的视频有多少 bit。

这个参数直接决定了视频的大小与清晰程度。

一般网上流传的电影 MKV(BDrip-1080P)的码率是 10Mb/s 左右,蓝光原盘是 20Mb/s 左右,这两者都是 H.264 编码的。另外一些 MV、PV、演示片什么的除了 H.264 编码,可能还有 MPEG-2 编码,码率大小不等,像 youtube 那些在线的 1080P 的视频,码率可能只有 5Mb/s,而一些 MV 的码率可以高到离谱,可以达到 110Mb/s 的,3 分多钟的 MV 差不多有 3GB 大小。

而一般的视频剪辑、后期软件,在输出序列的时候,都会有码率这个选项。

20211212164325.jpg

视频播放器的原理

播放视频的基本流程是:解协议 → 解封装 → 解码 → 视音频同步。如果播放本地文件则不需要解协议。

20211212164341.jpg

解协议的作用,就是将流媒体协议的数据,解析为标准的相应的封装格式数据。视音频在网络上传播的时候,常常采用各种流媒体协议,例如 HTTP,RTMP,或是 MMS 等等。这些协议在传输视音频数据的同时,也会传输一些信令数据。这些信令数据包括对播放的控制(播放,暂停,停止),或者对网络状态的描述等。解协议的过程中会去除掉信令数据而只保留视音频数据。

解封装的作用,就是将输入的封装格式的数据,分离成为音频流压缩编码数据和视频流压缩编码数据。封装格式种类很多,例如 MP4,MKV,RMVB,TS,FLV,AVI 等等,它的作用就是将已经压缩编码的视频数据和音频数据按照一定的格式放到一起。例如,FLV 格式的数据,经过解封装操作后,输出 H.264 编码的视频码流和 AAC 编码的音频码流。

解码的作用,就是将视频/音频压缩编码数据,解码成为非压缩的视频/音频原始数据。音频的压缩编码标准包含 AAC,MP3,AC-3 等等,视频的压缩编码标准则包含 H.264,MPEG2,VC-1 等等。解码是整个系统中最重要也是最复杂的一个环节。通过解码,压缩编码的视频数据输出成为非压缩的颜色数据,例如 YUV420P,RGB 等等;压缩编码的音频数据输出成为非压缩的音频抽样数据,例如 PCM 数据。

视音频同步的作用,就是根据解封装模块处理过程中获取到的参数信息,同步解码出来的视频和音频数据,并将视频音频数据送至系统的显卡和声卡播放出来。

canvas 播放视频

如果我们碰到一些特殊机型或者特殊情况 HTML5 的 video 解决方案不是很好处理,也可以采用 Canvas 去播放这个视频。

使用 Canvas 播放视频主要是利用 ctx.drawImage(video, x, y, width, height) 来对视频当前帧的图像进行绘制,其中 video 参数就是页面中的 video 对象。所以如果我们按照特定的频率不断获取 video 当前画面,并渲染到 Canvas 画布上,就可以实现使用 Canvas 播放视频的功能。

<video id="video" controls="controls" style="display: none;">
    <source src="https://xxx.com/vid_159411468092581" />
</video>
<canvas  id="myCanvas"  width="460"  height="270"  style="border: 1px solid blue;"  ></
canvas>
<div>
    <button id="playBtn">播放</button>
    <button id="pauseBtn">暂停</button>
</div>


const video = document.querySelector("#video");
const canvas = document.querySelector("#myCanvas");
const playBtn = document.querySelector("#playBtn");
const pauseBtn = document.querySelector("#pauseBtn");
const context = canvas.getContext("2d");
let timerId = null;
function draw({
    if (video.paused || video.ended) return;
    context.clearRect(00, canvas.width, canvas.height);
    context.drawImage(video, 00, canvas.width, canvas.height);
    timerId = setTimeout(draw, 0);
}
playBtn.addEventListener("click", () => {
    if (!video.paused) return;
    video.play();
    draw();
});
pauseBtn.addEventListener("click", () => {
    Tag标签标签: 前端周边 前端文章

上一篇:2021-2022年最新前端开发学习路线详细版(二)

下一篇:已经是最后一篇

评论区

表情

共0条评论
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~

相关内容