整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

HTML 音频(Audio)

音在HTML中可以以不同的方式播放.

问题以及解决方法

在 HTML 中播放音频并不容易!

您需要谙熟大量技巧,以确保您的音频文件在所有浏览器中(Internet Explorer, Chrome, Firefox, Safari, Opera)和所有硬件上(PC, Mac , iPad, iPhone)都能够播放。

在这W3CSchool 为您总结了问题和解决方法。

使用插件

浏览器插件是一种扩展浏览器标准功能的小型计算机程序。

插件可以使用 <object> 标签 或者 <embed> 标签添加在页面上.

这些标签定义资源(通常非 HTML 资源)的容器,根据类型,它们即会由浏览器显示,也会由外部插件显示。

使用 <embed> 元素

<embed>标签定义外部(非 HTML)内容的容器。(这是一个 HTML5 标签,在 HTML4 中是非法的,但是所有浏览器中都有效)。

下面的代码片段能够显示嵌入网页中的 MP3 文件:

实例

<embed height="50" width="100" src="horse.mp3">

问题:

  • <embed> 标签在 HTML 4 中是无效的。页面无法通过 HTML 4 验证。

  • 不同的浏览器对音频格式的支持也不同。

  • 如果浏览器不支持该文件格式,没有插件的话就无法播放该音频。

  • 如果用户的计算机未安装插件,无法播放音频。

  • 如果把该文件转换为其他格式,仍然无法在所有浏览器中播放。

使用 <object> 元素

<object tag> 标签也可以定义外部(非 HTML)内容的容器。

下面的代码片段能够显示嵌入网页中的 MP3 文件:

实例

<object height="50" width="100" data="horse.mp3"></object>

问题:

  • 不同的浏览器对音频格式的支持也不同。

  • 如果浏览器不支持该文件格式,没有插件的话就无法播放该音频。

  • 如果用户的计算机未安装插件,无法播放音频。

  • 如果把该文件转换为其他格式,仍然无法在所有浏览器中播放。

使用 HTML5 <audio> 元素

HTML5 <audio> 元素是一个 HTML5 元素,在 HTML 4 中是非法的,但在所有浏览器中都有效。

The <audio> element works in all modern browsers.

以下我们将使用 <audio> 标签来描述 MP3 文件(Internet Explorer、Chrome 以及 Safari 中是有效的), 同样添加了一个 OGG 类型文件(Firefox 和 Opera浏览器中有效).如果失败,它会显示一个错误文本信息:

实例

<audio controls>

<source src="horse.mp3" type="audio/mpeg">

<source src="horse.ogg" type="audio/ogg">

Your browser does not support this audio format.

</audio>

问题:

  • <audio> 标签在 HTML 4 中是无效的。您的页面无法通过 HTML 4 验证。

  • 您必须把音频文件转换为不同的格式。

  • <audio> 元素在老式浏览器中不起作用。

最好的 HTML 解决方法

下面的例子使用了两个不同的音频格式。HTML5 <audio> 元素会尝试以 mp3 或 ogg 来播放音频。如果失败,代码将回退尝试 <embed> 元素。

实例

<audio controls height="100" width="100">

<source src="horse.mp3" type="audio/mpeg">

<source src="horse.ogg" type="audio/ogg">

<embed height="50" width="100" src="horse.mp3">

</audio>

问题:

  • 您必须把音频转换为不同的格式。

  • <embed> 元素无法回退来显示错误消息。

雅虎媒体播放器 - 一个简单的添加音频到你网站上的方式

使用雅虎播放器是免费的。如需使用它,您需要把这段 JavaScript 插入网页底部:

雅虎播放器可以播放MP3以及其他各种格式。你只需添加一行代码到你的页面或 博客中就可以轻松地将您的HTML页面制作成 专业的播放列表:

实例

<a href="horse.mp3">Play Sound</a>

<script src="http://mediaplayer.yahoo.com/latest"></script>

