Web 多媒体入门 | 青训营笔记

138 阅读6分钟

Web 多媒体入门 | 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第 24 天

简介

本节课主要给大家介绍下什么是 web 多媒体,涉及到一些比较重要的概念和前端常用的多媒体 web API ,让大家对多媒体相关知识点有一个初步的了解和认识。

学习手册

概述

本节课程分为四个章节

  1. web多媒体历史介绍
  2. 基础知识
  3. 应用场景
  4. 一些新的技术标准

基础知识部分涉及到概念较多,大家可以在课前了解一下,比如编码格式、封装格式、Media Source Extensions(MSE)等等,可以帮助大家更好的理解web多媒体。

课前

熟悉视频相关概念,如I帧、B帧、P帧、帧率、GOP、H264、mp4

熟悉 videoElementaudioElement 相关属性和API

熟悉 Media Source Extensions 原理及其API

课后

可以查看 xgplayer 的源码,学习关于 web 多媒体播放器的具体流程

Web 多媒体历史

PC 时代

Flash 1994 - 2020

网页三剑客 flash draemweaver fireworks 播放插件

移动端时代

Flash下坡路 ios 不支持 flash

Webp,ogg,mp4 三种视频格式

Html5 2014年定稿

扩展 API

Media Source Extensions

基础知识

编码格式

图像基本概念

  • 分辨率:用于确定组成一幅图像的像素数据,就是指在水平和垂直方向上图像所具有的像素个数

  • 深度:图像深度是指存储每个像素所需要的比特数。图像深度决定了图像每个像素可能的颜色数,或可能的灰度级数。例如,彩色图像每个像素用 R、G、B 三个分量表示,每个分量用 8 位,像素深度为 24 位,可以表示的颜色数目为 224 ,即 16777216 个;一幅单色图像存储每个像素需要 8 bit ,则图像的像素深度为 8 位,最大灰度数目为 28 ,即 256 个。

视频基本概念

时间维度上一系列图片展示就是视频

  • 分辨率:每一帧图像的分辨率

  • 帧率:单位时间内包含的视频帧的数量

  • 码率:就是指视频单位时间内传输的数据量,一般用 kbps 表示,即千位每秒

I 帧、P 帧、B 帧:

  • I 帧又称帧内编码帧,是一种自带全部信息的独立帧,无需参考其他图像便可独立进行解码
  • P 帧又称帧间预测编码帧,需要参考前面的 I 帧或者 P 帧才能进行编码
  • B 帧又称双向预测编码帧,也就是 B 帧记录的是本帧与前后帧的差别

Pasted image 20220816113950.png

GOP(group of pictures):两个 I 帧之间的间隔

  • 一般为 2s 或 4s

Pasted image 20220816114313.png

编码的意义

直接按视频大小等于帧画面大小乘以帧画面数量这样存视频空间会有很多浪费:

  • 空间冗余:有一些成块的区域颜色是一样的
  • 时间冗余:两帧之间有可能图像内容几乎一样
  • 编码冗余:有些颜色数量很少的图像只需要很少的编码位就可以存储
  • 视觉冗余:人眼对高频颜色不敏感

编码数据处理流程

  1. 预测:去除空间冗余和时间冗余
  2. 变换:去除空间冗余
  3. 量化:去除视觉冗余
  4. 熵编码:去除编码冗余

编码格式标准

Pasted image 20220816115208.png

联合视频专家组 JVT

运动图像专家组 MPEG

AOM 开放媒体联盟 亚马逊、微软、Google,思科,英特尔

封装格式

封装格式:存储音视频、图片或字幕信息的一种容器

Pasted image 20220816115741.png

多媒体元素和扩展 API

video 与 audio 标签

video 元素

<!DOCTYPE html>
<html>
  <body>
    <video src="./video.mp4" muted autoplay controls width=600 height=300></video>
    <video muted autoplay controls width=600 height=300>
      <source src="./video.mp4"></source>
    </video>
  </body>
</html>

audio 元素

<!DOCTYPE html>
<html>
  <body>
    <audio src="./video.mp4" muted autoplay controls width=600 height=300></audio>
    <audio muted autoplay controls width=600 height=300>
      <source src="./video.mp4"></source>
    </audio>
  </body>
</html>

audio 与 video 元素方法

Pasted image 20220816120727.png

<!DOCTYPE html>
<html>
  <body>
    <button onclick="playVid()">播放视频</button>
    <button onclick="pauseVid()">暂停视频</button>
    <button onclick="loadVid()">重新加载视频</button>

    <video id="vs" src="demo.mp4"></video>

    <script>
      const myVideo = document.getElementById("vs");

      function playVid() {
	    myVideo.play();
      }
      
      function pauseVid() {
        myVideo.pause();
      }
      
      function loadVid() {
        myVideo.load();
      }
    </script>
  </body>
</html>

audio 与 video 元素属性

Pasted image 20220816121240.png

<!DOCTYPE html>
<html>
  <body>
    <button onclick="getVolume()">音量是多少?</button>
    <button onclick="setVolume()">将视频音量设置为20%</button>
    <button onclick="getCurTime()">获得当前播放时间</button>
    <button onclick="setCurTime()">将播放时间设置为第5秒</button>

    <video id="vs" src="demo.mp4"></video>

    <script>
      const myVideo = document.getElementById("vs");

      function getVolume() {
	    alert(myVideo.volume);
      }
      
      function setVolume() {
        myVideo.volume = 0.2;
      }
      
      function getCueTime() {
        alert(myVideo.currentTime);
      }
      
      function setCurTime() {
        myVideo.currentTIme = 5;
      }
    </script>
  </body>
