【问题标题】:Javascript to stop playing sound when another startsJavascript在另一个启动时停止播放声音
【发布时间】:2017-10-16 14:39:48
【问题描述】:

所以,在编码方面,我是一个完全的业余爱好者,但我仍然喜欢摆弄它。 我目前正在开发基于 html/jS/PHP 的音板,但我不知道如何在按下按钮播放另一个音板时停止播放声音。

<script type="text/javascript" charset="utf-8">
        $(function() {
            $("audio").removeAttr("controls").each(function(i, audioElement) {
                var audio = $(this);
                var that = this; //closure to keep reference to current audio tag
                $("#doc").append($('<button>'+audio.attr("title")+'</button>').click(function() {
                    that.play();
                }));
            });
        });
    </script>

我希望有人能理解这一点。提前致谢。 还有一个 PHP 代码可以自动从文件夹中获取音频文件到前端,对于这个问题可能是不必要的信息。

【问题讨论】:

  • 您考虑过使用Web Audio API吗?
  • @le_m 不,我没有,因为我真的不知道任何编码语言的基础知识,我只是碰巧发现这个几乎完整的一个已经集成了 PHP fetcher。如果有人要为我提供适合我需要的不同类型的播放器,我当然会改变它。

标签: javascript


【解决方案1】:

您可以做的是,在开始播放新音频之前暂停页面上所有可用的音频。像这样。

var audioOne = document.querySelector('#audio-1');
var audioTwo = document.querySelector('#audio-2');

var allAudios = document.querySelectorAll('audio');

function stopAllAudio(){
	allAudios.forEach(function(audio){
		audio.pause();
	});
}

document.querySelector('#play-1').addEventListener('click', function(){
	stopAllAudio();
	audioOne.play();
})
document.querySelector('#play-2').addEventListener('click', function(){
	stopAllAudio();
	audioTwo.play();
})
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<audio id="audio-1"
  src="http://developer.mozilla.org/@api/deki/files/2926/=AudioTest_(1).ogg">
</audio>
<audio id="audio-2"
  src="http://www.w3schools.com/html/horse.mp3">
</audio>

	<button id="play-1">
		play audio 1
	</button>
	<button id="play-2">
		play audio 2
	</button>	
</body>
</html>

您可以使用HTMLAudioElement,而不是使用&lt;audio&gt; 标签添加音频。

【讨论】:

    【解决方案2】:

    如果您使用引入了HTMLAudioElement 的 HTML5,这并不难做到。

    这是您尝试执行的最少代码:

    // Let's create a soundboard module ("sb")
    var sb = {
      song: null,
      init: function () {
        sb.song = new Audio();
        sb.listeners();
      },
      listeners: function () {
        $("button").click(sb.play);
      },
      play: function (e) {
        sb.song.src = e.target.value;
        sb.song.play();
      }
    };
    
    $(document).ready(sb.init);
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Audio</title>
    </head>
    <body>
      <button value="https://www.gnu.org/music/FreeSWSong.ogg">Song #1</button>
      <button value="https://www.gnu.org/music/free-software-song-herzog.ogg">Song #2</button>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    </body>
    </html>

    您也可以考虑像 howler.js 这样的库来帮助您进行开发过程。

    【讨论】:

    • 谢谢!这对我来说效果很好。不得不稍微调整一下 PHP 代码,但至少这对我来说很容易。
    【解决方案3】:

    您可以通过暂停stop and reset an audio element 并将其当前时间设置为0。每当单击按钮时,您都需要执行此操作。示例:

    // Available sounds:
    const sounds = {
      "Bottle": "http://freewavesamples.com/files/Bottle.wav",
      "Bamboo": "http://freewavesamples.com/files/Bamboo.wav"
    }
    
    // Load audio elements:
    let audios = {};
    for (let [title, url] of Object.entries(sounds)) {
        audios[title] = new Audio(url);
    }
    
    // Create board buttons:
    let board = document.getElementById("board");
    for (let title of Object.keys(audios)) {
      let button = document.createElement("button");
      button.textContent = title;
      button.dataset["audio"] = title;
      board.appendChild(button);
    }
    
    // Handle board button clicks:
    board.addEventListener("click", function(event) {
      let audio = audios[event.target.dataset["audio"]];
      if (audio) {
        // Pause and reset all audio elements:
        for (let audio of Object.values(audios)) {
          audio.pause();
          audio.currentTime = 0;
        }
        // Play this audio element:
        audio.play();
      }
    });
    &lt;div id="board"&gt;&lt;/div&gt;

    如果您想充分利用 Web Audio API 的全部功能,您可能会开始构建类似这样的音板:

    // Load buffer from 'url' calling 'cb' on complete:
    function loadBuffer(url, cb) {
      var request = new XMLHttpRequest();
      request.open('GET', url);
      request.responseType = 'arraybuffer';
      request.onload = () => context.decodeAudioData(request.response, cb);
      request.send();
    }
    
    // Available sounds:
    const sounds = {
      "Bottle": "url/to/bottle.wav",
      "Bamboo": "url/to/bamboo.wav"
    };
    
    let audioCtx = new (AudioContext || webkitAudioContext)(),
        board = document.getElementById("soundboard"),
        buffers = {},
        source;
    
    // Load buffers:
    for (let [title, url] of Object.entries(sounds)) {
      loadBuffer(url, buffer => buffers[title] = buffer);
    }
    
    // Create board buttons:
    for (let title of Object.keys(sounds)) {
      let button = document.createElement("button");
      button.textContent = title;
      button.dataset["buffer"] = title;
      board.appendChild(button);
    }
    
    // Handle board button clicks:
    board.addEventListener("click", function(event) {
      let buffer = buffers[event.target.dataset["buffer"]];
      if (buffer) {
        if (source) source.stop();
        source = audioCtx.createBufferSource();
        source.buffer = buffer;
        source.connect(audioCtx.destination);
        source.start();
      }
    });
    &lt;div id="soundboard"&gt;&lt;/div&gt;

    请注意,上面给出的声音 URL 必须位于同一域中或在同一源策略下可用(请参阅 CORS 标头)。

    【讨论】:

      【解决方案4】:

      以下代码可能对其他人有所帮助:

      var audioMap = new Map();
      var rappers = document.querySelectorAll('.rapper');
      rappers.forEach(function(rapper){
          audioMap.set(rapper, new Audio());
          rapper.addEventListener('click', function(){
              var audio = new Audio($(this).data('audio'));
              audio.play();
              audioMap.set(this, audio);
              var current = audioMap.get(this);
              // console.log('get', current);
              audioMap.forEach(function(audio){
                  if( audio != current ){
                      audio.pause();
                      audio.currentTime = 0;
                  }
              });
          });
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-15
        • 1970-01-01
        • 2014-05-20
        • 1970-01-01
        相关资源
        最近更新 更多