如果你要使用它,您需要把这段 JavaScript 插入网页底部:

<script src="http://mediaplayer.yahoo.com/latest"></script>

然后只需简单地把 MP3 文件链接到您的 HTML 中,JavaScript 会自动地为每首歌创建播放按钮:

<a href="song1.mp3">Play Song 1</a>

<a href="song2.wav">Play Song 2</a>

...

...

雅虎媒体播放器为您的用户提供的是一个小型的播放按钮,而不是完整的播放器。不过,当您点击该按钮,会弹出完整的播放器。

请注意,这个播放器始终停靠在窗框底部。只需点击它,就可将其滑出。

使用超链接

如果网页包含指向媒体文件的超链接,大多数浏览器会使用"辅助应用程序"来播放文件。

以下代码片段显示指向 mp3 文件的链接。如果用户点击该链接,浏览器会启动"辅助应用程序"来播放该文件:

实例

<a href="horse.mp3">Play the sound</a>

内联的声音说明

当您在网页中包含声音,或者作为网页的组成部分时,它被称为内联声音。

如果您打算在 web 应用程序中使用内联声音,您需要意识到很多人都觉得内联声音令人恼火。同时请注意,用户可能已经关闭了浏览器中的内联声音选项。

我们最好的建议是只在用户希望听到内联声音的地方包含它们。一个正面的例子是,在用户需要听到录音并点击某个链接时,会打开页面然后播放录音。

HTML 多媒体标签

New : HTML5 新标签

标签描述
<embed>定义内嵌对象。HTML4 中不赞成,HTML5 中允许。
<object>定义内嵌对象。
<param>定义对象的参数。
<audio>New定义了声音内容
<video>New定义一个视频或者影片
<source>New定义了media元素的多媒体资源(<video> 和 <audio>)
<track>New规定media元素的字幕文件或其他包含文本的文件 (<video> 和<audio>)

如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!

TML5 提供了播放音频文件的标准。

互联网上的音频

直到现在,仍然不存在一项旨在网页上播放音频的标准。

今天,大多数音频是通过插件(比如 Flash)来播放的。然而,并非所有浏览器都拥有同样的插件。

HTML5 规定了在网页上嵌入音频元素的标准,即使用 <audio> 元素。

浏览器支持

Internet Explorer 9+, Firefox, Opera, Chrome, 和 Safari 都支持 <audio> 元素.

注意: Internet Explorer 8 及更早IE版本不支持 <audio> 元素.

HTML5 Audio - 如何工作

如需在 HTML5 中播放音频,你需要使用以下代码:

实例

<audiocontrols><sourcesrc="horse.ogg"type="audio/ogg"><sourcesrc="horse.mp3"type="audio/mpeg">您的浏览器不支持 audio 元素。</audio>

control 属性供添加播放、暂停和音量控件。

在<audio> 与 </audio> 之间你需要插入浏览器不支持的<audio>元素的提示文本 。

<audio> 元素允许使用多个 <source> 元素. <source> 元素可以链接不同的音频文件,浏览器将使用第一个支持的音频文件

音频格式及浏览器支持

目前, <audio>元素支持三种音频格式文件: MP3, Wav, 和 Ogg:

浏览器MP3WavOgg
Internet Explorer 9+YESNONO
Chrome 6+YESYESYES
Firefox 3.6+YESYESYES
Safari 5+YESYESNO
Opera 10+YESYESYES

音频格式的MIME类型

FormatMIME-type
MP3audio/mpeg
Oggaudio/ogg
Wavaudio/wav

HTML5 Audio 标签

标签描述
<audio>定义了声音内容
<source>规定了多媒体资源, 可以是多个,在 <video> 与 <audio>标签中使用

如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!

家好,很高兴又见面了,我是"高级前端‬进阶‬",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。

