Javascript 如何生成HTML5视频音量水平图?

Javascript 如何生成HTML5视频音量水平图?,javascript,html5-video,html5-audio,web-audio-api,Javascript,Html5 Video,Html5 Audio,Web Audio Api,给出一个30多岁的普通网络视频: <video src="my-video.mp4"></video> 注意: 请给我纯JavaScript。没有图书馆 根据用途的不同,有几种方法可以做到这一点 为了获得准确度,您可以使用传统的音量和单位进行测量,如LUFS/(K加权,响度),(满刻度dB)等 简单简单的方法是只绘制波形的峰值。你只会对正值感兴趣。为了获得峰值,您需要检测两点之间的方向,并在方向从上向下变化时记录第一个点(p0>p1) 对于所有方法,您最终可以应用某种

给出一个30多岁的普通网络视频:

<video src="my-video.mp4"></video>
注意:

  • 请给我纯JavaScript。没有图书馆

根据用途的不同,有几种方法可以做到这一点

为了获得准确度,您可以使用传统的音量和单位进行测量,如LUFS/(K加权,响度),(满刻度dB)等

简单简单的方法是只绘制波形的峰值。你只会对正值感兴趣。为了获得峰值,您需要检测两点之间的方向,并在方向从上向下变化时记录第一个点(p0>p1)

对于所有方法,您最终可以应用某种形式的平滑,如加权移动平均()或通用平滑算法,以消除小峰值和变化(RMS、dB等)。您可以使用窗口大小,该窗口大小可与bin平滑(每段平均数)相结合

若要打印,您将获得当前样本的值,假设它已规格化,并将其绘制为按打印区域高度缩放的画布线或点

关于加载源数据的小型讨论 解决评论中的一些问题;这些都是我脑子里想出来的,给我一些建议-

由于Web Audio API无法单独进行流式处理,因此必须将整个文件加载到内存中,并将音频曲目解码到缓冲区中

  • 优点:有效(分析部分),数据最终准备就绪时快速分析,适用于较小的文件,如果缓存的URL无需重新下载即可使用
  • 缺点:初始加载时间长/用户体验不好,可能占用内存/不适合大文件,音频与视频同步“分离”,强制重新使用URL*,如果大文件和/或缓存不到位,则必须重新下载/流式传输文件,目前会导致某些浏览器/版本出现问题(请参见下面的示例)
*:始终可以选择将下载的视频存储为IndexedDB中的blob(及其含义),并使用带有该blob的对象URL在视频元素中进行流式传输(可能需要MSE才能正常工作,我自己没有尝试过)

流式处理时打印:

  • 优点:内存/资源便宜
  • 缺点:在播放完整个文件之前,绘图无法完整显示,用户可能跳过/跳转部分,也可能无法完成
侧面加载低质量单声道音频文件:

  • 优点:音频可以独立于视频文件加载到内存中,结果非常接近级别使用
  • 缺点:可能会延迟视频的初始加载,可能无法在视频开始前及时准备好,需要提前进行额外处理
服务器端打印:

  • 优点:上传时可以打印,请求视频时可以存储作为元数据提供的原始打印数据,低带宽,视频开始时数据准备就绪(假设数据表示时间段的平均值)
  • 缺点:服务器上需要能够分离、分析和生成绘图数据的基础设施,这取决于数据的存储方式,可能需要修改数据库
我可能遗漏了或遗漏了一些要点,但它应该给出总体思路

例子 此示例测量每个样本给定窗口大小的常规dB。窗口大小越大,结果越平滑,但计算时间也会更长

请注意,为简单起见,在本示例中,像素位置决定dB窗口范围。这可能会产生不均匀的间隙/重叠,具体取决于影响当前采样值的缓冲区大小,但应适用于此处演示的目的。此外,为了简单起见,我将dB读数除以40,这是一个有点任意的数字(ABS仅用于绘图和我的大脑工作方式(?)在深夜/清晨,当我这样做时:))

我在顶部添加了红色的bin/段平滑,以便更好地显示与自动调平等相关的长期音频变化

我在这里使用的是音频源,但您可以插入视频源,只要它包含可以解码的音频曲目格式(aac、mp3、ogg等)

除此之外,这个例子就是那个,一个例子。这不是生产代码,所以请接受它的价值。根据需要进行调整

(由于某些原因,音频不会在FirefoxV58Beta中播放,但会打印。音频在Chrome、FF58dev中播放)

var ctx=c.getContext(“2d”),ref,audio;
var actx=new(AudioContext | | webkitadiocontext)();
var url=“//dl.dropboxusercontent.com/s/a6s1qq4lnwj46uj/testaudiobyk3n_lo.mp3”;
ctx.font=“20px无衬线”;
ctx.fillText(“加载和处理…”,10,50);
ctx.fillStyle=“#001730”;
//加载音频
获取(url,{mode:“cors”})
.then(函数(resp){return resp.arrayBuffer()})
.then(actx.decodeAudioData.bind(actx))
.then(功能(缓冲区){
//从通道0获取数据(您需要测量所有/平均值。)
var channel=buffer.getChannelData(0);
//每个窗口的dB+绘图
var点=[0];
ctx.clearRect(0,0,c.宽度,c.高度);
ctx.移动到(x,c.高度);
对于(变量x=1,i,v;x>1),总和*c.高度);//-r/2以进行视觉补偿
}
ctx.lineWidth=2;
ctx.strokeStyle=“#c00”;
ctx.stroke();
//仅适用于音频/进度条
c、 style.backgroundImage=“url”(+c.toDataURL()+”);
c、 宽度=c.宽度;
ctx.fillStyle=“#c00”;
奥迪
volume|
 level|    ******
      |   *      *                           **
      |  *        *                         *  **
      |**          *      ***              *    
      |             ** * *   *            *
      +---------------*-*-----************------+--- time
      0                                        30s
          video is             and quiet 
          loud here            here