当前位置: 首页 > news >正文

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 否则它将暂停解码 :::

视频帧处理

在浏览器中一般配合使用 CanvasVideoFrame 进行处理,如:

  • 降低视频分辨率

    1. 绘制 VideoFrameCanvasctx.draw(videoFrame, 0, 0)

    2. 创建新的 VideoFramenew 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 音视频(二)在浏览器中解析视频

前言 浏览器中已经能直接播放视频&#xff0c;为什么还需要手动写代码解析&#xff1f; 因为&#xff0c;某些场景需要对视频进行更细致的处理&#xff0c;比如截取关键帧、提取视频中的文字、人物打码、极低延时播放视频等等。 总之&#xff0c;除了最单纯的视频播放外&…...

江天科技主要产品销售单价下滑,应收账款、存货周转率大幅下降

《港湾商业观察》廖紫雯 日前&#xff0c;苏州江天包装科技股份有限公司&#xff08;以下简称&#xff1a;江天科技&#xff09;冲击北交所&#xff0c;保荐机构为国投证券。 江天科技主要从事标签印刷产品的研发、生产与销售&#xff0c;公司主要产品包括薄膜类和纸张类的不…...

我国的金融组织体系,还有各大金融机构的分类,金融行业的组织

中国金融组织体系介绍 中国金融组织体系是一个复杂而多层次的系统&#xff0c;涵盖了各种类型的金融机构和监管机构。以下是关于中国金融组织体系的详细介绍&#xff0c;包括一行三会等金融监管机构&#xff0c;各大金融机构的分类、涉及的银行以及行业组织。 &#xff08;一…...

vue md5加密

在Vue中使用MD5加密&#xff0c;你可以使用第三方库如crypto-js。首先&#xff0c;你需要安装这个库&#xff1a; npm install crypto-js --save然后&#xff0c;在你的Vue组件中引入crypto-js并使用其MD5功能&#xff1a; <template><div><input v-model&quo…...

学习ASP.NET Core的身份认证(基于JwtBearer的身份认证7)

本文验证基于请求头中传递token信息的认证方式&#xff0c;webapi项目的控制器类中新建如下函数&#xff0c;仅通过验证的客户端能调用&#xff0c;需要客户端请求在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压缩包&#xff0c;选择source版本。…...

DDD - 整洁架构_解决技术设计困局

文章目录 Pre如何落地 DDD底层技术的更迭 整洁架构的设计主动适配器/北向适配器被动适配器/南向适配器 整洁架构的落地总结 Pre DDD - 软件退化原因及案例分析 DDD - 如何运用 DDD 进行软件设计 DDD - 如何运用 DDD 进行数据库设计 DDD - 服务、实体与值对象的两种设计思路…...

Python自动化运维:一键掌控服务器的高效之道

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在互联网和云计算高速发展的今天,服务器数量的指数增长使得手动运维和管理变得异常繁琐。Python凭借其强大的可读性和丰富的生态系统,成为…...

数论问题61一一各种进位制

10进位制是普遍使用的数进位制&#xff0c;二进位制是计算机采用的进位制。还有三进位制&#xff0c;四进位制&#xff0c;…等等。那一种进位制都能转化为10进位制。下面介绍这种方法。 ①10进位制的表示(口诀:逢10进1) 如8X10007X1005x1038753。 ②2进位制的表示(口诀:逢2…...

Java开发提速秘籍:巧用Apache Commons Lang工具库

一、Java 开发效率之困 在当今数字化时代&#xff0c;Java 作为一门广泛应用的编程语言&#xff0c;在各类软件开发项目中占据着举足轻重的地位。无论是大型企业级应用、互联网平台&#xff0c;还是移动应用后端&#xff0c;都能看到 Java 的身影。然而&#xff0c;Java 开发者…...

使用sql查询excel内容

