首页 文章 精选 留言 我的

精选列表

搜索[技术极客],共10000篇文章
优秀的个人博客,低调大师

浏览器端音视频处理新选择:Mediabunny 让 Web 媒体开发飞起来 | 葡萄城技术团队

浏览器端音视频处理新选择:Mediabunny 让 Web 媒体开发飞起来 在 Web 开发中,音视频处理一直是个“老大难”问题:传统方案要么依赖后端服务器中转(延迟高、成本高),要么使用移植自桌面的库(体积大、性能差),始终缺乏一个“为 Web 而生”的轻量高效解决方案。而今天要介绍的 Mediabunny,正是填补这一空白的 JavaScript 库——它能直接在浏览器中实现音视频的读取、写入、转换,且速度和易用性都远超同类工具。 一、什么是 Mediabunny? Mediabunny 是一个专注于 浏览器端音视频全流程处理 的 JavaScript 库,核心定位是“为 Web 原生设计,而非移植适配”。它基于 TypeScript 开发,提供了从底层控制到高层封装的完整 API,让开发者既能精细操作媒体数据,又无需处理复杂的编解码细节。 简单说,它解决了三个核心痛点: 无需后端依赖:所有处理都在客户端完成,减少网络请求和服务器成本; 性能拉满:利用浏览器 WebCodecs API 实现硬件加速,配合“按需加载”“流水线设计”,速度远超同类库; 轻量且灵活:零依赖、支持树摇优化(只打包用到的功能),bundle 体积最小仅 5KB 级。 二、Mediabunny 核心特性:不止于“能用”,更在于“好用” Mediabunny 的功能覆盖了 Web 音视频开发的全场景,以下是最值得关注的五大特性: 1. 高效读写:只加载你需要的数据 传统库读取音视频时往往会加载整个文件,而 Mediabunny 支持“按需提取”——无论是元数据(时长、分辨率、编码格式)还是原始帧数据,都能精准读取,避免不必要的性能浪费。 支持的读取源:网络 URL、本地文件(Blob)、内存缓冲区,覆盖绝大多数场景。 2. 可编程生成:动态创建音视频文件 你可以直接在浏览器中生成 MP4、WebM 等格式的媒体文件,支持添加多轨道(视频、音频、字幕),且时间精度可控制到微秒级。比如从 Canvas 捕获动画、从音频缓冲区生成音效,都能直接封装成文件。 3. 闪电转换:一站式处理格式/尺寸/编码 通过 Conversion API 可实现“格式转换+编辑”一体化:转码(如 MP4 转 WebM)、裁剪、缩放、旋转、音频重采样等操作一步完成,无需拼接多个工具。 4. 通用 I/O:灵活对接各种媒体源 Mediabunny 几乎支持所有 Web 媒体输入输出场景: 输入:Canvas、摄像头、屏幕共享、麦克风、自定义编码数据; 输出:内存缓存、本地文件下载、流式传输(边生成边推送)。 5. 广泛兼容:覆盖主流容器与编解码器 无论是常见的 MP4、WebM、MP3、WAV,还是较新的 AV1 编码、H.265,Mediabunny 都支持“双向处理”(既能读又能写)。完整兼容列表包括: 容器:.mp4、.webm、.mov、.mkv、.ogg、.wav 等; 视频编码:H.264/AVC、H.265/HEVC、VP8、VP9、AV1; 音频编码:AAC、MP3、Opus、Vorbis、FLAC、PCM; 字幕:WebVTT。 三、上手实战:3 段代码看懂 Mediabunny 用法 Mediabunny 的 API 设计非常直观,以下三个示例覆盖“读-写-转”核心场景,复制即可运行(需先安装依赖)。 前置步骤:安装 Mediabunny npm install mediabunny 示例 1:读取音视频元数据与帧数据 比如读取一个 MP4 文件的时长、分辨率,并提取中间帧: import { Input, UrlSource, VideoSampleSink, ALL_FORMATS } from 'mediabunny'; // 1. 初始化输入(支持 URL、Blob 等源) const input = new Input({ source: new UrlSource('./bigbuckbunny.mp4'), // 视频文件路径 formats: ALL_FORMATS, // 支持所有格式 }); // 2. 获取元数据 const duration = await input.computeDuration(); // 视频时长(秒) const videoTrack = await input.getPrimaryVideoTrack(); const { displayWidth: width, displayHeight: height, rotation } = videoTrack; // 分辨率、旋转角度 const audioTrack = await input.getPrimaryAudioTrack(); const { sampleRate: sampleRate, numberOfChannels: channels } = audioTrack; // 采样率、声道数 console.log(`视频:${width}x${height},时长:${duration}s;音频:${sampleRate}Hz,${channels}声道`); // 3. 提取中间帧 const sink = new VideoSampleSink(videoTrack); const middleFrame = await sink.getSample(duration / 2); // 获取中间位置的帧 // 可将 frame 绘制到 Canvas 或转为 Blob 下载 // 4. 遍历所有帧(适合批量处理) for await (const frame of sink.samples()) { // 处理每一针(如帧分析、滤镜效果) } 示例 2:从 Canvas 生成 MP4 文件 将 Canvas 动画捕获并生成 MP4 视频: import { Output, Mp4OutputFormat, BufferTarget, CanvasSource, QUALITY_HIGH } from 'mediabunny'; // 1. 初始化输出(格式:MP4,目标:内存缓冲区) const output = new Output({ format: new Mp4OutputFormat(), target: new BufferTarget(), }); // 2. 添加视频轨道(从 Canvas 捕获) const canvas = document.getElementById('my-canvas'); // 你的 Canvas 元素 const videoSource = new CanvasSource(canvas, { codec: 'av1', // 使用 AV1 编码(高效压缩) bitrate: QUALITY_HIGH, // 高画质 }); output.addVideoTrack(videoSource); // 3. 添加音频轨道(从音频缓冲区生成) const audioSource = new AudioBufferSource({ codec: 'opus', // Opus 音频编码 bitrate: QUALITY_HIGH, }); output.addAudioTrack(audioSource); // 4. 开始生成并写入数据 await output.start(); // (可选)向 audioSource 推送音频数据 // audioSource.push(audioBuffer); // 5. 完成生成,获取最终文件 await output.finalize(); const fileBlob = new Blob([output.target.buffer], { type: 'video/mp4' }); // 下载文件 const a = document.createElement('a'); a.href = URL.createObjectURL(fileBlob); a.download = 'canvas-animation.mp4'; a.click(); 示例 3:MP4 转 WebM 并缩放尺寸 将本地 MP4 文件转换为 WebM 格式,并缩放到 320x180: import { Input, BlobSource, Output, WebMOutputFormat, StreamTarget, Conversion, ALL_FORMATS } from 'mediabunny'; // 1. 读取本地文件(通过 <input type="file"> 获取) const fileInput = document.getElementById('file-input'); fileInput.addEventListener('change', async (e) => { const file = (e.target as HTMLInputElement).files[0]; if (!file) return; // 2. 初始化输入(本地文件)和输出(WebM 格式,流式写入) const input = new Input({ source: new BlobSource(file), formats: ALL_FORMATS, }); const output = new Output({ format: new WebMOutputFormat({ width: 320, // 目标宽度 height: 180, // 目标高度 }), target: new StreamTarget(createWritableStream()), // 流式输出到文件 }); // 3. 执行转换 const conversion = await Conversion.init({ input, output }); await conversion.execute(); alert('转换完成!'); }); // 辅助函数:创建可写流(用于下载) function createWritableStream() { const chunks = []; return new WritableStream({ write(chunk) { chunks.push(chunk); }, close() { const blob = new Blob(chunks, { type: 'video/webm' }); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'converted.webm'; a.click(); }, }); } 四、性能碾压:数据说话,Mediabunny 有多快? Mediabunny 在官方测试中(环境:Ryzen 7600X + RTX 4070 + NVMe SSD),性能全面超越 ffmpeg.wasm、mp4box.js 等主流库,以下是关键场景的对比数据: 测试场景 Mediabunny 同类库性能(对比) 提取元数据(ops/s) 862 是 @remotion/media-parser(233)的 3.7 倍,ffmpeg.wasm(1.83)的 471 倍 迭代视频包(packets/s) 10800 是 web-demuxer(2390)的 4.5 倍 MP4 转 WebM + 缩放至 320x180(frames/s) 804 是 @remotion/webcodecs(324)的 2.5 倍,ffmpeg.wasm(12)的 67 倍 性能优势的核心原因: 按需加载:只读取必要数据,避免冗余处理; 硬件加速:借助 WebCodecs API 调用 GPU 编解码; 流水线设计:读写、编解码并行处理,减少等待时间。 五、为什么选择 Mediabunny?核心优势总结 专为 Web 设计,而非移植:零依赖、TypeScript 原生,API 符合 Web 开发习惯,树摇优化后体积极小(全功能仅 69.6KB,远小于 ffmpeg.wasm 的几 MB); 性能天花板:硬件加速 + 高效设计,解决浏览器端媒体处理“卡慢”问题; 易用性平衡:既有高层封装(如 Conversion 一键转换),又支持底层控制(如逐帧处理),满足从快速开发到定制化需求; 开源免费:基于 MPL-2.0 协议,可用于商业闭源项目,无license 顾虑。 六、局限性 浏览器兼容性取决于WebCodecs API的支持程度 复杂处理可能受限于客户端设备性能 目前可能还不支持一些专业级媒体处理功能 七、应用场景展望 Mediabunny 适合所有需要在浏览器中处理音视频的场景: Web 音视频编辑器(如在线剪片、加滤镜); 实时媒体处理(如摄像头直播前的美颜、分辨率调整); 离线媒体工具(如本地文件格式转换、元数据提取); 教育/医疗场景(如视频标注、音频分析)。 结语 Mediabunny 的出现,终于让 Web 开发者拥有了一个“原生、高效、易用”的音视频处理工具,无需再依赖后端或笨重的移植库。作为开源项目,它的发展离不开社区贡献,如果你在使用中遇到问题或有功能需求,可前往其 GitHub 仓库(需自行搜索,官网未直接提供链接)参与讨论。 如果你正在开发 Web 音视频相关项目,不妨试试 Mediabunny——它可能会让你的开发效率和产品性能都提升一个档次!