今天给大家带来的主题是 standardized-audio-context,即 Web Audio API 的跨浏览器包装器,旨在严格遵循相关标准。话不多说,直接进入正题!

1.Web Audio API

1.1 什么是 Web Audio API

Web Audio API 提供了在 Web 上控制音频的一个非常有效的通用系统,允许开发者自选音频源,对音频添加特效,使音频可视化,添加空间效果(如平移)等等。

总之,Web Audio API 使用户可以在音频上下文(AudioContext)中进行音频操作,同时具有模块化路由的特点。在音频节点上操作基础的音频,连接在一起构成音频路由图。即使在单个上下文中也支持多源,尽管这些音频源具有多种不同类型通道布局。这种模块化设计提供了灵活创建动态效果的复合音频的方法。

一个简单而典型的 Web Audio 流程如下:

  • 创建音频上下文
  • 在音频上下文里创建源 — 例如 <audio>, 振荡器,流
  • 创建效果节点,例如:混响、双二阶滤波器、平移、压缩
  • 为音频选择一个目的地,例如系统扬声器
  • 连接源到效果器,对目的地进行效果输出

1.2 使用 Web Audio API

下面的示例展示了诸多 Web Audio API 接口的使用,包括对声音的音量进行改变。

var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// 定义音频上下文
// Webkit/blink 浏览器需要前缀,Safari 没有 window 将无法工作
var voiceSelect = document.getElementById("voice");
//  用于选择语音效果选项的选择框
var visualSelect = document.getElementById("visual");
// 用于选择音频可视化选项的选择框
var mute = document.querySelector(".mute");
// 静音按钮
var drawVisual;
// requestAnimationFrame
var analyser = audioCtx.createAnalyser();
// 创建一个AnalyserNode用来获取音频时间和频率数据以实现数据可视化。
var distortion = audioCtx.createWaveShaper();
// 创建了表示非线性失真的WaveShaperNode,通常被用来给音频添加失真效果
var gainNode = audioCtx.createGain();
// 创建一个 GainNode,可用于控制音频图的整体增益(或音量)
var biquadFilter = audioCtx.createBiquadFilter();
// 创建一个 BiquadFilterNode 表示一个二阶滤波器,可配置为几种不同的常见滤波器类型
function makeDistortionCurve(amount) {
  // 为失真/波形整形器节点使用创建曲线形状的函数
  var k = typeof amount === "number" ? amount : 50,
    n_samples = 44100,
    curve = new Float32Array(n_samples),
    deg = Math.PI / 180,
    i = 0,
    x;
  for (; i < n_samples; ++i) {
    x = (i * 2) / n_samples - 1;
    curve[i] = ((3 + k) * x * 20 * deg) / (Math.PI + k * Math.abs(x));
  }
  return curve;
}
navigator.getUserMedia(
  {
    // 限制 - 此应用程序仅需要音频
    audio: true,
  },
  // 成功回调
  function (stream) {
    source = audioCtx.createMediaStreamSource(stream);
    source.connect(analyser);
    analyser.connect(distortion);
    distortion.connect(biquadFilter);
    biquadFilter.connect(gainNode);
    gainNode.connect(audioCtx.destination);
    // 将不同的音频图节点连接在一起
    visualize(stream);
    voiceChange();
  },
  // 错误回调
  function (err) {
    console.log("The following gUM error occured: " + err);
  }
);
function visualize(stream) {
  WIDTH = canvas.width;
  HEIGHT = canvas.height;
  var visualSetting = visualSelect.value;
  console.log(visualSetting);
  if (visualSetting == "sinewave") {
    analyser.fftSize = 2048;
    var bufferLength = analyser.frequencyBinCount;
    // FFT 值的一半
    var dataArray = new Uint8Array(bufferLength);
    // 创建一个数组来存储数据
    canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);
    function draw() {
      drawVisual = requestAnimationFrame(draw);
      analyser.getByteTimeDomainData(dataArray);
      // 获取波形数据并将其放入上面创建的数组中
      canvasCtx.fillStyle = "rgb(200, 200, 200)";
      // 用画布画出波浪
      canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
      canvasCtx.lineWidth = 2;
      canvasCtx.strokeStyle = "rgb(0, 0, 0)";
      canvasCtx.beginPath();
      var sliceWidth = (WIDTH * 1.0) / bufferLength;
      var x = 0;
      for (var i = 0; i < bufferLength; i++) {
        var v = dataArray[i] / 128.0;
        var y = (v * HEIGHT) / 2;
        if (i === 0) {
          canvasCtx.moveTo(x, y);
        } else {
          canvasCtx.lineTo(x, y);
        }
        x += sliceWidth;
      }
      canvasCtx.lineTo(canvas.width, canvas.height / 2);
      canvasCtx.stroke();
    }
    draw();
  } else if (visualSetting == "off") {
    canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);
    canvasCtx.fillStyle = "red";
    canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
  }
}
function voiceChange() {
  distortion.curve = new Float32Array();
  biquadFilter.gain.value = 0;
  // 每次使用 voiceChange 函数时都会重置效果
  var voiceSetting = voiceSelect.value;
  console.log(voiceSetting);
  if (voiceSetting == "distortion") {
    distortion.curve = makeDistortionCurve(400);
    // 使用波形成形器节点对声音应用失真
  } else if (voiceSetting == "biquad") {
    biquadFilter.type = "lowshelf";
    biquadFilter.frequency.value = 1000;
    biquadFilter.gain.value = 25;
    // 使用双二阶将 Lowshelf 滤波器应用于声音
  } else if (voiceSetting == "off") {
    console.log("Voice settings turned off");
    // 不执行任何操作,因为选择了关闭选项
  }
}
// 用于更改可视化和语音设置的事件侦听器
visualSelect.onchange = function () {
  window.cancelAnimationFrame(drawVisual);
  visualize(stream);
};
voiceSelect.onchange = function () {
  voiceChange();
};
mute.onclick = voiceMute;
function voiceMute() {
  // 切换静音和取消静音
  if (mute.id == "") {
    gainNode.gain.value = 0;
    // gain set to 0 to mute sound
    mute.id = "activated";
    mute.innerHTML = "Unmute";
  } else {
    gainNode.gain.value = 1;
    // gain set to 1 to unmute sound
    mute.id = "";
    mute.innerHTML = "Mute";
  }
}

