你能帮我编写一个新的函数来计算循环播放的次数吗?

问题描述 投票:0回答:1

这段代码工作得很完美(我喜欢它),但我需要添加另一个函数来计算循环被执行的次数或声音被播放的次数。你能帮助我吗?谢谢。

<html> 
<body> 

<audio id="myAudio" controls>
  <source src="horse.ogg" type="audio/ogg">
  <source src="horse.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio><br>

<button onclick="enableLoop()" type="button">Enable loop</button>
<button onclick="disableLoop()" type="button">Disable loop</button>
<button onclick="checkLoop()" type="button">Check loop status</button>

<script>
var x = document.getElementById("myAudio");

function enableLoop() { 
  x.loop = true;
  x.load();
} 

function disableLoop() { 
  x.loop = false;
  x.load();
} 

function checkLoop() { 
  alert(x.loop);
} 
</script> 

</body> 
</html>```
javascript loops counting
1个回答
0
投票

诀窍是在播放MP3文件持续时间的最后0.25秒内递增一个计数器。你需要

  • 注册 "timeupdate" 事件到 <audio> 标签。

  • 获取MP3文件的持续时间,用 .duration 财产。

  • 监测进展情况与 .currentTime 属性。


演示

注。 详情请见演示

// Reference the <audio> tag
const mp3 = document.querySelector('audio');
// Reference the <form> tag
const ctrl = document.forms.controls;
// Collect all <output> and <button> into a HTML Collection
const ui = ctrl.elements;
// Define an external variable for a counter reference
let loops = 0;

/*
- Utility function to reset counter at a slight delay
*/
const counterReset = () => setTimeout(function() {
  ui.counter.value = '0';
  loops = 0;
}, 100);

/*
- Utility function to stop <audio> when playing
- There were multiple occurances of these 4 statements so
  this was made for the sake of DRY
*/
const stopPlay = () => {
  ui.playback.classList.add('play');
  ui.playback.classList.remove('pause');
  mp3.pause();
  mp3.currentTime = 0;
};

/*
- <audio> registered to the "timeupdate" event which is
  fired when playing at the frequenncy of 4 times a second
- So every 250ms event handler function countLoop is
  called during playback
*/
mp3.ontimeupdate = countLoop;

// <form> is registered to "click" and "reset" events
ctrl.onclick = playLoop;
ctrl.onreset = resetLoop;

// Click handler for <form>
function playLoop(event) {
  const clicked = event.target;
  let cmd = clicked.className;

  switch (cmd) {
    case 'play':
      clicked.classList.remove('play');
      clicked.classList.add('pause');
      mp3.play();
      break;
    case 'pause':
      clicked.classList.add('play');
      clicked.classList.remove('pause');
      mp3.pause();
      break;
    case 'loop':
      clicked.classList.add('once');
      clicked.classList.remove('loop');
      mp3.loop = true;
      stopPlay();
      counterReset();
      break;
    case 'once':
      clicked.classList.add('loop');
      clicked.classList.remove('once');
      mp3.loop = false;
      stopPlay();
      counterReset();
      break;
    default:
      break;
  }
}

// Timeupdate handler for <audio>
function countLoop(event) {

  // Get the time of MP3 file
  let time = this.duration;
  
  /*
  - if [loop] is enabled AND the current time is more or
    equal to the difference of the duration of the MP3
    file and 0.3sec
  - Increment the counter in 0.15sec.
  - This odd delay pattern is to ensure that within the
    last 0.25sec of the MP3 file the counter will
    increment
  */
  if (this.loop && this.currentTime >= time - .3) {
    setTimeout(function() {
      loops++;
      ui.counter.value = loops
    }, 150);
    
  // Otherwise if the MP3 file ends, increment counter
  } else if (this.ended) {
    this.currentTime = 0;
    loops++;
    ui.playback.classList.add('play');
    ui.playback.classList.remove('pause');
  }
  ui.counter.value = loops;
}

// Reset Handler for <form>
function resetLoop(event) {
  stopPlay();
  counterReset();
}
:root,
body {
  font: 400 4vh/1.5 Consolas;
}

output,
button {
  display: inline-block;
  font: inherit;
  font-size: 1rem
}

button {
  padding: 0;
  border: 0;
  font-size: 4rem;
  background: none;
  cursor: pointer;
}

#counter {
  width: 8rem;
  height: 4rem;
  font-size: 4rem;
  text-align: center;
  color: #0078D7;
}

#playback.play::before {
  content: '▶️'
}

#playback.pause::before {
  content: '⏸️'
}

#loopback.once::before {
  content: '🔁'
}

#loopback.loop::before {
  content: '🔂'
}
<audio src='http://www.orangefreesounds.com/wp-content/uploads/2019/09/Horse-trotting-sound.mp3?_=1'></audio>

<form id='controls'>
  <button id='playback' class='play' type='button'></button>
  <button type='reset'>⏹️</button>
  <button id='loopback' class='loop' type='button'></button>
  <output id='counter'>0</output>
</form>

0
投票

你可以使用音频元素的事件来实现这一点。在下面的例子中,我已经链接到一些静态的.mp3文件,并添加了'onseeking'事件处理程序,其中startresume的数量正在被计算。我特别使用了'onseeking',因为当一个寻路操作开始时,这个事件就会被触发,它涵盖了循环播放的情况。

更多关于事件 此处

<html> 
<body> 

<audio id="myAudio" controls>
  <source src="https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio><br>

<button onclick="enableLoop()" type="button">Enable loop</button>
<button onclick="disableLoop()" type="button">Disable loop</button>
<button onclick="checkLoop()" type="button">Check loop status</button>
<button onclick="checkCount()" type="button">Check count</button>
<script>
var x = document.getElementById("myAudio");
var count = 0;
x.onseeking = (event) => {
  count++;
};

function enableLoop() { 
  x.loop = true;
  x.load();
} 

function disableLoop() { 
  x.loop = false;
  x.load();
} 

function checkLoop() { 
  alert(x.loop);
} 

function checkCount() { 
  alert(count);
} 
</script> 

</body> 
</html>
© www.soinside.com 2019 - 2024. All rights reserved.