Можете ли вы помочь мне написать новую функцию для подсчета количества сыгранных циклов? - PullRequest
0 голосов
/ 30 апреля 2020

Этот код работает отлично (мне это нравится), но мне нужно добавить другую функцию, чтобы подсчитать, сколько раз был выполнен l oop или сколько раз воспроизводился звук. Вы можете помочь мне? Спасибо.

<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>```

Ответы [ 2 ]

0 голосов
/ 01 мая 2020

Хитрость заключается в том, чтобы увеличить счетчик в течение последних 0,25 с c продолжительности файла MP3 во время воспроизведения. Вам необходимо:

  • Зарегистрировать событие "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 голосов
/ 30 апреля 2020

Для этого вы можете использовать события аудиоэлемента. В приведенном ниже примере я связался с некоторым файлом stati c .mp3 и добавил обработчик события «onseeking», в котором подсчитывается количество пусков / резюме. Я специально использовал «onseeking», потому что это событие вызывается при запуске операции поиска и охватывает случай воспроизведения l oop.

Подробнее о событиях здесь

<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>
...