HTML躬行记(4)——Web音视频基础

本文涉及的产品
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: HTML躬行记(4)——Web音视频基础

 公司目前的业务会接触比较多的音视频,所以有必要了解一些基本概念。

  文章涉及的一些源码已上传至 Github,可随意下载。


一、基础概念


  本节音视频的基础概念摘自书籍《FFmpeg入门详解 音视频原理及应用》。

1)音频

  声音的三要素为频率、振幅和波形,即声音的音调、声波的响度和声音的音色。

  音频是一种利用数字化手段对声音进行录制、存放、编辑、压缩和播放的技术,相关概念包括采样、量化、编码、采样率、声道数和比特率等。

  采样是指只在时间轴上对信号进行数字化。

  量化是指在幅度轴上对信号进行数字化。

  每个量化都是一个采样,将这么多采样进行存储就叫做编码。

  声道数是指所支持的能发不同声音的音响个数,常见的有单声道、立体声道等。

  比特率,也叫码率(b/s)指一个数据流中每秒能通过的信息量。

  WebRTC 对音频的噪声抑制和回声消除做了很好的处理。

  音频格式是指要在计算机内播放或处理的音频文件的格式,是对声音文件进行数、模转换的过程,常见的有 MP3、WAV、AAC 等。

  音频信号能压缩的依据包括声音信号中存在大量的冗余度,以及人的听觉具有强音能抑制同时存在的弱音现象。

  压缩编码原理是在压缩掉冗余的信号,冗余信号是指不能被人耳感知到的信息,包括听觉范围之外以及被掩蔽掉的音频信号,压缩编码分为 2 类。

  1. 无损压缩:熵编码,包括哈夫曼、算术和行程等编码。
  2. 有损压缩:波形、参数、混合等编码,波形编码包括 PCM、DPCM、ADPCM、子带编码、矢量量化等。

2)视频

  视频泛指将一系列静态影像以电信号的方式加以捕捉、记录、处理、存储、传送与重现的各种技术。

  帧(Frame)是视频的一个基本概念,表示一副画面,一段视频由许多帧组成。

  视频帧又分为 I 帧、P 帧和 B 帧:

  1. I 帧是帧内编码帧,是一个完整都关键帧,无需辅助就能完整显示画面;
  2. P 帧是前向预测编码帧,是一个非完整帧,需要参考前面的 I 帧或 P帧生成画面;
  3. B 帧是双向预测编码帧,需要参考前后图像帧编码生成。

  帧率(f/s 或 Hz)是单位时间内帧的数量,电视一般 1 秒 24 帧,帧率越高,画面越流畅、逼真。

  码率即比特率(b/s),指单位时间内播放连续媒体(如压缩后的音频或视频)的比特数量,码率越高带宽消耗得就越多。

  视频格式非常多,包括视频文件格式、视频封装格式和视频编码格式等。

  视频文件格式有 MP4、RMVB、MKV、FLV、TS、M3U8 等。FLV 是一种流媒体格式,TS 广泛应用于数字广播系统。

  M3U8 是使用 HLS 协议格式的基础,文件内容是一个播放列表(Playlist),采用 UTF-8 编码,记录了一些列媒体片段资源,顺序播放片段即可完整展示资源,如下所示。

