Home > Enterprise >  How to trigger a function which is inside another function
How to trigger a function which is inside another function

Time:10-08

I have function running every second (for clock) .
I wanted to add sound to every tick tick....(second) but as function is running automatic (means no triggering is taking place) and when sound added produces an error

Error showing is :
Uncaught DOMException: play() failed because the user didn't interact with the document first.

Know that it is not possible to play audio automatic .

So tried to create a start sound btn which play the audio but as second time (of clock) and don't match with audio . So there is a mismatch

I am trying to add that function(audio play) inside second(clock time) calculator .
Is this possible or not

Link to similar question but not able to find the solution

The code is as follows

setInterval(clockRunner, 1000);

function clockRunner() {
  //Clock code goes here
  function trigger() {
    var audioElement = document.getElementById('audiotag1');
    audioElement.play();
  }
}
<audio id="audiotag1" src="https://soundbible.com/mp3/Tick-DeepFrozenApps-397275646.mp3" preload="metadata" controls></audio>
<button onclick="trigger()">Start</button>

Update

Added event listener inside the outer function but this way sound is playing once not every second .

One solution here can be adding another setInterval but this will again create problem of playing sound at different timing of clock's second

Also it shows the same error in the console(mentioned above) until user clicks the btn

setInterval(clockRunner, 1000);

function clockRunner() {
  //Clock code goes here

document.getElementById('demo').innerHTML = new Date();
  setInterval(trigger, 1000);
  document.getElementById("triggerSnd").addEventListener('click', trigger)

  function trigger() {
    var audioElement = document.getElementById('audiotag1');
    audioElement.play();
  }
}
<audio id="audiotag1" src="https://soundbible.com/mp3/Tick-DeepFrozenApps-397275646.mp3" preload="metadata" controls></audio>
<button id="triggerSnd">Start</button>
<div id="demo"></div>

Thanks for help in advance

CodePudding user response:

I've changed my answer completely. Now I didn't need to use an event listener, just the proper API of HTMLMediaElement that audio uses. Note that I've add loop attribute to tick's audio.

var blast = document.getElementById("blast");
var tick = document.getElementById("tick");

var tickDuration, timeDiff, lastTime


tick.onloadedmetadata = () => tickDuration = tick.duration


timeDiff = 0.3 // max difference between sync, dont lower it or it will bug (can explain if u want)
lastTime = 0

blast.addEventListener("timeupdate", () => {
    let bct = blast.currentTime
  let tct = tick.currentTime
  let syncBlastTime = tickDuration - (tickDuration - bct%tickDuration)
  let diff = Math.abs(syncBlastTime - tct)
  lastTime = bct
  
  console.log(`Blast: ${bct} Tick: ${tct}\nSynced time difference (seconds): ${diff.toFixed(6)}`)
  if(diff > timeDiff) { // add this or it will bug the tick audio
        tick.currentTime = syncBlastTime
   }  
})

blast.addEventListener("pause", () => {
   tick.pause()
})

blast.addEventListener("playing", () => {
   tick.play()
})
<audio id="blast" src="http://stream.arrowcaz.nl/caz64kmp3" controls="loop"></audio>
<audio id="tick" src="https://soundbible.com/mp3/A-Z_Vocalized-Mike_Koenig-197996831.mp3" loop controls='loop'></audio>
<br />

CodePudding user response:

If you make use of some variables, you can control your code to perform like a clock. It's worth noting that there are two possibilities, either the clock has started or it has stopped.

The interval will run when you clicked to start and it will be cleared in stopping it. Here I can't notice any mismatch between the sound and the timer.

var start = document.getElementById("triggerSnd")
var audioElement = document.getElementById('audiotag1')
var demo = document.getElementById('demo')
var interval, isMuted = true

// The second argument of addEventListener should be a function
// that receives an argument 'event'

clockRunner();
clock(); // call firstly
setInterval(() => clock(), 1000)
    
start.addEventListener('click', clockRunner)

function clock(isMuted){
  //Clock code goes here
  demo.innerText = new Date();
  audioElement.play();
}

function clockRunner() {
    audioElement.muted = isMuted
    start.innerText = isMuted ? "Start" : "Stop"
    isMuted = !isMuted
}
<audio id="audiotag1" src="https://soundbible.com/mp3/Tick-DeepFrozenApps-397275646.mp3" preload="metadata"></audio>
<button id="triggerSnd">Start</button>
<div id="demo"></div>

  • Related