1html로 소지의 mp3를 북의 달인화(의사 자동작보)

샘플



drum_masters.0.0301.htm

사용방법



html을 열고 로컬 mp3 등을 선택하면 재생이 시작됩니다.
Level의 수치가 어디에서 마크를 내는지를 나타냅니다.
즉 조용한 곡이라면 이 Level 값을 낮추지 않으면 마크가 나오지 않습니다.
대상 mp3 자체의 게인에 따라 다릅니다.
별도로 200을 넘어도 문제는 없습니다.




결함


  • 2곡 계속해서 플레이를 할 수 없다
    Uncaught (in promise) TypeError: Failed to execute
    해제할 수 없습니다. 다시 로드할 수밖에 없다.
    깨끗함이 없다.
  • 곡 전체의 레벨 피크 검출을 자동으로 하지 않는다
    전체 길이를 n 초로하고 4 분의 n 정도로 평균 피크와 BPM을 계산하면 좋을 것입니다.
  • audio 태그를 2 개 준비하지 않기 때문에 마크가 나오고 북을 두드릴 때까지의 러그가 연출할 수 없다
  • 1분 정도로 연주 정지에 가져가고 싶다.
  • 푸리에 변환의 편입이 아직.  =    의 추가되지 않음
  • 현재 3% 남은 97% 먼 길

  • Ver0.03 소스



    drum_masters.0.03.htm
    <html>
      <head>
        <style>
          .block1{background-color:#ff0000;
            width:26px;
            height:26px;
            left:300px;
            border-style:solid;
            border-width:2px;
            border-radius: 15px 15px 15px 15px;
            border-color:#FFFFFF;
          }
    
          .block2{
            width:30px;
            height:30px;
            left:300px;
            position: absolute;
            border-style:solid;
            border-width:2px;
            border-radius: 15px 15px 15px 15px;
            border-color:#000000;
            box-shadow: 4px 4px 8px -4px #333333;
            -moz-box-shadow: 4px 4px 8px -4px #333333;
            -webkit-box-shadow: 4px 4px 8px -4px #333333;
          }
    
          .box{
            width:300px;
            height:60px;
            position:  relative;
            overflow:hidden;
          }
        </style>
      </head>
    
      <body>
        Level <input type="text" id="int_peak" value="200" size="3"> 200 大=易---------小=難 20<br />
        <input type="file" id="file_slct"><br />
        <audio id="auo" ></audio><br />
        <input type="hidden" id="blk_count" value="0">
        <div class="box" id="box"></div>
    
      </body>
    
      <footer>
        <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>
        <script>
          var str_id = 0
          var int_wait=0
          //****************************
          async function put_red_mark1(){
            var div2 = document.createElement('div');
            div2.classList.add('block2');
            div2.innerHTML="<div class='block1'></div>"
            div2.id="b" + str_id
            box.appendChild(div2);
            $("#b" + str_id).animate({"left": "-=340px"}, 2000,"linear",function(){$(this).remove();});
            str_id=parseInt(blk_count.value)+1
            blk_count.value=str_id
            int_wait=1
            await sleep(200);
            int_wait=0
          }
    
          //****************************
          var wm = new WeakMap();
          var audioSource;
          //********************************************************
          //const file_slct = document.querySelector('#file_slct');
          async function convertAudioFileToDataUrl(file) {
            const reader = new FileReader();
            const loadPromise = new Promise((resolve, reject) => {
              reader.onload = (event) => {
                resolve(event.target.result);
              };
            });
            reader.readAsDataURL(file);
            return loadPromise;
          }
    
    
    
          //*************************************//
          function sleep(m_second) {
              return new Promise(resolve => {
                  setTimeout(() => {
                      resolve()
                  }, m_second)
              })
              console.log("slpx")
          }
    
    
    
    
          //******************************
          file_slct.addEventListener('change', async (event) => {
            var audioctx = new AudioContext();
            const file = file_slct.files[0];
            auo.src = await convertAudioFileToDataUrl(file);
            audioSource = audioctx.createMediaElementSource(auo);
            auo.play()
    
            //timer_intvl=setInterval(timer_handler, 1000 ) ;
    
    
            var processor = audioctx.createScriptProcessor(256,1,1);
            audioSource.connect(processor);
            processor.connect(audioctx.destination);
            audioSource.connect(audioctx.destination);
            var int_peak=0
    
            processor.onaudioprocess = function(e){
    
              if (int_wait==0){
                var amp = e.inputBuffer.getChannelData(0);
                const reducer = (accumulator, currentValue) => accumulator + Math.abs(currentValue);
                int_peak=amp.reduce(reducer) / amp.length * 800
                //document.getElementById('bar').style.width = '' + (int_peak) + 'px';
                if(auo.paused){
                  processor.disconnect();
                  audioSource.disconnect();
                  auo.src='';
                }else{
                  if(int_peak > document.getElementById("int_peak").value){
                    //log出力
                    //console.log(int_peak)
                    put_red_mark1("b" + blk_count.value);
                  }
                }
              }
            };
          })
    
    
    
        </script>
      </footer>
    </html>
    

    좋은 웹페이지 즐겨찾기