#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=150000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/low/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=240000,RESOLUTION=416x234,CODECS="avc1.42e00a,mp4a.40.2"
http://example.com/lo_mid/index.m3u8
#EXTINF:15.169000
94256c7244451f8fd_20221020113637199.ts
#EXT-X-ENDLIST

  其中 codecs 参数提供解码特定流所需的编解码器的完整信息。之所以使用 ts 格式的片段是为了可以无缝拼接,让视频连续。

  HLS(HTTP Live Steaming,HTTP 直播流协议)的工作原理是把整个流分成一个一个的基于 HTTP 的文件来下载,每次只下载部分。

  视频封装格式也叫容器,可以将已经编码并压缩好的视频轨和音频轨按照一定的格式放到一个文件中。

  视频编码格式能够对数字视频进行压缩或解压缩的程序或设备,也可以指通过特定的压缩技术,将某种视频格式转换成另一种视频格式。

  常见的视频编码格式有几个大系列,包括 MPEG-X、H.26X 和 VPX 等。

  H.264(H.264/MPEG-4 或 AVC)是一种被广泛使用的高精度视频的录制、压缩和发布格式,H.265 是它的继任者。

  一个原始视频,若没有编码,则体积会非常大。假设图的分辨率是 1920*1080,帧率为 30,每像素占 24b,那没张图占 6.22MB左右,1 秒的视频大小是 186.6MB左右,1 分钟就是 11G了。

  对原始视频进行压缩的目的是去除冗余信息,这些信息包括:

  1. 空间冗余,在图像数据中,像素间在行、列方向上都有很大的相关性,相邻像素的值比较接近或者完全相同。
  2. 时间冗余,在视频图像序列中,相邻两帧又许多共同的地方,可采用运动补偿算法来去掉冗余。
  3. 视觉冗余,相对于人眼的视觉特性而言,人类视觉系统对图像的敏感性是非均匀和非线性的,并不是所有变化都能被观察到。
  4. 结构冗余,在图像的纹理区,以及图像的像素值存在明显的分布模式。
  5. 知识冗余,对许多图像的理解与某些先验知识有相当大的相关性,这类规律可由先验知识和背景知识得到。

  视频播放器播放本地视频文件或互联网上的流媒体文件大概需要解协议、解封装、解码、音视频同步、渲染等几个步骤,如下图所示。

  


二、Web中的音视频


  HTML5 标准推出后,提供了播放视频的 video 元素,以及播放音频的 audio 元素。

  为了能更精准的控制时间、容器格式转换、媒体质量和内存释放等复杂的媒体处理,W3C 推出了 MSE(Media Source Extensions)媒体源扩展标准。

  若要访问浏览器中已有的编解码器,可以试试 WebCodecs,它可以访问原始视频帧、音频数据块、图像解码器、音频和视频编码器和解码器。

  在浏览器中主流的视频编码格式是 H.264/MPEG-4,不过需要支付专利费。

  

  而 Google 推出的开源编码格式:VP8,除了 IE 之外,其他浏览器的高版本都能支持。

  

  最新的 H.265 和 VP9 在浏览器的兼容性上都不理想,有些第三方库会自己写一个 H.265 的解码器脚本,然后来播放视频。

1)播放器

  直播使用 video 元素播放视频很多功能都无法满足,因此很多时候都会引入一个播放器,例如 video.jsreact-player 等。

  这些播放器都能支持多种格式的视频,例如 flv、m3u8、mp4 等;并且有完整的控制键,例如音量、缩放、倍速等,覆盖移动和 PC 两个平台,以及可引入插件等。

  下图是一种播放器的整体架构图,来源于《Web端H.265播放器研发解密》。

  

  除了常规的使用 video 元素播放视频之外,还可以用 canvas 播放,具体实现可以参考 JSMpeg

2)MSE

  在 MSE 规范中,提供了 MediaSource 对象,它可以附着在 HTMLMediaElement 中,即 video 元素的 src 的属性值可以是它。

  一个 MediaSource 包含一个或多个 SourceBuffer 实例(下图来源于W3C官网),SourceBuffer 表示通过 MediaSource 传递到 HTMLMediaElement 并播放的媒体片段。

  

  下面是一个使用 MSE 的完整示例,修改了 MDN 中的代码首先是声明视频路径和 MIME 参数,注意,要正确指定 codecs 参数,否则视频无法播放。

const video = document.getElementById('video');
const assetURL = 'demo.mp4';
const mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';

  然后实例化 MediaSource 类,并将其与 video 元素关联,注册 sourceopen 事件。

const mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);

  最后实现 sourceOpen 函数,通过 fetch() 请求视频资源,将读取到的 ArrayBuffer 数据附加到 sourceBuffer 中。

