【问题标题】:How to load multiple audio players by array's length and play different sound on each?如何按数组的长度加载多个音频播放器并在每个播放器上播放不同的声音?
【发布时间】:2016-02-20 22:33:13
【问题描述】:

我正在尝试在一个 HTML 页面上出现的不同音频播放器上加载不同的声音(.mp3 音频)。也就是说,数组的长度决定了屏幕上出现的玩家数量。所以,在这个例子中,我在数组中有 3 个元素。因此,3 个音频播放器播放 3 种不同的东西。

我已经设法将 3 个玩家放在第一页上,就像我为他们的等效文本(动物声音)所做的那样,但 我面临以下问题

  1. 每个播放器播放相同的声音,而不是递增并为不同的播放器播放每个播放器。 我使用“for循环”来增加数组,但我找不到让它“记住”旧音频的方法,所以它总是通过所有播放器播放最后一个声音。在这种情况下,它只播放“猫”。

  2. 即使我点击空行,在第一个和第二个播放器之间,没有音频播放器 - 声音仍在播放,我不知道为什么.. .

我将非常感谢任何帮助!!!

//use JQuery to grab the audioID and play the audio 
jQuery(document).ready(function() {
	var speakWord = document.getElementsByClassName('speakout');
			var nowPlaying = speakWord[0];
			nowPlaying.load();
			$("#divAudio").on("click", function() {
			nowPlaying.play();
			});
	});	

var textBox = document.getElementById('inBox');   			//Responsible for printing words
var player = document.getElementById('myPlayer');			//PLAYING the sound (<audio>)
var outArr = ['Dog', 'Cow','Cat'];
var pathArr = ['http://cd.textfiles.com/mmplus/MEDIA/WAV/EFFECTS/BARK.WAV', 'http://www.internetstart.se/download/ljud/moo.wav', 'http://area512.htmlplanet.com/wavs/blackcat.wav'];
var audioLogo = document.getElementById('divAudio');		//for the APPEREANCE of the audio player (LOGO)
var img_audio = document.createElement("IMG");				// properties of the IMAGE 
br = document.createElement("br");          			//creating a break in the document 
var new_audio = document.createElement("audio");

var points = 50;

if(outArr.constructor === Array) {
	//audioLogo.style.display = "initial";
	for(i=0; i < outArr.length; ++i) {
		
		//regarding the TEXT elements:
		textBox.innerHTML += outArr[i]+'<br>';  
		textBox.style.fontSize = "30px";
		textBox.style.position = "absolute";
		textBox.style.top = String(points)+'pt';
		textBox.style.marginRight= "5pt";
		textBox.style.lineHeight = "71pt";
		textBox.style.right = '5pt';	
	}
}
else {
	textBox.innerHTML += outArr;
	textBox.style.fontSize = "30px";
	textBox.style.position = "absolute";
	textBox.style.top = "76pt";
}
var points = 70;
for(i=0; i < pathArr.length; ++i) {
			var new_audio = document.createElement("audio");
			var multiAud = audioLogo.querySelectorAll('.multiple_audio');
			
			imgArr =  Array(pathArr.length).fill('http://www.coli.uni-saarland.de/~andreeva/powin/images/sound.png');
			if(i<1){
			img_audio.style.height = "9%";  //the size of the audio logo
			img_audio.style.width = "9%";
			img_audio.setAttribute("src", imgArr[i]); //creating an attribute (image) to be added to doc
			audioLogo.style.position = "absolute";   
			audioLogo.style.top = '58pt';		
			audioLogo.style.lineHeight = "73pt";
			player.src = pathArr[i]; 
			audioLogo.appendChild(img_audio); 
			audioLogo.innerHTML +=  '<br>';
			}
			else {
			var audio = new Audio(pathArr[i]);
			audio.className = 'multiple_audio';
			img_audio.style.height = "9%";
			img_audio.style.width = "9%";
			img_audio.setAttribute("src", imgArr[i]); //creating an attribute (image) to be added to doc
			audioLogo.style.position = "absolute";
			audioLogo.style.top = '58pt';
			audioLogo.style.lineHeight = "73pt";
			audioLogo.appendChild(img_audio);
			player.src = pathArr[i]; 
			audioLogo.innerHTML +=  '<br>';
			//player.parentNode.insertBefore(audio , player.nextNode); 
			}
			
		}
