Richienb / audic

Play some audio.
MIT License
68 stars 9 forks source link

audio.currentTime is always rounded #27

Open Ponali opened 4 months ago

Ponali commented 4 months ago

when trying to get an audio's current time, the result is always rounded - this is bad for me since i want to seek the audio current time. another thing is that using audio.currentTime+=1; does nothing and only seeks to the rounded current position.

Suppenterrine commented 4 months ago

I also have a question regarding the currentTime. I'm trying to set the currentTime to a random number and want it to start playing from there. Here is the code I'm using:

import Audic from 'audic';
import mm from 'music-metadata';

/**
 * 
 * @param {*} filePath 
 * @returns duration of the audio file in seconds
 */
async function getMetadata(filePath) {
  try {
    const metadata = await mm.parseFile(filePath);
    return metadata.format.duration
  } catch (error) {
    console.error('Error:', error);
  }
}

const path = 'audio_files/sam.mp3';
const audio = new Audic(path);
console.log("initiated");

const totalDuration = await getMetadata(path);
// random start time between 0 and last 5 seconds of file
const randomStart = parseInt(Math.random() * (totalDuration - 5));
console.log("start", randomStart);

// set playtime to the calculated time
audio.currentTime = randomStart;
await audio.play();

setTimeout(() => {
  audio.destroy();
  console.log("finished playing 2 seconds from", randomStart, "seconds");
}, 2000);

This doesn't work. It plays the audio every time from the beginning. Am I doing something wrong? Is there a way to do this?

Greetings~

eedefeed commented 4 months ago

@Ponali I think audic is being limited by VLC's API here; looks like only integer seconds are supported.

@Suppenterrine I'm also having some struggles using audic and having the same problems with starting times as you. I THINK the issue is as follows: 1) when you do audio.currentTime, audic tries to send a command to VLC. It looks to me, and I could be wrong, that VLC doesn't actually respond with any success/failure status regarding whether the command was successful or not. 2) If VLC doesn't have a track 'fully loaded' (as I'm going to call it), seek will fail because it has no track on which to seek. 3) I think audic issues the command to seek before it issues the command to play. Because the track isn't 'fully loaded', the seek doesn't do anything.

I have tried first issuing audic.play() then issuingaudic.currentTime() one line later, but I think there's some async stuff going on that means that the track still isn't fully loaded by the time audic issues the play command to VLC.

To solve this, I've also tried using audic.addEventListener('canplay', myFunction) to see if it detects when VLC has a track loaded, but this event never seems to get triggered for me.

So instead I'm using the "playing" event to detect when audio is playing, as follows:

   start(fullTrackPath, startTime = 10) {

        this.track  = new Audic(fullTrackPath);

        this.track.addEventListener("playing", () => {
            if(startTime) {
                this.track.currentTime = startTime;
            }
        });

        this.track.play();
    }

I didn't want to use the 'playing' event, since I don't know whether I'll ever hear a few milliseconds of the start of the track before it then seeks. If that becomes an issue for me, I'm going to try immediately pausing the track after playing, then playing it again during the 'playing' event, which will still be triggered.

Debugging this has been a bit of a pain. When you are coding events, try adding try/catch blocks to all the code in your events: audic seems to silence errors generated in these functions.