Search code examples
javascripthtmlaudio-playerhtml-input

How to make remaining time NOT show duration?


This is my website. if you know how to make md dropdowns pls tell me, but here it is.

//this is a long but working workaround javascript being horrible at decimals. BTW stackoverflow, if i put this in a question, FU. you made me add 99 lines of code to a simple site.
math = (type, parameters)=>{
  var tops = []
  switch(type){
    case "+":
      parameters.forEach((parameter)=>{
        if(typeof parameter !== "number"){
          throw "this isnt algebra, not even value "+index;
        }
        if((parameter.toString().split(".").length) > 1){
          tops.push(parameter.toString().split(".")[1].length);
        }else{
          tops.push(0);
        }
      });
      tops.sort(function(a, b){return b-a});
      parameters = parameters.map((parameter)=>{
        return parameter*(10**tops[0]);
      });
      var result = 0;
      parameters.forEach((parameter)=>{
        result += parameter;
      });
      return result/(10**tops[0]);
      break;
    case "-":
      parameters.forEach((parameter, index)=>{
        if(typeof parameter !== "number"){
          throw "this isnt algebra, not even value "+index;
        }
        if((parameter.toString().split(".").length) > 1){
          tops.push(parameter.toString().split(".")[1].length);
        }else{
          tops.push(0);
        }
      });
      tops.sort(function(a, b){return b-a});
      parameters = parameters.map((parameter)=>{
        return parameter*(10**tops[0]);
      });
      var result = 0;
      parameters.forEach((parameter, index)=>{
        if(index === 0){
          result+= parameter;
        }else{
          result-=parameter;
        }
      });
      return result/(10**tops[0]);
      break;
    case "*":
      parameters.forEach((parameter)=>{
        if(typeof parameter !== "number"){
          throw "this isnt algebra, not even value "+index;
        }
        if((parameter.toString().split(".").length) > 1){
          tops.push(parameter.toString().split(".")[1].length);
        }else{
          tops.push(0);
        }
      });
      tops.sort(function(a, b){return b-a});
      parameters = parameters.map((parameter)=>{
        return parameter*(10**tops[0]);
      });
      var result = 1;
      parameters.forEach((parameter)=>{
        result *= parameter;
      });
      return result/(10**tops[0]);
      break;
    case "/":
      parameters.forEach((parameter)=>{
        if(typeof parameter !== "number"){
          throw "this isnt algebra, not even value "+index;
        }
        if((parameter.toString().split(".").length) > 1){
          tops.push(parameter.toString().split(".")[1].length);
        }else{
          tops.push(0);
        }
      });
      tops.sort(function(a, b){return b-a});
      parameters = parameters.map((parameter)=>{
        return parameter*(10**tops[0]);
      });
      var result = 0;
      parameters.forEach((parameter, index)=>{
        if(index === 0){
          result+= parameter;
        }else{
          result/=parameter;
        }
      });
      return result/(10**tops[0]);
      break;
  }
}















pp = document.querySelector("#pp");
fi = document.createElement("input");
fi.type = "file";
bt = document.querySelector("#bt");
tt = document.querySelector("#tt");
cr = document.querySelector("#cr");
ts = document.querySelector("#ts");
tj = document.querySelector("#tj");
au = new Audio();
ly = document.querySelector("#ly");
sl = document.querySelector("#sl");
cr.addEventListener("click", ()=>{
  try{
    clearInterval(iv);
  }catch(USLISERROOR){}
  fl = null;
  au.pause();
  au = new Audio();
  pp.innerText = "▶️";
  ts.value = null;
  tj.hidden = true;
  tt.value = null;
  sl.value = null;
  sl.disabled = true;
  sl.readonly = false;
  sl.placeholder = "nothing is playing";
  ly.disabled = true;
  ly.value = "edt";
});
cr.click();
pp.addEventListener("click", ()=>{
  if(fl !== null){
    if(au.paused){
      au.play();
      pp.innerText = "⏸️";
      iv = setInterval(()=>{
        ts.value = au.currentTime;
        tj.value = au.currentTime;
        tt.value = math("-", [au.duration, au.currentTime]);
      }, 1);
    }else{
      au.pause();
      pp.innerText = "▶️";
      clearInterval(iv);
    }
  }else{
    bt.innerText = "waiting for input..."
    fi.click();
    fi.addEventListener("input", ()=>{
      fl = fi.files[0];
      bt.innerText = "checking file type...";
      if(fl.type.startsWith("audio/")){
        bt.innerText = "reading file...";
        rd = new FileReader();
        rd.readAsBinaryString(fl);
        rd.addEventListener("loadend", ()=>{
          au.src = "data:"+fl.type+";base64,"+btoa(rd.result);
          bt.innerText = "reconstructing audio ..."
          ts.value = 0;
          tj.hidden = false;
          tj.value = 0;
          sl.disabled = false;
          ly.disabled = false;
          sl.placeholder = "input lyrics";
          au.addEventListener("canplaythrough", ()=>{
            bt.innerText = "";
            tj.max = au.duration;   //Math.trunc(au.duration)+1;
            tt.value = au.duration;
          })
        });
      }else{
        bt.innerText = "please input audio only.";
        fl = null;
      }
    });
  }
});
imput = ()=>{
  ts.value = tj.value;
  tt.value = math("-", [au.duration, JSON.parse(tj.value)]);
}
tj.addEventListener("mousedown", ()=>{
  paused = au.paused;
  au.pause();
  pp.innerText = "️↔️";
  try{
    clearInterval(iv);
  }catch(USLISERROOR){}
  tj.addEventListener("input", imput);
});
tj.addEventListener("mouseup", ()=>{
  tj.removeEventListener("input", imput);
  au.currentTime = JSON.parse(tj.value);
  if(!paused){
    au.play();
    iv = setInterval(()=>{
      ts.value = au.currentTime;
      tj.value = au.currentTime;
      tt.value = math("-", [au.duration, au.currentTime]);
    }, 1);
    pp.innerText = "⏸️"
  }else{
    pp.innerText = "️▶️";
    ts.value = au.currentTime;
    tt.value = math("-", [au.duration, au.currentTime]);
  }
});
au.addEventListener("ended", ()=>{
  pp.innerText = "🔁";
  clearInterval(iv);
});

