Web Audio API DEMO

  一转眼就已经有三个月没写博客了,毕业季事情确实多,现在也终于完全毕业了,博客还是不能落下。偶尔还是要写一下。

  玩HTML5的Audio API是因为之前看到博客园里有关于这个的博客,觉得挺好玩的,所以就学习了一下。本文仅作为自己的学习记录。如有错误之处请指出。

    最终的效果也就如右图,楼主只是简单的做了个demo,如果要有更复杂的效果,园友们可以自己去玩一下 

  DEMO链接:请戳我!!!   选择音频文件后即可播放

  同时,这个API目前浏览器支持度不高,若要用于生产环境,请自行斟酌。

  首先,要做成这种效果,要分几步:

  1、获取音频文件,实例化一个音频容器对象。

  2、通过FileReader把音频文件转成ArrayBuffer后再对其进行解码。

  3、将解码后的buffer数据通过AudioBufferSourceNode接口传给音频容器对象并且播放。

  4、使用AnalyserNode接口实例化一个分析器。

  5、使用分析器获取音频播放时的各个频率。

  6、根据频率在canvas上画出来。

  大概说起来就以上几步,具体代码分析如下:

  先将要用到的对象先定义好:其中包括audioContext音频容器对象,以及canvas的2d绘图环境对象,requestAnimationFrame的兼容性写法。

var music = document.getElementById("music"),canvas = document.getElementById("cas"),ctx=canvas.getContext("2d");

window.AudioContext= window.AudioContext||window.webkitAudioContext||window.mozAudioContext;
window.RAF =  (function(){
            return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {window.setTimeout(callback, 1000 / 60); };
})();
var AC = new AudioContext();

  

  然后就获取音频文件,可以直接通过input file来获取,或者用xhr也行。楼主为了方便,做的demo上就是直接用input file来获取音频文件。代码如下:通过onchange事件来获取到音频文件music.file[0]。再对音频文件进行解码,也就是changeBuffer方法要做的事。

music.onchange = function(){
            if(music.files.length!==0){
                changeBuffer(music.files[0]);
            }
        }        

  

  获取到了音频文件,先用FilreReader将文件转成ArrayBuffer对象,在加载完后可以通过e.target.result获取到文件内容。

  然后再对文件内容进行解码,用到的就是audioContext对象里的decodeAudioData方法。根据官方API文档得知,该方法有三个参数:第一个是就是音频ArrayBuffer对象,第二个是成功解码完毕后的回调,第三个是解码失败后的回调

function changeBuffer(file){
            var fr = new FileReader();
            fr.onload = function(e){
                var fileResult = e.target.result;
                AC.decodeAudioData(fileResult , function(buffer){
                    playMusic(buffer)
                }, function(e){
                    console.log(e)
                    alert("文件解码失败")
                })
            }
            fr.readAsArrayBuffer(file);
        }

  

  解码成功后悔调用playMusic方法,并且传入解码后的buffer数据,此时实例化一个AudioBufferSource对象,AudioBufferSource对象的属性有五个。分别是:buffer、playbackRate、loop、loopstart和loopend,buffer自然就是音频buffer数据,playbackRate是渲染音频流的速度,其默认值是1。loop则是播放循环属性,默认为false,如果设为true则会循环播放音频。loopstart和loopend则是循环开始和结束的时间段,以秒为单位,默认值均为0,只有当loop的值为true的时候这两个属性才会起效。

  实例化AudioBufferSource对象后,要给与音频一个输出目的地,也就是要将音频连接到扬声器上,通过connect(audioContext.destination)连接。

  然后创建一个分析器,直接通过createAnalyser方法创建一个分析器。同样,通过connect方法将音频跟分析器连接起来。

  准备完毕后,则调用start方法,开始播放音频。然后再跳转到canvas的绘图方法animate中,将音谱绘制出来。

