当前位置: 首页 > 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…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...