使用 Web Audio API,时间可以非常精确地控制,几乎没有延迟,开发人员可以准确地响应事件,并且可以针对采样数据进行编程。

Web Audio API 也使开发者能够控制音频的空间化。在基于源 - 侦听器模型的系统中,它允许控制平移模型和处理距离引起的衰减或移动源(移动侦听)引起的多普勒效应。

2.什么是 standardized-audio-context

standardized-audio-context 是 Web Audio API 的跨浏览器包装器,旨在严格遵循相关标准。standardized-audio-contex 包提供了 Web Audio API 的一个子集(几乎是完整的),可以在每个受支持的浏览器中以可靠且一致的方式工作。


与其他流行的 Polyfill 相比,standardized-audio-contex 不会在全局范围内污染或修改任何内容。 换句话说,它不会引起任何副作用。 因此,可以在任何库内安全使用,即所谓的 ponyfill。standardized-audio-contex 上下文的目标之一是仅实现缺失的功能,并尽可能避免重写内置功能。

但是,有些特性是无法以某种方式伪造的并使它们在与本机实现时具有相同的性能,其中最突出的是 AudioWorklet。

Web Audio API 的 AudioWorklet 接口用于提供在单独线程中执行的自定义音频处理脚本,以提供非常低延迟的音频处理。

工作集的代码在 AudioWorkletGlobalScope 全局执行上下文中运行,使用由工作集和其他音频节点共享的单独的 Web Audio 线程。

