热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

webAudio学习与音频播放

随着浏览器的越发强大,用浏览器自带的api操作音频已经不是难事了。我们来使用webaudioapi简单地处理下音频资源。简介在学习webaudioapi之前,先了解三个概念:音频源

随着浏览器的越发强大,用浏览器自带的api操作音频已经不是难事了。我们来使用web audio api简单地处理下音频资源。

简介

在学习web audio api之前,先了解三个概念:

  • 音频源,也就是音频输入,可以是直接从设备输入的音频,也可以是远程获取的音频文件。
  • 处理节点,分析器和处理器,比如音调节点,音量节点,声音处理节点。
  • 输出源,指音频渲染设备,一般情况下是用户设备的扬声器,即context.destination。

其实,音频源和输出源也都可以视为节点,这三者的关系可以用这张图表示:

《web Audio学习与音频播放》

当然,实际使用中,可能会有n个处理节点,都可以使用connect依次关联起来。

音频文件播放

假如现在要用web audio api播放本地的一个音乐文件,按照前面的流程,我们来试下。

文件上传

既然音频文件来自本地,那么得支持文件上传:

我这儿限制了先显示wav和mp3两种格式。

文件读取

给input增加change事件,处理选中的文件:

var cOntext= new (window.AudioContext || window.webkitAudioContext)();
document.getElementById('file').addEventListener('change', function(e) {
var read = new FileReader();
read.Onload= function() {
// 将arrayBuffer转成audioBuffer
context.decodeAudioData(this.result, function(buffer) {
playSound(buffer);
}, function() {
console.log('error');
});
};
// 利用filereader将file转成arraybuffer格式
read.readAsArrayBuffer(this.files[0]);
});

丢了一段代码,我们来看下,new AudioContext(),创建audio的上下文环境,至于webkitAudioContext是兼容较低版本的chrome的。

fileReader大伙应该见到的比较多了吧,这儿用他读取对应file对象中的文件数据,readAsArrayBuffer表示读取结果用arrayBuffer对象显示,由于此方法是异步读取的,所以只能放在onload回调中处理。

而我们拿到的arrayBuffer不能直接给web audio播放,需要使用decodeAudioData()方法将arrayBuffer转成audioBuffer,那么此时转化后的audioBuffer就是音频源啦。decodeAudioData更多介绍可以查看MDN:https://developer.mozilla.org…。

注:w3c文档上说明decodeAudioData支持audio标签支持的所有音频格式。

音频播放

音频数据到手,接下来就是播放啦。

文件上传后,我们拿到了音频audioBuffer形式的数据,接下来使用createBufferSource()方法播放音频数据,再connect到destination就可以播放了。

// 播放音频
function playSound(buffer) {
var source = context.createBufferSource();
// 设置数据
source.buffer = buffer;
// connect到扬声器
source.connect(context.destination);
source.start();
}

一个简单的音频文件播放器就完成了,如果是从服务器上获取文件也是类似的,只不过是多了个ajax处理。

代码地址:webAudio播放本地音乐。

音频的话,可以去一些音乐网站下载,如果懒得下的话,我这直接提供音频下载:林俊杰_-_我还想她.mp3

小bug

当连续选择多个文件时,你会发现,多个音频文件一起播放了,因此,多音频输入时,都一起connect到context.destination上就可以实现一起播放了。对于此处,这应该算是个bug,查看AudioBufferSourceNode文档,可以利用stop()方法去处理,大伙自个想下,处理下咯。

前面的例子里只出现了音频源和音频输出,并未出现处理节点。接下来,我们尝试自己创建音频,并使用音量处理节点。

自制音频并播放

创建音频源

此处我们不使用外部的音频文件,而是使用createOscillator()方法创建音频源。

该方法返回OscillatorNode,可以通过frequency属性设置他的振荡频率,type属性则可以用来指定要播放的波形。更多属性和方法参考OscillatorNode文档。

var cOntext= new (window.AudioContext || window.webkitAudioContext)();
var oscillator = context.createOscillator();
// oscillator.type = 'sine';
// oscillator.frequency.value = 800; // 频率800Hz,默认440

创建音量处理节点

使用createGain()方法,修改返回值中的value,既可以改变音量大小。