1. 简介 我们在前面的文章中提到了calcite支持csv和json文件的数据源适配, 其实就是将文件解析成表然后以文件夹为schema, 然后将生成的schema注册到RootSehema(RootSchema是所有数据源schema的parent&#xff0c;多个不同数据源schema可以挂在同一个RootSchema下)下, 最终使用…...

[Python学习日记-78] 基于 TCP 的 socket 开发项目 —— 模拟 SSH 远程执行命令

[Python学习日记-78] 基于 TCP 的 socket 开发项目 —— 模拟 SSH 远程执行命令 简介 项目分析 如何执行系统命令并拿到结果 代码实现 简介 在Python学习日记-77中我们介绍了 socket 基于 TCP 和基于 UDP 的套接字&#xff0c;还实现了服务器端和客户端的通信&#xff0c;本…...

电子应用设计方案101:智能家庭AI喝水杯系统设计

智能家庭 AI 喝水杯系统设计 一、引言 智能家庭 AI 喝水杯系统旨在为用户提供个性化的饮水提醒和健康管理服务&#xff0c;帮助用户养成良好的饮水习惯。 二、系统概述 1. 系统目标 - 精确监测饮水量和饮水频率。 - 根据用户的身体状况和活动量&#xff0c;智能制定饮水计划。…...

vue学习路线

以下是一个详细的Vue学习路线&#xff1a; 一、基础入门 &#xff08;一&#xff09;环境搭建 1. 安装Node.js和npm&#xff1a;Vue项目依赖于Node.js环境&#xff0c;需从官网下载并安装最新版本的Node.js&#xff0c;npm会随Node.js一起安装。 2. 安装Vue CLI&#xff1a;V…...

(15)Chainlink Automation(定时任务) 详细介绍及用法

Chainlink Automation 详细介绍 1. 什么是 Chainlink Automation&#xff1f; Chainlink Automation 是 Chainlink 提供的一个去中心化服务&#xff0c;专门用于自动化执行智能合约的链上操作。它允许开发者基于时间或特定条件&#xff08;如链上或链下事件&#xff09;触发智…...

从入门到精通:RabbitMQ的深度探索与实战应用

目录 一、RabbitMQ 初相识 二、基础概念速览 &#xff08;一&#xff09;消息队列是什么 &#xff08;二&#xff09;RabbitMQ 核心组件 三、RabbitMQ 基本使用 &#xff08;一&#xff09;安装与环境搭建 &#xff08;二&#xff09;简单示例 &#xff08;三&#xff09;…...

基于微信小程序高校订餐系统的设计与开发ssm+论文源码调试讲解

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专…...

【vitePress】基于github快速添加评论功能(giscus)

一.添加评论插件 使用giscus来做vitepress 的评论模块&#xff0c;使用也非常的简单&#xff0c;具体可以参考&#xff1a;giscus 文档&#xff0c;首先安装giscus npm i giscus/vue 二.giscus操作 打开giscus 文档&#xff0c;如下图所示&#xff0c;填入你的 github 用户…...

PID 控制算法(二):C 语言实现与应用

在本文中&#xff0c;我们将用 C 语言实现一个简单的 PID 控制器&#xff0c;并通过一个示例来演示如何使用 PID 控制算法来调整系统的状态&#xff08;如温度、速度等&#xff09;。同时&#xff0c;我们也会解释每个控制参数如何影响系统的表现。 什么是 PID 控制器&#xf…...

Git本地搭建

Git本地搭建 &#xff08;项目突然不给创建仓库了&#xff0c;为了方便管理项目只能自己本地搭建git服务&#xff09; 为了在本地搭建Git环境并实现基本的Git操作&#xff0c;步骤如下&#xff1a; 安装Git软件 ‌Windows‌&#xff1a;从Git官方网站下载并安装适用于Windows…...

ORB-SLAM2源码学习:Initializer.cc⑧: Initializer::CheckRT检验三角化结果

前言 ORB-SLAM2源码学习&#xff1a;Initializer.cc⑦: Initializer::Triangulate特征点对的三角化_cv::svd::compute-CSDN博客 经过上面的三角化我们成功得到了三维点&#xff0c;但是经过三角化成功的三维点并不一定是有效的&#xff0c;需要筛选才能作为初始化地图点。 …...

leetcode 2239. 找到最接近 0 的数字

题目&#xff1a;2239. 找到最接近 0 的数字 - 力扣&#xff08;LeetCode&#xff09; 加班用手机刷水题&#xff0c;补个记录 1 class Solution { public:int findClosestNumber(vector<int>& nums) {int ret nums[0];for (int i 1; i < nums.size(); i) {if…...

Rust实现内网穿透工具:从原理到实现

目录 1.前言2.内网穿透原理3.丐版实现3.1 share3.2 server3.3 client3.4 测试4.项目优化4.1 工作空间4.2 代码合并4.3 无锁优化4.4 数据分离4.5 错误处理4.6 测试代码4.7 参数解析本篇原文为:Rust实现内网穿透工具:从原理到实现 更多C++进阶、rust、python、逆向等等教程,可…...

【深度学习】1.深度学习解决问题与应用领域

深度学习要解决的问题 一、图像识别相关问题 物体识别 背景和意义&#xff1a;在众多的图像中识别出特定的物体&#xff0c;例如在安防监控领域&#xff0c;识别出画面中的人物、车辆等物体类别。在自动驾驶技术中&#xff0c;车辆需要识别出道路上的行人、交通标志、其他车辆…...

文档解析:PDF里的复杂表格、少线表格如何还原?

PDF中的复杂表格或少线表格还原通常需要借助专业的工具或在线服务&#xff0c;以下是一些可行的方法&#xff1a; 方法一&#xff1a;使用在线PDF转换工具 方法二&#xff1a;使用桌面PDF编辑软件 方法三&#xff1a;通过OCR技术提取表格 方法四&#xff1a;手动重建表格 …...

深圳大学-计算机系统(3)-实验三取指和指令译码设计

实验目标 设计完成一个连续取指令并进行指令译码的电路&#xff0c;从而掌握设计简单数据通路的基本方法。 实验内容 本实验分成三周&#xff08;三次&#xff09;完成&#xff1a;1&#xff09;首先完成一个译码器&#xff08;30分&#xff09;&#xff1b;2&#xff09;接…...

Java Swing 编程全面解析:从 AWT 到 Swing 的进化之路

目录 前言 一、AWT 简介 1. 什么是 AWT&#xff1f; 2. AWT 的基本组件 3. AWT 编程示例 二、Swing 的诞生与进化 1. Swing 的特点 2. Swing 和 AWT 的主要区别 3. Swing 的基本组件 三、Swing 编程的基础示例 四、Swing 的高级功能 1. 布局管理器 2. 事件监听 3…...

mysql数据库启动出现Plugin ‘FEEDBACK‘ is disabled.问题解决记录

本人出现该问题的环境是xampp&#xff0c;异常关机&#xff0c;再次在xampp控制面板启动mysql出现该问题。出现问题折腾数据库之前&#xff0c;先备份数据&#xff0c;将mysql目录下的data拷贝到其他地方&#xff0c;这很重要。 然后开始折腾。 查资料&#xff0c;会发现很多…...

2025年大模型对智能硬件发展的助力与创新创意

随着人工智能(AI)技术,尤其是大模型的快速进步,智能硬件领域正在经历前所未有的变革。到2025年,大模型不仅能为智能硬件提供强大的算法支持,还能通过数据处理、智能决策和系统集成等方面的创新,推动硬件设备的性能提升和功能拓展。本文将从多个维度分析大模型对智能硬件…...

Tensor 基本操作1 unsqueeze, squeeze, softmax | PyTorch 深度学习实战

本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 目录 创建 Tensor常用操作unsqueezesqueezeSoftmax代码1代码2代码3 argmaxitem 创建 Tensor 使用 Torch 接口创建 Tensor import torch参考&#xff1a;https://pytorch.org/tutorials/beginn…...