ly.addEventListener("input", ()=>{
  switch(ly.value){
    case "edt":
      sl.disabled = false;
      sl.placeholder = "input lyrics";
      break;
    case "dmo":
      sl.style.color = "#000000"
      sl.disabled = true;
      sl.placeholder = "lyrics at pause";
  }
});
lyrics = [];
times = [];
sl.addEventListener("keyup", (event)=>{
  if (event.key === "Enter"){
    lyrics.push({
      ts: ts.value,
      lyrics: sl.value
    });
    times.push(ts.value);
    times.sort((a, b)=>{return a-b});
    sl.value = null;
  }
});
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Pley Myoozik</title>
    <script src="script.js" defer></script>
  </head>   
  <body style="font-family: arial;">
    <div style="position: absolute; top: 1%; left: 1%; width: 49%; height: 100%;">
      Audio control
      <br>
      <button id="pp" style="font-size: 200%; padding-top: 3px; padding-bottom: 7px; padding-left: 5px; padding-right: 5px;">▶️</button>
      <div id="bt"></div>
      <input type="number" readonly placeholder="nothing is playing" id="ts" style="width: 97%;">
      <input type="range" id="tj" min="0" max="0" step="0.000001" hidden style="width: 97%;">
      <input type="number" readonly placeholder="nothing is playing" id="tt" style="width: 97%;">
      <br>
      <button id="cr">clear file</button>
    </div>
    <div style="position: absolute; top: 1%; right: 1%; width: 49%; height: 100%;">
      <select id="ly" disabled>
        <option value="edt">LyricEdit'r</option>
        <option value="dmo">LyricDemo'r</option>
      </select>
      <br>
      <input type="text" placeholder="nothing is playing" id="sl" disabled style="position: absolute; bottom: 3%; width: 100%; font-size: 200%;">
    </div>
  </body>
</html>

its purpose is to play music from a file.

to use it, press the play button and upload a file.

the problem I'm looking to solve is that #tj(range input)'s mouseup event is making #tt(bottom number input)show the duration of the audio, not the leftover time. The issue is gone after pressing the play button(you have to have this paused in order to remake the problem), but returns after adjusting tj again.(still, audio must be paused to see)

according to the debugger (not going to lie, i had no idea how it works, but i think i do?), this happened in line 206, but it makes no sense....

how can i fix this, and why is this happening?

its been nearly two days, havent made one edit on my public site.... im bumping. sorry. dont upvote unless you plan to answer


Solution

  • Setting currentTime on the audio file causes the system to start buffering data from that location.

    When it has buffered enough to play (which happens pretty dang fast), it triggers the canplaythrough event.

    You have an event handler on that event, that always sets tt to the duration. You need to subtract the currentTime in that handler and not assume it only happens when currentTime is zero.

    au.addEventListener("canplaythrough", ()=>{
                bt.innerText = "";
                tj.max = au.duration;   
                tt.value = math("-", [au.duration, au.currentTime]);
              })