#layout {
position: relative;
overflow: auto;
left: 225px;
width: 	800px;
height: 370px;
background-color: white;  
padding-left: 1px;
max-width:100%;
}

#myText {
pointer-events: none;
width: 	800px;
height: 370px;
resize: none;
font-size: 45px;
font-family: Arial, Helvetica, Verdana;
background: url(https://qph.is.quoracdn.net/main-qimg-47327da6ae3e0b3727a9b9a7ea7f1adb?convert_to_webp=true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<html lang="en">
    <head>
	<meta charset="utf-8"/>
    <script type="text/javascript" src="jquery-1.11.3.js"></script>
    </head>
    <body>
	<br>
		<div id="layout" readonly="readonly">
		<div contenteditable maxlength="200" readonly="readonly" id="myText" dir="auto" name="outtest" class = "fetchBox"></div> 
		<div id="inBox" class="fetch" dir="auto"></div>
		
		 <audio class="speakout" id="myPlayer"> 

			Your Browser does not support the HTML audio Tag!
		</audio>
		
		<div class="play" id="divAudio"><img id="play_image"> </div>
		
		</div>
				
</body>
  
</html>

附言

  • 音频标签不能是标准的,默认显示为播放/暂停。我使用了自己的播放器徽标,但在本示例中,我从绝对 URL 链接了一个徽标。

  • 我尝试使用其他帖子中的提示 (multiple and dynamic audio players applied for a dictionary in HTML/JavaScript) 但这并没有那么好。我尝试使用

    var audio = new Audio(); 和

    player.parentNode.insertBefore(audio, player.nextNode);

解决问题1。 不确定,可能是因为没有使用标准播放器?

【问题讨论】:

    标签: javascript html css audio


    【解决方案1】:

    更新 2

    根据 OP 的要求,HTML5 音频元素的原生控件已替换为自定义暂停/播放按钮。我没有为每个音频添加事件侦听器,而是采用了article 中的一种技术。

    • 当在.arrayBox(包含所有玩家的&lt;section&gt;)上检测到点击时调用新函数handlePlay()

    • handlePlay() 将确定实际点击了哪些按钮,然后播放或暂停点击按钮之后的音频元素。

    • 添加了新的按钮对象ybtn 以在生成音频元素之前生成。

      • 可以使用.btn 类设置新按钮的样式。
      • 注意按钮的内容是一种字体:
        • ?&amp;#128264;关闭
        • ? &amp;#128266; 开启
        • 此替代方法的加载速度比图片更快,而且它会减少 HTTP 请求。

    Plunker

    片段

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <title>DeXY Player</title>
      <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1, maximum-scale=1, user-scalable=0" />
      <link href='https://fonts.googleapis.com/css?family=Raleway:600' rel='stylesheet' />
      <style>
        html {
          box-sizing: border-box;
          font: 500 16px/1.428 'Raleway';
          height: 100vh;
          width: 100vw;
        }
        
        *,
        *:before,
        *:after {
          box-sizing: inherit;
          margin: 0;
          padding: 0;
        }
        
        body {
          position: relative;
          font-size: 1rem;
          line-height: 1;
          height: 100%;
          width: 100%;
          overflow-x: hidden;
          overflow-y: auto;
          -webkit-font-smoothing: antialiased;
          background: #222;
          color: #fc2;
        }
        
        button {
          font: inherit;
          line-height: 1.5;
          padding: 1px 3px;
          border-radius: 8px;
          border: 1px solid #00f;
          margin: 20px;
          background: rgba(0, 0, 0, .4);
          color: #00f;
          cursor: pointer;
        }
        
        button:hover {
          border: 1px solid #0ff;
          color: #0ff;
        }
    
        .btn {/* The audio buttons' styles */
          display: inline-block;
        }
      </style>
    </head>
    
    <body>
      <h1>DeXY Audio Array Player</h1>
      <button id="btn1"><a>Load</a></button>
      <section id="arrayBox">
        
      </section>
      <script>
    //This array of strings is a required input needed to run DeXY Player.
     
        var playList = ['http://glpjt.s3.amazonaws.com/so/av/day01.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day02.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day03.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day04.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day05.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day06.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day07.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day08.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day09.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day10.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day11.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day12.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day13.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day14.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day15.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day16.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day17.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day18.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day19.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day20.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day21.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day22.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day23.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day24.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day25.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day26.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day27.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day28.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day29.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day30.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day31.mp3'];
    
    //qty is the total quantity of elements within the playList array.
    
        var qty = playList.length;
        console.log('qty: ' + qty);
      </script>
      <script>
        var aBox = document.getElementById('arrayBox');
        var btn1 = document.getElementById('btn1');
    //Click event triggers a callback: loadPlayers()
        aBox.addEventListener('click', handlePlay, false);
        btn1.addEventListener('click', loadPlayers, false);
    
        function loadPlayers() {
          var dArray = [];
    //Each iteration creates a div#dx{?}.snd, appends it to the section, and then is pushed into dArray.
    
          for (var d = 0; d < qty; d++) {
            var division = document.createElement('div');
            division.id = "dx" + d;
            division.className = 'snd';
            aBox.appendChild(division);
            dArray.push(division);
          }
    //Each iteration creates an audio element audio#x{?}, adds a series of attributes, and is assigned a MP3 from thr playlist.     
          
          for (var x = 0; x < qty; x++) {
            var ID = dArray[x].getAttribute('id');
            var xTag = document.createElement('audio');
            var yBtn = document.createElement('button');
            var xDiv = document.getElementById(ID);
            var xID = ID.substr(1, 3);
            var yID = ID.substr(2, 3);
            var xUrl = playList[x];
            
            xDiv.appendChild(yBtn);
            yBtn.setAttribute('id', 'y' + yID);
            yBtn.className ="btn";
            console.log('Player Button ID: '+ yBtn.id);
            yBtn.innerHTML = "&#128264;&nbsp;"; 
            yBtn.style.fontSize = "24px";
            yBtn.style.lineHeight = 1;
    
            xDiv.appendChild(xTag);
            xTag.setAttribute('id', xID);
            xTag.setAttribute('preload', 'auto');
            xTag.setAttribute('src', xUrl);
          }
        }
        
        function handlePlay(e) {
          if (e.target !== e.currentTarget) {
            var button = e.target.id;
            var btn = document.getElementById(button);
            console.log('button: '+btn);
            var clip = btn.nextSibling.id;
            console.log('clip: '+clip);
            var audio = document.getElementById(clip);
            console.log('audio '+audio);
            if(audio.paused) {
              audio.play();
              btn.innerHTML ="&#128266;"
              btn.style.color ="#0ff";
              btn.style.padding = '1px';
              btn.style.border = '1px solid #0ff';
            }
            else {
              audio.pause();
              btn.innerHTML ="&#128264;&nbsp;"
              btn.style.color ="#00f";
              btn.style.padding = '1px 5px';
              btn.style.border = '1px solid #00f';
            }
          }
          e.stopPropagation();
        }
    
      </script>
    </body>
    
    </html>

    更新

    经过与 OP 的简短讨论,我更新了最新版本。此版本将接受并使用字符串数组作为播放列表。将所有内容重构为单个函数。一键点击,31个功能音频播放器瞬间出现。 JS中有cmets作为函数loadPlayers()的简单演练。

    Plunker

    片段

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <title>dXPlayer</title>
      <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1, maximum-scale=1, user-scalable=0" />
      <link href='https://fonts.googleapis.com/css?family=Raleway:600' rel='stylesheet' />
      <style>
        html {
          box-sizing: border-box;
          font: 500 16px/1.428 'Raleway';
          height: 100vh;
          width: 100vw;
        }
        
        *,
        *:before,
        *:after {
          box-sizing: inherit;
          margin: 0;
          padding: 0;
        }
        
        body {
          position: relative;
          font-size: 1rem;
          line-height: 1;
          height: 100%;
          width: 100%;
          overflow-x: hidden;
          overflow-y: auto;
          -webkit-font-smoothing: antialiased;
          background: #222;
          color: #fc2;
        }
        
        button {
          font: inherit;
          line-height: 1.5;
          padding: 1px 3px;
          border-radius: 8px;
          border: 1px solid #0ec;
          margin: 20px;
          background: rgba(0, 0, 0, .4);
          color: #0FF;
        }
      </style>
    </head>
    
    <body>
      <h1>dX Audio Array Player</h1>
      <section id="arrayBox">
        <button id="btn1">Load</button>
      </section>
      <script>
    //This array of strings is a required input needed to run dXPlayer.
     
        var playList = ['http://glpjt.s3.amazonaws.com/so/av/day01.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day02.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day03.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day04.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day05.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day06.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day07.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day08.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day09.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day10.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day11.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day12.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day13.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day14.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day15.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day16.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day17.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day18.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day19.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day20.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day21.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day22.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day23.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day24.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day25.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day26.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day27.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day28.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day29.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day30.mp3', 'http://glpjt.s3.amazonaws.com/so/av/day31.mp3'];
        
    //qty is the total quantity of elements within the playList array.
    
        var qty = playList.length;
        console.log('qty: ' + qty);
      </script>
      <script>
        var btn1 = document.getElementById('btn1');
    //Click event triggers a callback: loadPlayers()
    
        btn1.addEventListener('click', loadPlayers, false);
    
        function loadPlayers() {
          var tgtArea = document.getElementById('arrayBox');
          var dArray = [];
    //Each iteration creates a div#dx{?}.snd, appends it to the section, and then is pushed into dArray.
    
          for (var d = 0; d < qty; d++) {
            var division = document.createElement('div');
            division.id = "dx" + d;
            division.className = 'snd';
            tgtArea.appendChild(division);
            dArray.push(division);
          }
    //Each iteration creates an audio element audio#x{?}, adds a series of attributes, and is assigned a MP3 from thr playlist.     
          
          for (var x = 0; x < qty; x++) {
            var ID = dArray[x].getAttribute('id');
            var xTag = document.createElement('audio');
            var xDiv = document.getElementById(ID);
            var xID = ID.substr(1, 3);
            var xUrl = playList[x];
    
            xDiv.appendChild(xTag);
            xTag.setAttribute('id', xID);
            xTag.setAttribute('controls', 'controls');
            xTag.setAttribute('preload', 'auto')
            xTag.setAttribute('src', xUrl);
          }
        }
      </script>
    </body>
    
    </html>



    OP 的代码中有太多需要调试的内容,因此我提供了一个可以实现与 OP 相同目标的工作演示。该演示包括:

    • 两个事件监听器...
      • DOM Content被加载​​时(JS几乎相当于jQuery的DOM Ready),并且...
      • 另一个按钮 (btn1) 点击。
    • 两个函数...
      • btn1 上的点击事件被触发时,loadPlayers() 被调用。
        • 它在 NodeList 中收集 div.snd...
        • ... 依次转换为数组...
        • ...由for 循环迭代。
        • 循环的每个实例都会产生一个加载了独特内容的独特音频元素。
      • xStruct 是在 loadPlayers() 中调用的函数,用于进行克隆、添加属性和分配内容。

    在准备这样的项目时,我更喜欢让我的所有资产都近在咫尺且易于访问。 - 确保音频文件都在一个目录(文件夹)中。 - 使用连续编号的短功能文件名。 (例如wav1.wav、`wav2.wav 等..) - 以类似的方式分配 ID。 - 如果您使用分散在多个位置的内容、冗长冗长的名称以及不易遵循模式的类和 ID,您将更容易出错。

    在设置此演示时需要遵守几件事:

    • 对于您要创建的每个播放器,您必须在 HTML 中已有一个 div:

      • id 应相同,但编号除外。
      • 您还必须将类 .snd 分配给每个 div。
    • 以与 div id 相同的方式命名每个文件。

    Plunker

    片段

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <title>35529918</title>
      <style>
        section {
          margin: 30px
        }
      </style>
    </head>
    
    <body>
      <button id="btn1">Load</button>
      <section>
        <div id="wav1" class="snd"></div>
        <div id="wav2" class="snd"></div>
        <div id="wav3" class="snd"></div>
      </section>
      <script>
        window.addEventListener('DOMContentLoaded', function(e) {
    
          var btn1 = document.getElementById('btn1');
    
          btn1.addEventListener('click', loadPlayers, false)
    
          function loadPlayers() {
            var divList = document.querySelectorAll('.snd');
            var divArray = Array.prototype.slice.call(divList);
            for (var i = 0; i < divArray.length; i++) {
              var ID = divArray[i].id;
              xStruct(ID);
            }
          }
    
          function xStruct(ID) {
            var xTag = document.createElement('audio');
            var xDiv = document.getElementById(ID);
            var xUrl = 'https://glpjt.s3.amazonaws.com/so/av/';
            var xWav = xUrl + ID + '.wav';
            var xID = ID.substr(1, 3);
            xDiv.appendChild(xTag);
            xTag.setAttribute('id', xID);
            xTag.setAttribute('controls', 'controls');
            xTag.setAttribute('src', xWav);
          }
        }, false);
      </script>
    </body>
    
    </html>

    【讨论】:

    • 感谢 zer00ne!你给了我很多思考和改进的东西。然而,这并不能完全解决核心问题。我需要在阵列中有灵活数量的音频播放器。如果数组有 5 个元素 - 应该有 5 个玩家,这无法提前确定!原因是我提示用户在输入中输入单词。当在数据库中找到单词时,它会获取数组中元素的数量,这应该是灵活的......
    • 不客气,先生。用户输入?这样更容易写。用户输入了什么?歌名?媒体是否来自一个来源/网址/位置?只要您的音频文件每个不超过 10MB,就不会放慢速度,但如果您确实打算播放更大的文件,最好在页面上运行一个播放器。
    • 嗯,我已经写过了。我没有将这部分(输入)添加到这个问题中,因为我只想处理播放器问题,你看到了吗?为了简单起见,我只写了一个伪数组。源是一个 .mp3 路径(现在在硬盘上),所以我只使用来自网络的随机 URL 来进行可视化。您写道“对于您想要创建的每个玩家,您必须已经有一个 div”。但怎么会?难道不能在一个固定的div中迭代和添加一个播放器吗?
    • 是的,我担心渲染时间,但似乎我的担心是没有根据的,所以回顾一下,您希望数组长度不受限制,src 来自输入,并且所有内容都是动态生成的。跨度>
    • 是的!假设您输入“Birds”作为输入,您将得到 ["Sparrow, Blackbird", Dove"] 以及它们在左侧的声音(3 种不同的声音),如果您输入“Dogs”,您将得到 ["Collie, "梗犬"] (2)。但是同样,您不必修改输入代码,就像我所拥有的那样,只需展示如何根据数组的长度创建 X 数量的玩家 - 就足够了!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多