Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sound.currentTime Needed #140

Open
Mr-Ahmadi opened this issue Jun 25, 2020 · 7 comments
Open

sound.currentTime Needed #140

Mr-Ahmadi opened this issue Jun 25, 2020 · 7 comments

Comments

@Mr-Ahmadi
Copy link

Thank you for your cool library.

Is there any way for getting the currentTime of sound and change it?

Something like audio.currentTime = 5;?

@garthholmes
Copy link

I believe you can start the sound from a certain point, but I don't believe you can have something like an interactive song position that is changeable at any time, typical with modern video and audio players on the web.

Of course anything is better than nothing.

@Mr-Ahmadi
Copy link
Author

@Nascent ow can we do that?

@kyoukhana
Copy link

Yea we need this. But even better would be awesome to get the current play back time for each individual sound object within a group object

@Mr-Ahmadi
Copy link
Author

might be possible with a little mathematics...

@1hko
Copy link

1hko commented Jan 19, 2023

I also ran into this issue using Pizzicato. Here's the basic moving pieces I used to solve the issue:

const state = {  // transport state
  type: "stop",  // sound is stopped
  playhead: 0,   // current playhead position
  timeRef: null, // time reference when play was clicked
}

const sound = new Pizzicato.Sound(...)

Now implement your transport controls:

function play() {
  switch (state.type) {
    case "stop":
      state.type = "play"            // change play state
      transport.timeRef = Date.now() // record time reference
      sound.play(0, state.playhead)  // play sound from current playhead
      break
    case "play":
      break                          // sound is already playing
  }
}

function stop() {
  switch (state.type) {
    case "stop":
      break                                             // sound is already stopped
    case "play":
      const delta = (Date.now() - state.timeRef) / 1000 // compute time delta
      state.type = "stop"                               // change play state
      state.playhead = state.playhead + delta           // update playhead
      state.timeRef = null                              // unset time reference
      break
  }
}

Now you can get the playhead position at any time:

requestAnimationFrame(function onFrame() {
  switch (state.type) {
    case "stop":
      console.log("playhead", state.playhead)         // render
      break
    case "play":
      const delta = (Date.now() - state.timeRef) / 1000
      console.log("playhead", state.playhead + delta) // render
      break
  }
  requestAnimationFrame(onFrame)
})

@LeonBaudouin
Copy link

Hacky way to get current time, works with paused tracks and doesn't need manual tracking. I didn't test it with stopped or detached tracks tho

const isPaused = !audio.playing;
const lastTimePlayed = audio.lastTimePlayed;
const offsetTime = audio.offsetTime || 0;
const contextTime = audio.sourceNode?.context?.currentTime || 0;
const currentTime = isPaused ? offsetTime : contextTime - lastTimePlayed;

@garthholmes
Copy link

garthholmes commented Nov 26, 2024

I implemented this, albeit with some changes namely the transport keyword, is replaced by state and some other changes:

const secondsToMinSecPadded = time => { const minutes = ${Math.floor(time / 60)}.padStart(1, "0"); const seconds = ${time - minutes * 60}.padStart(2, "0"); return ${minutes}:${seconds}`;
};

const state={type:"stop",playhead:0,timeRef:0}

const playbuttonhandler=function(){
switch (state.type) {
case "stop":
state.type = "play"
state.timeRef = Date.now()
drums.play(0, state.playhead);machine.play();percussion.play();drumsynth.play();basses.play();guitars.play();keyboards.play();orchestra.play();vocals.play();metronome.play();
break
case "play":
break
}
}

const pausebuttonhandler=function(){
switch (state.type) {
case "stop":
break
case "play":
const delta = (Date.now() - state.timeRef) / 1000
state.type = "stop"
state.playhead = state.playhead + delta
state.timeRef = null
drums.pause();machine.pause();percussion.pause();drumsynth.pause();basses.pause();guitars.pause();keyboards.pause();orchestra.pause();vocals.pause();metronome.pause();
break
}
}

const stopbuttonhandler=function(){
switch (state.type) {
case "stop":
break
case "play":
const delta = (Date.now() - state.timeRef) / 1000
state.type = "stop"
state.playhead=0;
attentionfirstspan.textContent=Math.floor(state.playhead / 60) + ":" + (state.playhead % 60 ? state.playhead % 60 : '00');
attentionlastspan.textContent=Math.floor(state.playhead / 60) + ":" + (state.playhead % 60 ? state.playhead % 60 : '00');
state.timeRef = null
drums.stop();machine.stop();percussion.stop();drumsynth.stop();basses.stop();guitars.stop();keyboards.stop();orchestra.stop();vocals.stop();metronome.stop();
break
}
}

requestAnimationFrame(function onFrame() {
switch (state.type) {
case "play":
const delta = (Date.now() - state.timeRef) / 1000
attentionfirstspan.textContent=secondsToMinSecPadded(Math.round(state.playhead + delta));
attentionlastspan.textContent=secondsToMinSecPadded(Math.round(state.playhead + delta));
break
}
requestAnimationFrame(onFrame)
})`

I really love this library and it is still solid after many years. I am about to replace all .mp3 files with .flac and see how they load but one thing I think Pizzicato.js needs, is a way to be able to click on a timeline and navigate to a particular section of a song since people are so used to being able to do that with stereo recordings, for example on the streaming platforms but it may require the original developer to implement unless there are savvy users who can come up with something brilliant, as is this case with the code originally posted in this thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants