1

我一直在制作网络游戏一段时间,我很快注意到,一旦我使用 .cloneNode(true) 多次播放同一个音频文件以避免每次我想播放音频文件时一遍又一遍地重新下载文件,我就松了控制诸如播放音量和播放速率之类的东西,有谁知道我如何才能重新控制音频文件的每个副本的这些参数?

我尝试为原始文件中的音频副本设置参数,但没有果汁

In the HTML : 
<audio src = "sight.wav" id="sight"/>
<button onclick="playSound()">Play some audio</audio>

In the Js
var get = new Function("id", "return document.getElementById(id)");

function playSound()
{
  get(sight).volume = 0.30;
  get(sight).playbackRate = 0.40;
  get(sight).cloneNode(true).play();
};

对我来说看起来像是有效的代码,但就像我说的那样,没有果汁,cloneNodes 完全忽略了音量和播放设置,只播放正常的音频。我应该怎么办?

4

1 回答 1

0

Node.cloneNode()在元素上调用时,将创建一个具有与原始节点相同属性的相同子类型的新元素。

在这里,您没有修改原始的attributes,而只是修改了一些未反映因此未克隆的 IDL 属性。

const original = document.querySelector("audio");
console.log( "default", [...original.attributes].map( (att) => att.name ) ); // []
original.volume = 0.2;
console.log( "volume set", [...original.attributes].map( (att) => att.name ) ); // []
original.controls = true;
console.log( "controls set", [...original.attributes].map( (att) => att.name ) ); // [ "controls" ]

const clone = original.cloneNode();
console.log( "clone volume", clone.volume ); // 1
console.log( "clone controls", clone.controls ); // true
<audio></audio>

因此,您可以重写代码,以便设置克隆元素的volume andplayBackRate而不是设置原始节点的元素,但请注意,如果您确实生成了多个相同的音频,您应该使用 Web-Audio API 及其AudioBuffer接口,它对播放这些媒体的时间提供了更大的控制,并且与初始化 DOM MediaElements 相比,它占用的内存要少得多。

于 2020-10-17T06:00:06.830 回答