通过 BaseAudioContext.audioWorklet 属性访问音频上下文的 AudioWorklet 实例。

值得一提的是,standardized-audio-contex 是用 TypeScript 编写,这意味着它可以在任何 TypeScript 项目中无缝使用。与 TypeScript 提供的开箱即用的 Web 音频 API 类型相比,standardized-audio-contex 导出的类型实际上与具体实现相匹配。 TypeScript 根据 Web Audio API 的 Web IDL 定义生成其类型,该定义并不总是与实际可用的实现匹配。

目前,standardized-audio-context 在 Github 上通过 MTI 协议开源,有超过 0.6k 的 star、6.3k 的项目依赖量、NPM 周平均下载量 50k,是一个值得关注的前端开源项目。

3.使用 standardized-audio-context

standardized-audio-context 可在 npm 上使用,并且可以像其他库一样安装。

npm install standardized-audio-context

然后,可以以如下方式导入 AudioContext 和 OfflineAudioContext:

import { AudioContext, OfflineAudioContext } from "standardized-audio-context";
  • AudioContext :表示由链接在一起的音频模块构建的音频处理图,每个模块都由一个 AudioNode 表示。AudioContext 控制其包含的节点创建以及音频处理或解码的执行。 在执行其他操作之前,开发者需要创建一个 AudioContext,因为所有事情都发生在上下文中。 建议创建一个 AudioContext 并重用它,而不是每次都初始化一个新的,可以同时将单个 AudioContext 用于多个不同的音频源和管道。
  • OfflineAudioContext :是一个 AudioContext 接口,表示从链接在一起的 AudioNode 构建的音频处理图。 与标准 AudioContext 相比,OfflineAudioContext 不会将音频渲染到设备硬件。 相反,它会尽可能快地生成它,并将结果输出到 AudioBuffer。

开发者还可以使用 jspm 等服务加载标准化音频上下文。此时,上面的导入语句需要更改为指向 URL。

import {
  AudioContext,
  OfflineAudioContext,
} from "https://jspm.dev/standardized-audio-context";

一旦 AudioContext 和 OfflineAudioContext 被导入,开发者就可以原生方法一样使用。例如,以下代码片段将产生一个漂亮且干净的正弦波。

import { AudioContext } from "standardized-audio-context";
const audioContext = new AudioContext();
const oscillatorNode = audioContext.createOscillator();
// OscillatorNode 接口表示周期性波形,例如:正弦波。
// 它是一个 AudioScheduledSourceNode 音频处理模块
// 可以创建给定波的指定频率,实际上是恒定的音调
oscillatorNode.connect(audioContext.destination);
oscillatorNode.start();

另一种方法是使用 AudioNode 构造函数(在本例中为 OscillatorNode 构造函数)而不是工厂方法。

import { AudioContext, OscillatorNode } from "standardized-audio-context";
const audioContext = new AudioContext();
const oscillatorNode = new OscillatorNode(audioContext);
oscillatorNode.connect(audioContext.destination);
oscillatorNode.start();
// 指定开始播放提示音的确切时间

4.本文总结

本文主要和大家聊聊standardized-audio-context,即 Web Audio API 的跨浏览器包装器,旨在严格遵循相关标准。相信通过本文的阅读,大家对 standardized-audio-context 会有一个初步的了解,同时也会有自己的看法。

因为篇幅有限,文章并没有过多展开,如果有兴趣,可以在我的主页继续阅读,同时文末的参考资料提供了大量优秀文档以供学习。最后,欢迎大家点赞、评论、转发、收藏!

参考资料

https://github.com/chrisguttandin/standardized-audio-context

https://www.npmjs.com/package/standardized-audio-context

https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API/Using_Web_Audio_API

https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API

https://mdn.github.io/voice-change-o-matic/

https://developer.mozilla.org/en-US/docs/Web/API/AudioContext

https://habr.com/ru/articles/210422/