var gainNode = context.createGain();
gainNode.gain.value = 0.8; // 音量 0 ~ 1

节点关联与播放

将这些”节点”connect起来就可以播放了。

oscillator.connect(gainNode); // 音频源关联到音量
gainNode.connect(context.destination); // 音量关联到扬声器
// chrome 73 需要用户点击才可播放
document.getElementById('start').addEventListener('click', function() {
oscillator.start();
});

虽然播放后是一片噪音,不过简单的web audio api我们已经会使用啦。

代码地址:webAudio制造噪音并播放。

其他

自己尝试过程中,在控制台下遇到这个警告:

The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.

《web Audio学习与音频播放》

大概意思就说AudioContext需要用户手动触发,所以只需要将new AudioContext()移动到事件内部就行了。

总结

我们已经能够使用web audio播放本地音乐和制造噪音了,接下来,可以尝试下其他的api了。

阅读原文。

欢迎关注微信公众号[ 我不会前端 ]或扫描下方二维码!

《web Audio学习与音频播放》


推荐阅读
  • 本文探讨了如何通过优化 DOM 操作来提升 JavaScript 的性能,包括使用 `createElement` 函数、动画元素、理解重绘事件及处理鼠标滚动事件等关键主题。 ... [详细]
  • 使用HTML和JavaScript实现视频截图功能
    本文介绍了如何利用HTML和JavaScript实现从远程MP4、本地摄像头及本地上传的MP4文件中截取视频帧,并展示了具体的实现步骤和示例代码。 ... [详细]
  • 函子(Functor)是函数式编程中的一个重要概念,它不仅是一个特殊的容器,还提供了一种优雅的方式来处理值和函数。本文将详细介绍函子的基本概念及其在函数式编程中的应用,包括如何通过函子控制副作用、处理异常以及进行异步操作。 ... [详细]
  • 本文详细介绍了如何在Oracle VM VirtualBox中实现主机与虚拟机之间的数据交换,包括安装Guest Additions增强功能,以及如何利用这些功能进行文件传输、屏幕调整等操作。 ... [详细]
  • 问题场景用Java进行web开发过程当中,当遇到很多很多个字段的实体时,最苦恼的莫过于编辑字段的查看和修改界面,发现2个页面存在很多重复信息,能不能写一遍?有没有轮子用都不如自己造。解决方式笔者根据自 ... [详细]
  • 如何从BAM文件绘制ATAC-seq插入片段长度分布图?
    在ATAC-seq数据处理中,插入片段长度的分布图是一个重要的质量控制指标,它能反映出核小体的周期性排列。本文将详细介绍如何从BAM文件中提取并绘制这些数据。 ... [详细]
  • 本文详细介绍了在Linux操作系统上安装和部署MySQL数据库的过程,包括必要的环境准备、安装步骤、配置优化及安全设置等内容。 ... [详细]
  • 本文介绍了如何在 Node.js 中使用流(Stream)进行数据读取与写入,包括创建可读流与可写流的基本方法,并提供了具体的代码示例。 ... [详细]
  • JavaScript 实现图片文件转Base64编码的方法
    本文详细介绍了如何使用JavaScript将用户通过文件输入控件选择的图片文件转换为Base64编码字符串,适用于Web前端开发中图片上传前的预处理。 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • IO流——字符流 BufferedReader / BufferedWriter 进行文件读写
    目录节点流、处理流读文件:BufferedReader的使用写文件:BufferedWriter的使用节点流处理流节点流和处理流的区别和联系字符流Buf ... [详细]
  • h5调用本地摄像头和麦克风一
    h5调用本地摄像头和麦克风一,Go语言社区,Golang程序员人脉社 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • Windows Phone 弹出窗口实现方案
    在当前版本的 Silverlight for Windows Phone 中,由于缺乏对 ChildWindow 的支持,开发者需要采用其他方法来实现弹出窗口的功能。本文将探讨几种有效的解决方案。 ... [详细]
  • C# 中创建和执行存储过程的方法
    本文详细介绍了如何使用 C# 创建和调用 SQL Server 存储过程,包括连接数据库、定义命令类型、设置参数等步骤。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有