function sourceOpen(e) {
  URL.revokeObjectURL(video.src);
  const mediaSource = e.target;
  // 创建指定 MIME 类型的 SourceBuffer 并添加到 MediaSource 的 SourceBuffers 列表
  const sourceBuffer = mediaSource.addSourceBuffer(mime);
  // 请求资源
  fetch(assetURL)
    .then(function(response) {
      return response.arrayBuffer();    // 转换成 ArrayBuffer
    })
    .then(function(buf) {
      sourceBuffer.addEventListener('updateend', function() {
        if (!sourceBuffer.updating && mediaSource.readyState === 'open') {
          mediaSource.endOfStream();    // 视频流传输完成后关闭流
          video.play();
        }
      });
      sourceBuffer.appendBuffer(buf); // 添加已转换成 ArrayBuffer 的视频流数据
    });
}

  为 sourceBuffer 注册 updateend 事件,并在视频流传输完成后关闭流。

  注意,要想看到视频的播放,不能直接静态 HTML 文件,需要将文件附加到 HTTP 服务器中。

  本文借助 Node.js,搭建了一个极简的 HTTP 服务器,当然也可以将 HTML 文件挂载到 Nginx 或 IIS 服务器中。

const http = require('http');
const fs = require('fs');
// HTTP服务器
const server = http.createServer((req, res) => {
  // 实例化 URL 类
  const url = new URL(req.url, 'http://localhost:1000');
  const { pathname } = url;
  // 路由
  if(pathname === '/') {
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end(fs.readFileSync('./index.html'));
  }else if(pathname === '/demo.mp4') {
    res.writeHead(200, { 'Content-Type': 'video/mp4' });
    res.end(fs.readFileSync('./demo.mp4'));
  }else if(pathname === '/client.js') {
    res.writeHead(200, { 'Content-Type': 'application/javascript' });
    res.end(fs.readFileSync('./client.js'));
  }
});
server.listen(1000);

  B站的 flv.js 播放器是依赖 MSE,可自动解析 flv 格式的文件并在 video 元素中播放,完全抛弃了 Flash。

  顺便说一句,flv 格式的数据传输一般采用 RTMP(Real Time Messaging Protocol)直播协议,这是由 Adobe 公司提出的私有协议,工作在 TCP 协议之上。

 

参考资料:

视频和音频内容

网页视频编码指南

Support for ISOBMFF-based MIME types in Browsers

WebRTC应用该使用哪种音视频编解码器

三种视频流浏览器播放解决方案

Web端H.265播放器研发解密

从 Chrome 源码 video 实现到 Web H265 Player

Web音视频串流

WebCodecs对音视频进行编码解码

Media Source Extensions

快速播放音频和视频预加载

Web视频播放原理:介绍

流式播放器的实现原理