优秀的个人博客,低调大师

测试用例设计方法六脉神剑——第一剑:入门试招,等价边界初探 | 京东物流技术团队

1 背景及问题 G.J.Myers在<软件测试技巧>中提出:测试是为了寻找错误而运行程序的过程,一个好的测试用例是指很可能找到迄今为止尚未发现的错误的测试, 一个成功的测试是揭示了迄今为止尚未发现的错误的测试。 对于新手来说,日常测试用例设计时,很少用到系统的方法论,大多是根据产品需求文档或自己的主观判断直接进行测试用例的编写,经常会造成漏测等严重问题。所以,使用方法论支撑测试用例设计的过程,使其更加合理化、规范化,是一件至关重要的事情。但测试用例设计方法种类繁多,适用场景也各不相同,针对具体需求层面进行测试用例编写时,很难选取合适的方法来进行设计。 2 目标及意义 质量管理领域权威人物J.M.Juran将质量定义为“决定产品性能”和‘“满意程度’的特征”, 而测试注重于产品的满意度。 测试用例设计的过程是将产品需求转化为一种可操作性的步骤,在整个产品生命周期中发挥着至关重要的作用,基于方法论的规范化用例设计,能帮助测试人员拓展测试范围,完善测试覆盖面,降低漏测率,提升产品满意度。 本系列文章对经典的测试用例设计方法逐个进行剖析,并深入到日常工作的实际需求中,结合具体场景进行实战演练,并分别对各类方法的适用场景进行归纳梳理,形成可复用系统模板,帮助大家快速熟悉常用测试用例设计方法,提升测试人员专业度及工作效率,从而提升交付质量。 3 初探 说到测试用例设计方法,大家最容易想到的肯定是等价类和边界值法,所以,首先,我们将对这两种测试用例设计方法进行介绍。 3.1 等价类划分法 3.1.1 概念及原理 1.定义 等价类:某个输入域的子集合 等价类划分:有效等价类(合理的、有意义的输入集合) 无效等价类(不合理的 or 无意义的输入集合) 2. 基本思想 设计测试用例时,要同时考虑这两种等价类。因为软件不仅要能接收合理的数据,也要能经受意外的考验,这样的测试才能确保软件具有更高的可靠性。 3.1.2 方法步骤 根据需求,大体上可以先划分为有效和无效两种 然后再细化相应的等价类(从组合情况进行细化) 建立等价类表 生成测试用例 3.1.3 举个栗子 场景:一个输入框的输入规则为1~12位字母和数字组合 根据等价类划分法,具体可建立等价类表如下(把输入拆分成长度和符号组合两种),即可得到用例 划分 有效等价类 编号 无效等价类 编号 长度 [1,12] (1) 0 (2) - -  (12,+∞) (3) 符号 a (4) 数字+其它字符 (5) - -  其它字符 (6) 3.2 边界值分析法 3.2.1 概念及原理 1.定义 是等价类划分的一个补充方法,将等价类划分的边界作为用例设计(在有效和无效等价类的边界取值中,会存在值重复的情况,可按有效无效进行取舍)。 2. 基本思想 大量的错误是发生在输入或输出范围的边界上,而不是发生在输入输出范围的内部,所以为了保证测试质量,就需要重点测试边界,就有了边界值这样的测试方法。 3. 等价类和边界值的关系 边界值分析法是作为对等价类划分法的补充,边界值分析不是从某等价类中随便挑一个作为代表,而是使这个等价类的每个边界都要作为测试条件。 边界值数据本质上是属于某个等价类的范围,测试时有时是一种冗余(正好等于,刚刚大于或刚刚小于边界的值),但是为了更好的测试质量,边界值必须要单独进行测试,适当必要的冗余是可以接受的。 4. 使用方法 那我们怎么去找边界值呢?一般会关注以下几个点: **上点:**区间的端点值 **内点:**上点之间任意一点 离点:若是开区间的离点,就是开区间中上点内侧紧邻的点;若是闭区间的离点,就是闭区间中上点外侧紧邻的点 ① 闭区间 ② 半开半闭区间 ③ 开区间 3.2.2 举个栗子 场景:一个输入框的输入规则为1~12位字母和数字组合 具体可建立等价类表如下(把输入拆分成长度和符号组合两种) 根据边界值法,按照闭区间[1, 12]确定上点(1,12)、内点(2)、离点(0,13),建立等价类和边界值表如下(把输入拆分成长度和符号组合两种),即可得到用例。 划分 有效等价类 边界值 无效等价类 边界值 长度 [1,12] 1,2,11,12 0 0 - -  (12,+∞) 13 符号 a  数字+其它字符  - -  其它字符  3.3 测试设计——“等价类+边界值” 3.3.1 举个栗子 场景:手机号兼容座机号的格式校验 有横杠:XXX(3位或4位)-XXXXXXXX(7或8位):3+7或者3+8或者4+7或者4+8 有横杠有分机号:XXX(3位或4位)-XXXXXXXX(7或8位)-XXX(1-5位) 无横杠:XXX(3位或4位)XXXXXXXX(7或8位) 11位-17位 取消第一位必须为”1“,且取消第二位必须为“除0,1,2”限制。 设计步骤: 1.等价类划分:以第一条为例-有横杠:XXX(3位或4位)-XXXXXXXX(7或8位) 根据等价类划分法的步骤,首先进行拆分第一部分和第二部分,获得第一部分的有效等价类[3, 4]和无效等价类(len>4 & 0<len<3);获得第二部分的有效等价类[7,8]和无效等价类(len>8 & 0<len<7)。以此类推,获取所有的有效和无效等价类。 2. 边界值分析:根据区间开闭性,定位上点、内点、离点。 如:有效等价类[3, 4]的上点为3和4,无效等价类(len>4 & 0<len<3)的离点为5和2,内点无。 3. 数据处理:按照步骤1和2及数据的组合情况,列出所有的情况。 4. 整理最终用例:根据步骤3得到的数据,按照要求设计测试数据及相应的预期结果,得到最终测试用例。 4 总结 方法 等价类划分法 边界值分析法 核心 “分类”及代表值 边界值和边界两边的邻值 优点 通过把输入数据和输出数据进行分类,选用分类中的代表值,在保证了测试覆盖的情况下大大减少了测试用例的数量,使测试工作变得简单高效 大量的程序错误发生在输入的边界上,考虑了边界值的测试用例能更高效发现程序中的错误和缺陷 缺点 输入与输入之间的关系考虑少,可能产生一些逻辑错误。还需要其他用例设计方法来补充测试 只能作为一个对其他设计方法的补充;这种方法表面上听起来简单,但有的边界值非常微妙,不容易确定下来;只适用于多个变量相互独立又都代表实际物理量的情况,对变量之间的依赖关系则考虑不到。 适用场景 有数据输入(编辑框)的地方,可以使用等价类划分法。例如:用户登录、注册、新建、查询 有数据输入且存在取值边界或长度边界时,边界值法往往跟等价类划分法一起使用,从而形成一套较为完善的测试方案。 等价类划分和边界值分析法只考虑了单个的输入条件,在输入条件有各种组合、输入条件之间的相互制约关系的场景中很难发挥有效作用,这个时候就需要因果图与判定表法来帮助我们设计测试用例了,让我们一起来看看吧~ 作者:京东物流 陈雨婷 王鹏 张苑 李硕 来源:京东云开发者社区 自猿其说Tech 转载请注明来源

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册