Web 音视频(二)在浏览器中解析视频
前言
浏览器中已经能直接播放视频,为什么还需要手动写代码解析?
因为,某些场景需要对视频进行更细致的处理,比如截取关键帧、提取视频中的文字、人物打码、极低延时播放视频等等。
总之,除了最单纯的视频播放外,对视频数据的一切处理都需要从解析开始。
MP4 简单介绍
MP4 是最流行兼容性最好的视频封装格式之一,在各种浏览器中也得到了良好支持;
本系列后续都以 MP4 视频作为示例,所以先简单介绍 MP4 的基本概念。
其它格式的视频文件需使用对应的解封装 SDK
MP4 可以分为普通 MP4 和 Fragment MP4;
普通 MP4 的元数据可在音视频数据前面(利于网络播放),也可在后面;
Fragment MP4 把音视频数据切成一个个小片段管理,非常方便直播场景,也是 MSE 唯一支持的格式。

MP4 使用 Box 的抽象概念来描述管理数据,不同的数据抽象成不同的 Box,允许多层嵌套 Box;
下图是一个普通 MP4 文件的可视化,该文件视频分辨率存储在 moov box -> trak box -> ... -> avc1 box 中,已编码(压缩)的音视频数据则存储在 mdata box 中

你可以访问 mp4box.js filereader 来可视化 MP4 文件
MP4 解封装
我们使用 mp4box.js 在浏览器中解封装(demux)MP4 文件;
解封装(demux)可以理解为提取 MP4 文件的元数据,以及将音视频数据解析成一个个包(Sample)方便处理。
而 MP4 Sample 可转换为 EncodedVideoChunk 或 EncodedAudioChunk。

WebAV 项目中的 SampleTransform 可将 MP4 文件流转换成 Sample 流(ReadableStream)
mp4FileStream.pipeThrough(new SampleTransform())即可得到 Sample 流。
解封装伪代码
mp4box.js API 文档
const file = mp4box.createFile()
file.onReady = info => {file.setExtractionOptions(info.videoTracks[0]?.id, 'video')file.setExtractionOptions(info.audioTracks[0]?.id, 'audio')file.start()
}file.onSamples = (id, type, samples) => {// `EncodedVideoChunk` 或 `EncodedAudioChunk`const chunks = samples.map(s => new EncodedVideoChunk({type: (s.is_sync ? 'key' : 'delta')timestamp: (1e6 * s.cts) / s.timescale,duration: (1e6 * s.duration) / s.timescale,data: s.data}))
}const mp4stream = await fetch('<mp4 url>').body
let inputBufOffset = 0
while (read ui8ArrBuf for mp4stream) {const inputBuf = ui8ArrBuf.bufferinputBuf.fileStart = inputBufOffsetinputBufOffset += inputBuf.byteLengthfile.appendBuffer(inputBuf)
}
解封装过程不会消耗过多的计算资源,一般使用 js 处理也不会碰到性能瓶颈,该过程不在 WebCodecs 的覆盖范围内。
视频解码
不同的视频需要对应的解封装程序,解封装得到的数据(如 MP4 Sample)可转换为 WebCodecs 中提供的 EncodedVideoChunk 或 EncodedAudioChunk,然后分别由 VideoDecoder 或 AudioDecoder 进行解码(解压)。
使用解码器之前需要初始化配置(decoder.configure),必填参数 codec 可以在解封装时拿到(onReady)。

