Home  >  Q&A  >  body text

javascript - Question about audio tag pausing

<audio src="res/bg.mp3" id="m1" controls loop></audio>
    <input type="checkbox" id="bgm"/>:是否播放背景音乐
    <script>

        bgm.onchange=function(){
            if(this.checked){
                m1.volume=0;
                m1.play();
                var timer=setInterval(function(){
                    m1.volume+=0.1;
                    if(m1.volume>0.9){
                        clearInterval(timer);
                    }
                },200);
            }else{
                var timer=setInterval(function(){
                    if(m1.volume>0){
                        m1.volume-=0.1;
                    }else{
                        clearInterval(timer);
                        m1.pause();
                    }
                },200);
            }
        }
    </script>

The code is as above. I want to make a small function of clicking the checkbox to realize the fade-in and fade-out of background music. The fade-in can be realized, but when fading out, I want it to automatically pause when the volume reaches 0. But after my volume changed to 0, the progress bar was still running and m1.pause() did not take effect. .

I really don’t understand, I’m new to front-end, please give me some guidance π-π

迷茫迷茫2678 days ago950

reply all(3)I'll reply

  • 巴扎黑

    巴扎黑2017-06-20 10:09:02

    This question is quite interesting, and the logic of the code is correct.

    The first thing you need to understand is: the calculation of floating point numbers in js is not accurate, for example: 0.2 + 0.1The result is 0.30000000000000004.

    The direct reason is the error: Failed to set the 'volume' property on 'HTMLMediaElement': The volume provided (-1.77636e-16) is outside the range [0, 1].This is saying that volume can only be in Assign a value within the interval [0, 1].

    When fading in, add 0.1 each time, and the actual volume value printed is:

    Volume decreases by 0.1 each time. The actual decrease will produce a very, very small number in the end, but it is still greater than 0:

    So m1.volume-=0.1 will still be executed, causing the volume to be set to a negative number and the above error will be reported.

    The solution has already been given by a classmate. You can also pay attention to ES6 Number.EPSILON, which is specially used to solve calculation accuracy problems.

    reply
    0
  • 扔个三星炸死你

    扔个三星炸死你2017-06-20 10:09:02

    The problem lies in the value of volume. In the HTML5 specification, the value of volume cannot be less than 0, but the calculation in your code makes the value of volume less than 0, so the script will not be executed due to an error. It is recommended to change it to

    if(m1.volume>0.1){
        m1.volume-=0.1;
    }else{
        clearInterval(timer);
        m1.pause();
    }

    This is the error record:
    Failed to set the 'volume' property on 'HTMLMediaElement': The volume provided (1.1) is outside the range [0, 1]
    In addition, the code failed the continuous click test and the sound did not reach the maximum If you click the checkbox again, a bug will appear.

    reply
    0
  • 天蓬老师

    天蓬老师2017-06-20 10:09:02

    Change it to this:

       var timer = null;
        bgm.onchange=function(){
            if(this.checked){
                m1.volume=0;
                m1.play();
                clearInterval(timer);
                timer=setInterval(function(){
                    m1.volume+=0.1;
                    if(m1.volume>0.9){
                        clearInterval(timer);
                    }
                },200);
            }else{
                clearInterval(timer);
                timer=setInterval(function(){
                    console.log(m1.volume)
                    if(m1.volume>0){
                        // m1.volume -= 0.1;这里会有精度问题,一直减0.1不是到从1到0
                        m1.volume = m1.volume-0.1<=0?0:m1.volume-0.1;
                    }else{
                        m1.pause();
                        clearInterval(timer);
                    }
                },200);
            }
        }`
        

    reply
    0
  • Cancelreply