</html>

audio 与 video 元素事件

Pasted image 20220816121724.png

<!DOCTYPE html>
<html>
  <body>
    <video id="vs" src="demo.mp4"></video>

    <script>
      const myVideo = document.getElementById("vs");

      myVideo.addEventListener('canplay', function() {
	        alert('canplay');
      });
      myVideo.addEventListener('pause', function() {
	        alert('pause');
      });
      myVideo.addEventListener('play', function() {
	        alert('play');
      });
      myVideo.addEventListener('waiting', function() {
	        alert('waiting');
      });
    </script>
  </body>
</html>

audio 与 video 元素缺陷

  • 不支持直接播放 hls、flv 等视频格式

  • 视频资源的请求和加载无法通过代码控制

    • 分段加载(节约流量)
    • 清晰度无缝切换
    • 请确预加载

媒体源扩展 API(Media Source Extensions)

  • 无插件在 web 端播放流媒体
  • 支持播放 hls、flv、mp4 等格式视频
  • 可实现视频分段加载、清晰度无缝切换、自适应码率、精确预加载等

Pasted image 20220816122317.png

使用:

  1. 创建 mediaSource 实例
  2. 创建指向 mediaSource 的 URL
  3. 监听 sourceopen 事件
  4. 创建 sourceBuffer
  5. 向 sourceBuffer 中加入数据
  6. 监听 updateend 事件
let mimeCodec = 'video/mp4; codecs="avcl.42E01E, mp4a.40.2"';
let mediaSource = new MediaSource();

video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', () {
  let mediaSource = this;
  let sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  fetchAB('frag_bunny.mp4', function (buf) {
    sourceBuffer.addEventListener('updateend', function () {
	  mediaSource.endOfStream();
	  video.play();
    });
    sourceBuffer.appendBuffer(buf);
  });
});

function fetchAB (url, cb) {
  let xhr = new XMLHttpRequest;
  xhr.open('get', url);
  xhr.responseType = 'arraybuffer';
  xhr.onload = function () { cb(xhr.response); };
  xhr.send();
}

var mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2”’

首先,前面的 video/mp4 代表这是一段 mp4 格式封装的视频,同理也存在类似 video/webm、audio/mpeg、audio/mp4 这样的 mime 格式。

后面的这一段 codecs="...." 比较特别,以逗号相隔,分为两段:

  • 第一段,'avc1.42E01E',即它用于告诉浏览器关于视频编解码的一些重要信息,诸如编码方式、分辨率、帧率、码率以及对解码器解码能力的要求。 在这个例子中,'avc1' 代表视频采用 H.264 编码,随后是一个分隔点,之后是 3 个两位的十六进制的数,这 3 个十六进制数分别代表: AVCProfileIndication(42) profile_compability(E0) AVCLevelIndication(1E) 第一个用于标识 H.264 的 profile,后两个用于标识视频对于解码器的要求。 datatracker.ietf.org/doc/html/rf…
  • 第二段 'mp4a.40.2',这一段信息是关于音频部分的,代表视频的音频部分采用了 AAC LC 标准: 'mp4a' 代表此视频的音频部分采用 MPEG-4 压缩编码。 随后是一个分隔点,和一个十六进制数(40),这是 ObjectTypeIndication,40 对应的是 Audio ISO/IEC 14496-3 标准。(不同的值具有不同的含义,详细可以参考官方文档) 然后又是一个分隔点,和一个十进制数(2),这是 MPEG-4 Audio Object Type,维基百科中的解释是 "MPEG-4 AAC LC Audio Object Type is based on the MPEG-2 Part 7 Low Complexity profile (LC) combined with Perceptual Noise Substitution (PNS) (defined in MPEG-4 Part 3 Subpart 4)",具体是什么意思就不翻译了,其实就是一种 H.264 视频中常用的音频编码规范。

MSE 播放流程

Pasted image 20220816123607.png

播放器播放流程

Pasted image 20220816123716.png

mp4 和 fmp4

Pasted image 20220816123835.png

多个moof ,fmp4 对流式播放友好

流媒体协议

Pasted image 20220816123934.png

HLS 全称是 HTTP Live Streaming ,是一个由 Apple 公司提出的基于 HTTP 的媒体流传输协议,用于实时音视频流的传输。目前 HLS 协议被广泛应用于视频点播和直播领域

Pasted image 20220816124118.png

主播放列表:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=500000, RESOLUTION=720x480
mid_video_index.M3U8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=800000, RESOLUTION=1280x720
wifi_video_index.M3U8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=3000000, CODECS="avcl.4d00le,mp4a.40.5", RESOLUTION=1920x1080 h264main_heaac_index.M3U8
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=64000, CODECS="mp4a.40.5", aacaudio_index.M3U8

媒体播放列表:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:64
#EXT-X-TARGETDURATION:12
#EXTINF:11.550
livestream-64.ts
#EXTINF:5.250
livestream-65.ts
#EXTINF:7.700
livestream-66.ts
#EXTINF:6.850
livestream-67.ts

应用场景

Pasted image 20220816124202.png

Abr、防挡弹幕、低延时直播、防劫持 ...

总结与展望

总结:

  • flash -> H5 video -> MSE
  • 编码格式、封装格式、多媒体元素、流媒体协议
  • 应用场景

新技术标准:

  • Webassembly
  • WebCodecs
  • WebGPU
  • WebVR、WebXR