var analyser;
        function playMusic(buffer){
            var absn = AC.createBufferSource();
            analyser = AC.createAnalyser();
            absn.connect(analyser);
            absn.connect(AC.destination);
            absn.buffer = buffer;
            absn.loop = true;
            absn.start(0);
            animate()
        }

  

  前面两段代码楼主也不是很懂,看了官方API得知analyser的frequencyBinCount的值为:Half the FFT size,而据楼主网上查的资料得知FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。同时FFT还可以将一个信号的频谱提取出来。也就是说这两段代码应该就是使用FFT算法将音频各个频率的信息提取出来转换成数组,数组里的每一个值都代表音频在当前频率的信号量。根据这些信号量就可以很清晰的看出各个频率的差别

  获取到各个频率的信号量后,就可以通过这些参数进行绘制不同的条形图,就完成了最简单的音频动画了。

function animate(){
            var array = new Uint8Array(analyser.frequencyBinCount);
            analyser.getByteFrequencyData(array);
            ctx.clearRect(0,0,canvas.width,canvas.height);
            for(var i=0;i<array.length;i+=10){
                ctx.fillRect(i,canvas.height-array[i] , 10 , array[i]);
                ctx.strokeStyle = "#FFF"
                ctx.strokeRect(i,canvas.height-array[i] , 10 , array[i]);
            }
            RAF(animate)
        }

下面贴出全部代码:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style type="text/css">
        #cas{
            position: absolute;
            left:0;top:0;bottom: 0;right: 0;
            margin: auto;
            border: 1px solid;
        }
    </style>
</head>
<body>
    <input type="file" name="" id="music" />
    <canvas id="cas" width="1000" height="540"></canvas>
    <script type="text/javascript" charset="utf-8">
        var music = document.getElementById("music"),canvas = document.getElementById("cas"),ctx=canvas.getContext("2d");

        window.AudioContext= window.AudioContext||window.webkitAudioContext||window.mozAudioContext;
        window.RAF =  (function(){
            return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {window.setTimeout(callback, 1000 / 60); };
        })();

        var AC = new AudioContext();

        music.onchange = function(){
            if(music.files.length!==0){
                changeBuffer(music.files[0]);
            }
        }

        function changeBuffer(file){
            var fr = new FileReader();
            fr.onload = function(e){
                var fileResult = e.target.result;
                AC.decodeAudioData(fileResult , function(buffer){
                    playMusic(buffer)
                }, function(e){
                    console.log(e)
                    alert("文件解码失败")
                })
            }
            fr.readAsArrayBuffer(file);
        }

        var analyser;
        function playMusic(buffer){
            var absn = AC.createBufferSource();
            analyser = AC.createAnalyser();
            absn.connect(analyser);
            absn.connect(AC.destination);
            absn.buffer = buffer;
            absn.loop = true;
            absn.start(0);
            animate()
        }

        function animate(){
            var array = new Uint8Array(analyser.frequencyBinCount);
            analyser.getByteFrequencyData(array);
            ctx.clearRect(0,0,canvas.width,canvas.height);
            for(var i=0;i<array.length;i+=10){
                ctx.fillRect(i,canvas.height-array[i] , 10 , array[i]);
                ctx.strokeStyle = "#FFF"
                ctx.strokeRect(i,canvas.height-array[i] , 10 , array[i]);
            }
            RAF(animate)
        }
    </script>
</body>
</html>

Web Audio API DEMO,布布扣,bubuko.com

时间: 2024-10-07 18:27:04

Web Audio API DEMO的相关文章

【HTML5】Web Audio API打造超炫的音乐可视化效果

HTML5真是太多炫酷的东西了,其中Web Audio API算一个,琢磨着弄了个音乐可视化的demo,先上效果图: 项目演示:别说话,点我!  源码已经挂到github上了,有兴趣的同学也可以去star或者fork我,源码注释超清楚的哦~~之前看刘大神的文章和源码,感觉其他方面的内容太多了,对初学者来说可能一下子难以抓到Web Audio API的重点,所以我就从一个初学者的角度来给大家说说Web Audio API这些事吧. Web Audio API与HTML5提供的Audio标签并不是同

ASP.NET Core环境Web Audio API+SingalR+微软语音服务实现web实时语音识别