「1.4 万字」玩转前端 Video 播放器

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
2月前
|
存储 Web App开发 移动开发
HTML5 Web 存储详解
HTML5 Web存储提供了两种客户端数据存储机制:**Local Storage**和**Session Storage**。Local Storage用于长期存储数据,即使关闭浏览器数据也依然存在,适用于保存用户偏好设置等信息。Session Storage则在标签或窗口关闭时清除数据,适合存储临时信息。两者均提供了简单的API进行数据的存取操作,但需要注意的是,Web存储并非加密存储,不应存放敏感信息。现代浏览器普遍支持Web存储,合理利用这两种存储方式可提升Web应用的用户体验。
|
2月前
|
存储 移动开发 大数据
HTML5 Web IndexedDB 数据库详解
IndexedDB 是一种高效的浏览器存储方案,允许在本地存储大量结构化数据,支持索引和事务,适用于需要离线和大数据处理的应用。它由数据库、对象仓库等组成,通过键值对存储数据,确保数据一致性和完整性。本介绍展示了如何创建、读取、更新和删除数据,以及事务和错误处理的最佳实践。
|
27天前
|
前端开发 JavaScript 搜索推荐
HTML与CSS在Web组件化中的核心作用及前端技术趋势
本文探讨了HTML与CSS在Web组件化中的核心作用及前端技术趋势。从结构定义、语义化到样式封装与布局控制,两者不仅提升了代码复用率和可维护性,还通过响应式设计、动态样式等技术增强了用户体验。面对兼容性、代码复杂度等挑战,文章提出了相应的解决策略,强调了持续创新的重要性,旨在构建高效、灵活的Web应用。
35 6
|
27天前
|
前端开发 JavaScript UED
在数字化时代,Web 应用性能优化尤为重要。本文探讨了CSS与HTML在提升Web性能中的关键作用及未来趋势
在数字化时代,Web 应用性能优化尤为重要。本文探讨了CSS与HTML在提升Web性能中的关键作用及未来趋势,包括样式表优化、DOM操作减少、图像优化等技术,并分析了电商网站的具体案例,强调了技术演进对Web性能的深远影响。
33 5
|
2月前
|
存储 移动开发 数据库
HTML5 Web IndexedDB 数据库常用数据存储类型
IndexedDB 支持多种数据存储类型,满足复杂数据结构的存储需求。它包括基本数据类型(如 Number、String、Boolean、Date)、对象(简单和嵌套对象)、数组、Blob(用于二进制数据如图像和视频)、ArrayBuffer 和 Typed Arrays(处理二进制数据)、结构化克隆(支持 Map 和 Set 等复杂对象),以及 JSON 数据。尽管不直接支持非序列化数据(如函数和 DOM 节点),但可以通过转换实现存储。开发者应根据具体需求选择合适的数据类型,以优化性能和使用体验。
|
2月前
|
移动开发 JavaScript 前端开发
HTML5 Web Workers详解
HTML5 Web Workers 允许在后台线程中运行 JavaScript,实现复杂计算而不影响用户界面,提升应用性能。其主要特性包括并行处理、异步通信、独立作用域及多数据类型支持。通过创建和使用 Worker 文件,如 `worker.js`,可执行后台任务,并与主线程通过消息传递机制通信。适用于数据处理、图像处理、复杂计算及网络请求并行等场景。需要注意的是,Web Workers 在浏览器兼容性、安全性限制、调试及资源消耗方面需特别关注。合理利用 Web Workers 可显著增强 Web 应用的流畅度和响应速度。
|
2月前
|
SQL 存储 移动开发
HTML5 Web SQL 数据库详解
Web SQL 数据库是 HTML5 中的一种本地存储技术,允许在浏览器中使用 SQL 语言操作本地数据,支持离线访问和事务处理,适用于缓存数据和小型应用。然而,其存储容量有限且仅部分现代浏览器支持,标准已不再积极维护,未来可能被 IndexedDB 和 localStorage 等技术取代。使用时需谨慎考虑兼容性和发展前景。
|
2月前
|
存储 移动开发 缓存
HTML5 Web 存储详解
HTML5 Web 存储包括 `localStorage` 和 `sessionStorage`,前者提供持久存储且无过期时间,后者仅在会话期间有效。两者均支持键值对形式存储数据,容量约为 5-10 MB。`localStorage` 适用于用户偏好设置、登录状态保持及离线应用缓存;`sessionStorage` 则用于临时数据如表单输入。数据以字符串形式存储,可通过 `JSON` 方法处理对象。由于数据存储于本地,不适合存放敏感信息。示例代码展示了如何使用按钮将输入框内容保存至 `localStorage` 并进行清除操作。
|
2月前
|
移动开发 前端开发 JavaScript
HTML与现代Web开发的不同技术
【10月更文挑战第11天】HTML与现代Web开发的不同技术
34 0
|
3月前
|
前端开发 程序员
【前端web入门第二天】01 html语法实现列表与表格_合并单元格
本文介绍了HTML中的列表与表格的使用方法。列表包括无序列表(`<ul>`嵌套`<li>`)、有序列表(`<ol>`嵌套`<li>`)和定义列表(`<dl>`嵌套`<dt>`和`<dd>`)。
71 19