const videoDecoder = new VideoDecoder({output: (videoFrame) => {// videoFrame 可绘制到 Canvas 进行额外处理},error: console.error,
});
videoDecoder.configure({ codec: '<视频数据对应的编码格式>' });
解码视频数据得到多个 VideoFrame, AudioData 对象,这两个对象包含了对应帧视频、音频的原始数据,可通过其实例的 copyTo 方法将原始数据 copy 到 ArrayBuffer 中。
TIP
VideoFrame可能占用大量显存,及时close避免影响性能
VideoFrame.copyTo会将帧的原始数据从显存复制到内存,像素处理请优先使用 WebGL
VideoDecoder输出(output)的VideoFrame需要及时close否则它将暂停解码 :::
视频帧处理
在浏览器中一般配合使用 Canvas 对 VideoFrame 进行处理,如:
-
降低视频分辨率
-
绘制
VideoFrame到Canvas,ctx.draw(videoFrame, 0, 0) -
创建新的
VideoFrame,new VideoFrame(canvas, {...})
-
-
裁剪视频;使用
ctx.draw后面的定位参数,绘制VideoFrame指定区域 -
叠加视频、图片、文字等;先绘制
VideoFrame再绘制其他元素 -
降低帧率,平均抽取丢掉多余帧;如 60FPS -> 30FPS,大概每两帧丢掉一帧不绘制
-
滤镜、抠图、特效等复杂图形处理;使用 WebGL 或 WebGPU
WebAV 视频解析示例
mp4box.js 解封装配合 WebCodecs 解码原理上很简单,但需要阅读大量文档、API 以及编写很多细节逻辑,汇总起来就相对繁琐了。
@webav/av-cliper 提供了 MP4Clip 可以将视频流转换成视频帧(VideoFrame) 屏蔽许多繁琐过程
import { MP4Clip } from '@webav/av-cliper';// 传入一个 mp4 文件流即可初始化
const clip = new MP4Clip((await fetch('<mp4 url>')).body);
await clip.ready;let time = 0;
// 最快速度渲染视频所有帧
while (true) {const { state, video: videoFrame } = await clip.tick(time);if (state === 'done') break;if (videoFrame != null && state === 'success') {ctx.clearRect(0, 0, cvs.width, cvs.height);// 绘制到 Canvasctx.drawImage(videoFrame,0,0,videoFrame.codedWidth,videoFrame.codedHeight);// 注意,用完立即 closevideoFrame.close();}// 时间单位是 微秒,所以差不多每秒取 30 帧,丢掉多余的帧time += 33000;
}
clip.destroy();
关于优联前端
武汉优联前端科技有限公司由一批从事前端10余年的专业人才创办,是一家致力于H5前端技术研究的科技创新型公司,为合作伙伴提供专业高效的前端解决方案,合作伙伴遍布中国及东南亚地区,行业涵盖广告,教育, 医疗,餐饮等。有效的解决了合作伙伴的前端技术难题,节约了成本,实现合作共赢。开发Web前端,微信小程序、小游戏,2D/3D游戏,动画交互与UI广告设计等各种技术研发。

相关文章:
Web 音视频(二)在浏览器中解析视频
前言 浏览器中已经能直接播放视频,为什么还需要手动写代码解析? 因为,某些场景需要对视频进行更细致的处理,比如截取关键帧、提取视频中的文字、人物打码、极低延时播放视频等等。 总之,除了最单纯的视频播放外&…...
江天科技主要产品销售单价下滑,应收账款、存货周转率大幅下降
《港湾商业观察》廖紫雯 日前,苏州江天包装科技股份有限公司(以下简称:江天科技)冲击北交所,保荐机构为国投证券。 江天科技主要从事标签印刷产品的研发、生产与销售,公司主要产品包括薄膜类和纸张类的不…...
我国的金融组织体系,还有各大金融机构的分类,金融行业的组织
中国金融组织体系介绍 中国金融组织体系是一个复杂而多层次的系统,涵盖了各种类型的金融机构和监管机构。以下是关于中国金融组织体系的详细介绍,包括一行三会等金融监管机构,各大金融机构的分类、涉及的银行以及行业组织。 (一…...
vue md5加密
在Vue中使用MD5加密,你可以使用第三方库如crypto-js。首先,你需要安装这个库: npm install crypto-js --save然后,在你的Vue组件中引入crypto-js并使用其MD5功能: <template><div><input v-model&quo…...
学习ASP.NET Core的身份认证(基于JwtBearer的身份认证7)
本文验证基于请求头中传递token信息的认证方式,webapi项目的控制器类中新建如下函数,仅通过验证的客户端能调用,需要客户端请求在Header中添加’Authorization’: Bearer token’的键值对且通过token验证后才能调用。 [Authorize] [HttpGet]…...
Ubuntu16.04 安装OpenCV4.5.4 避坑
Ubuntu16.04 安装C版OpenCV4.5.4 Ubuntu16.04 VSCode下cmakeclanglldb调试c 文章目录 Ubuntu16.04 安装C版OpenCV4.5.41. 下载Opencv压缩包2. 安装Opencv-4.5.43. 配置OpenCV的编译环境4.测试是否安装成功 1. 下载Opencv压缩包 下载Opencv压缩包,选择source版本。…...
DDD - 整洁架构_解决技术设计困局
文章目录 Pre如何落地 DDD底层技术的更迭 整洁架构的设计主动适配器/北向适配器被动适配器/南向适配器 整洁架构的落地总结 Pre DDD - 软件退化原因及案例分析 DDD - 如何运用 DDD 进行软件设计 DDD - 如何运用 DDD 进行数据库设计 DDD - 服务、实体与值对象的两种设计思路…...
Python自动化运维:一键掌控服务器的高效之道
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在互联网和云计算高速发展的今天,服务器数量的指数增长使得手动运维和管理变得异常繁琐。Python凭借其强大的可读性和丰富的生态系统,成为…...
数论问题61一一各种进位制
10进位制是普遍使用的数进位制,二进位制是计算机采用的进位制。还有三进位制,四进位制,…等等。那一种进位制都能转化为10进位制。下面介绍这种方法。 ①10进位制的表示(口诀:逢10进1) 如8X10007X1005x1038753。 ②2进位制的表示(口诀:逢2…...
Java开发提速秘籍:巧用Apache Commons Lang工具库
一、Java 开发效率之困 在当今数字化时代,Java 作为一门广泛应用的编程语言,在各类软件开发项目中占据着举足轻重的地位。无论是大型企业级应用、互联网平台,还是移动应用后端,都能看到 Java 的身影。然而,Java 开发者…...
使用sql查询excel内容
1. 简介 我们在前面的文章中提到了calcite支持csv和json文件的数据源适配, 其实就是将文件解析成表然后以文件夹为schema, 然后将生成的schema注册到RootSehema(RootSchema是所有数据源schema的parent,多个不同数据源schema可以挂在同一个RootSchema下)下, 最终使用…...
[Python学习日记-78] 基于 TCP 的 socket 开发项目 —— 模拟 SSH 远程执行命令
[Python学习日记-78] 基于 TCP 的 socket 开发项目 —— 模拟 SSH 远程执行命令 简介 项目分析 如何执行系统命令并拿到结果 代码实现 简介 在Python学习日记-77中我们介绍了 socket 基于 TCP 和基于 UDP 的套接字,还实现了服务器端和客户端的通信,本…...
电子应用设计方案101:智能家庭AI喝水杯系统设计
智能家庭 AI 喝水杯系统设计 一、引言 智能家庭 AI 喝水杯系统旨在为用户提供个性化的饮水提醒和健康管理服务,帮助用户养成良好的饮水习惯。 二、系统概述 1. 系统目标 - 精确监测饮水量和饮水频率。 - 根据用户的身体状况和活动量,智能制定饮水计划。…...
vue学习路线
以下是一个详细的Vue学习路线: 一、基础入门 (一)环境搭建 1. 安装Node.js和npm:Vue项目依赖于Node.js环境,需从官网下载并安装最新版本的Node.js,npm会随Node.js一起安装。 2. 安装Vue CLI:V…...
(15)Chainlink Automation(定时任务) 详细介绍及用法
Chainlink Automation 详细介绍 1. 什么是 Chainlink Automation? Chainlink Automation 是 Chainlink 提供的一个去中心化服务,专门用于自动化执行智能合约的链上操作。它允许开发者基于时间或特定条件(如链上或链下事件)触发智…...
从入门到精通:RabbitMQ的深度探索与实战应用
目录 一、RabbitMQ 初相识 二、基础概念速览 (一)消息队列是什么 (二)RabbitMQ 核心组件 三、RabbitMQ 基本使用 (一)安装与环境搭建 (二)简单示例 (三)…...
基于微信小程序高校订餐系统的设计与开发ssm+论文源码调试讲解
第4章 系统设计 一个成功设计的系统在内容上必定是丰富的,在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值,吸引更多的访问者访问系统,以及让来访用户可以花费更多时间停留在系统上,则表明该系统设计得比较专…...
【vitePress】基于github快速添加评论功能(giscus)
一.添加评论插件 使用giscus来做vitepress 的评论模块,使用也非常的简单,具体可以参考:giscus 文档,首先安装giscus npm i giscus/vue 二.giscus操作 打开giscus 文档,如下图所示,填入你的 github 用户…...
PID 控制算法(二):C 语言实现与应用
在本文中,我们将用 C 语言实现一个简单的 PID 控制器,并通过一个示例来演示如何使用 PID 控制算法来调整系统的状态(如温度、速度等)。同时,我们也会解释每个控制参数如何影响系统的表现。 什么是 PID 控制器…...
Git本地搭建
Git本地搭建 (项目突然不给创建仓库了,为了方便管理项目只能自己本地搭建git服务) 为了在本地搭建Git环境并实现基本的Git操作,步骤如下: 安装Git软件 Windows:从Git官方网站下载并安装适用于Windows…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