处于项目需要,我研究了一下web端的语音识别实现.目前市场上语音服务已经非常成熟了,国内的科大讯飞或是国外的微软在这块都可以提供足够优质的服务,对于我们工程应用来说只需要花钱调用接口就行了,难点在于整体web应用的开发.最开始我实现了一个web端录好音然后上传服务端进行语音识别的简单demo,但是这种结构太过简单,对浏览器的负担太重,而且响应慢,交互差:后来经过调研,发现微软的语音服务接口是支持流输入的连续识别的,因此开发重点就在于实现前后端的流式传输.参考这位国外大牛写的博文Continuou

[Javascript] Intro to the Web Audio API

An introduction to the Web Audio API. In this lesson, we cover creating an audio context and an oscillator node that actually plays a sound in the browser, and different ways to alter that sound. var context = new window.AudioContext() || new window.

关于Web Audio API的入门

Web Audio API提供了一个简单强大的机制来实现控制web应用程序的音频内容.它允许你开发复杂的混音,音效,平移以及更多. 可以先看一下MDN的这篇文章<Web Audio API的运用>  https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API/Using_Web_Audio_API 不过,看了上述文章后可能还是不知道怎么用Web Audio API来实现一些简单的功能,比如播放一段mp3音频,文章中并没有相应的例

web audio living

总结网页音频直播的方案和遇到的问题. 代码:(github,待整理) 结果: 使用opus音频编码,web audio api 播放,可以达到100ms以内延时,高质量,低流量的音频直播. 背景: VDI(虚拟桌面) h264网页版预研,继h264视频直播方案解决之后的又一个对延时有高要求的音频直播方案(交互性,音视频同步). 前提: flexVDI开源项目对音频的支持只实现了对未编码压缩的PCM音频数据.并且效果不好,要么卡顿,要么延时,流量在2~3Mbps(根据缓冲的大小). 解决方案: 在

Web Audio介绍

Web Audio还是一个比较新的JavaScript API,它和HTML5中的<audio>是不同的,简单来说,<audio>标签是为了能在网页中嵌入音频文件,和播放器一样,具有操作界面,而Web Audio则是给了开发者对音频数据进行处理.分析的能力,例如混音.过滤等,类似于对音频数据进行PS. 一般的网站应用应该是用不倒这些API中的,但是一些游戏引擎或者在线音乐编辑等类型的网站应该用得到. Web Audio API紧紧围绕着一个概念设计:audio context,它就

一个非常轻量级的 Web API Demo

一个非常轻量级的 Web API Demo,代码量很少,实现了方法拦截器,token校验,异常拦截器,缓存 创建项目:如果选择Web API,项目中东西会比较多,这里选择Empty,把下面的Web API勾上,MVC不要勾 项目目录结构:  Global.asax.cs代码:这里配置方法拦截器和异常拦截器 using System; using System.Collections.Generic; using System.Linq; using System.Web; using Syste

HTML5项目笔记4:使用Audio API设计绚丽的HTML5音乐播放器

HTML5 有两个很炫的元素,就是Audio和 Video,可以用他们在页面上创建音频播放器和视频播放器,制作一些效果很不错的应用. 无论是视屏还是音频,都是一个容器文件,包含了一些音频轨道,视频轨道和一些元数据,这些是和你的视频或者音频控件绑定到一块的,这样才形成了一个完整的播放组件. 浏览器支持情况: 浏览器 支持情况 编解码器 Chrome 3.0 Theora . Vorbis .Ogg H.264 . AAC .MPEG4 FireFox 3.5 Theora . Vorbis .Og

【完全开源】百度地图Web service API C#.NET版,带地图显示控件、导航控件、POI查找控件

目录 概述 功能 如何使用 参考帮助 概述 源代码主要包含三个项目,BMap.NET.BMap.NET.WindowsForm以及BMap.NET.WinformDemo. BMap.NET 对百度地图Web Service API 的一些封装,每个接口返回的都是JObject类型(参见Json.NET): BMap.NET.WindowsForm(开始少写了一个s ,后来一直没改) 提供一系列可以在Winform中使用的控件,包括地图显示控件.导航控件.POI查找控件等等: BMap.NET.