JavaScript audio.pause() and audio.play() not working in audio visualizer

时间:2018-07-25 04:50:48

标签: javascript audio

I have an audio visualizer to which I'm attempting to add controls. Unfortunately, the problem cannot be easily replicated in a snippet because a special server must be setup to allow frequency access to the audio. However, I'll describe the problem the best I can.

All JavaScript for the project is below. I haven't tried skip functions yet but play/pause doesn't work.

This block handles all the play/pause.

function updatePlayState(){
            //console.log(paused)
            console.log(audio.paused)
            //audio.play();
            audio.pause();
            console.log(audio.paused)
            /*if(!paused){
                paused = true;
                audio.pause();
                console.log(audio.src)
            }else{
                audio.play();
            }*/
        }

When I click the button, the console logs false and then true. However, it continues the same behavior after additional clicks. The audio also doesn't pause. The audio object I'm using is global so scope must not be the issue. I'm just wanting to get the audio to pause and then I'll move on to additional functionality.

//initialize global variables...
    var audio, canvas, ctx, audioCtx, source, analyser, playlist_index = 0, full_screen = false, paused = false;
    var playlist = [
        //'http://localhost/audio-visualizer/audio/audio.mp3',
        'http://localhost/audio-visualizer/audio/HaxPigMeow.mp3',
        'http://localhost/audio-visualizer/audio/4ware.mp3',
        'http://localhost/audio-visualizer/audio/Narwhals_song.mp3'
    ];

    //when the page loads...
    window.addEventListener('load', function() {
        //initialize the canvas...
        initializeCanvas();
        //initialize audio...
        initializeAudio();
        //initialize audio analyzer (get frequency information)...
        initializeAudioAnalyser();
        //initialize audio controls...
        initializeAudioControls();
    });

    //when the window is resized...
    window.addEventListener('resize', function() {
      resizeCanvas();
    });

    function initializeCanvas() {
      //get the canvas...
      canvas = document.getElementById('canvas');
      //create a canvas context to draw graphics...
      ctx = canvas.getContext('2d');
      //resize the canvas to fit the window...
      resizeCanvas();
    }

    function resizeCanvas() {
      //set height of canvas...
      canvas.width = window.innerWidth;
      //set width of canvas...
      canvas.height = window.innerHeight;
      //set width of context...
      ctx.width = window.innerWidth;
      //set height of context...
      ctx.height = window.innerHeight;
      //reset drawing properties...
      setCanvasDrawingProperties();
    }

    function initializeAudio() {
      //load the audio...
      audio = new Audio(playlist[playlist_index]);
      //bypass CORS (Cross Origin Resource Sharing) restrictions...
      audio.crossOrigin = 'anonymous';
      //when the audio finishes playing; replay...
      //audio.loop = true;
      //play automatically...
      //audio.autoplay = true;
      //wait until audio fully loads before playing...
      audio.oncanplaythrough = function() {
        setTimeout(function() {
            window.addEventListener('click',function(e){
            audio.play();
                //request full screen access...
                if(e.target.tagName != 'INPUT'){
                    var root_element = document.documentElement;
                    rfs = root_element.requestFullscreen
                        || root_element.webkitRequestFullScreen
                        || root_element.mozRequestFullScreen
                        || root_element.msRequestFullscreen 
                    ;

                    rfs.call(root_element);
                }
                //show audio controls....
                document.getElementById('controlContainer').style.display = 'block';
                setTimeout(function(){
                    document.getElementById('controlContainer').style.opacity = '1';
                },500);
                //hide the loading message...
                document.getElementById('overlayLoadingMessage').style.opacity = '0';
                window.setTimeout(function() {
                    document.getElementById('overlayLoadingMessage').style.display = 'none';
                }, 500);
            });
        }, 1000);
      };

      audio.addEventListener('ended',function(){
        skipForward();
        playlist_index++;
        if(playlist_index == playlist.length){
            playlist_index = 0;
        }
        audio.src = playlist[playlist_index];
        audio.crossOrigin = 'anonymous';
        audio.play();
      })
    }

    function initializeAudioControls(){
        document.getElementById('skipBack').addEventListener('click',skipTrackBackward);
        document.getElementById('skipForward').addEventListener('click',skipTrackForward);
        document.getElementById('pause').addEventListener('click',updatePlayState);

        function skipTrackForward(){
            console.log('skip forward')
        }

        function skipTrackBackward(){
            console.log('skip backward')
        }

        function updatePlayState(){
            //console.log(paused)
            console.log(audio.paused)
            //audio.play();
            audio.pause();
            console.log(audio.paused)
            /*if(!paused){
                paused = true;
                audio.pause();
                console.log(audio.src)
            }else{
                audio.play();
            }*/
        }
    }

    function initializeAudioAnalyser() {

      //create an audio context for browsers (including older webkit)...
    if(window.webkitAudioContext){
      //an older browser which needs to use the webkit audio constructor...
      audioCtx = new window.webkitAudioContext;
    }else{
      //a newer browser which has full support for the audio context...
      audioCtx = new window.AudioContext;
    }

      //create a new analyser...
      analyser = audioCtx.createAnalyser();
      //create new media source for the audio context...
      source = audioCtx.createMediaElementSource(audio);
      //connect the analyser to the source...
      source.connect(analyser);
      //connect audio output device information to the analyser to gather audio frequencies...
      analyser.connect(audioCtx.destination);
      //set drawing properties...
      setCanvasDrawingProperties();
      //let's do this thing (time to animate)...
      animate();
    }

    function setCanvasDrawingProperties() {
      //set background color of future drawing...
      ctx.fillStyle = '#fff';
      //blur radius (50px)...
      ctx.shadowBlur = 50;
      //shadow color...
      ctx.shadowColor = "#ddd";
    }

    function animate() {
      //clear canvas...
      ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);

      //create new frequency array map...
      frequencyBinaryCountArray = new Uint8Array(analyser.frequencyBinCount);

      //input frequency data into the array map...
      analyser.getByteFrequencyData(frequencyBinaryCountArray);

      //calculate radius based on frequency information (uses channel 50 right now)..
      var r = frequencyBinaryCountArray[50];
      //set x of circle...
      var x = (window.innerWidth / 2);
      //set y of circle...
      var y = (window.innerHeight / 2);
      //set start angle (the circumference of the circle)...
      var startAngle = 2 * Math.PI;
      //set end angle (the end circumference of the circle)...
      var endAngle = 0 * Math.PI;

      //draw a circle; radius is based on frequency...

      //begin the drawing...
      ctx.beginPath();
      //draw the circle...
      ctx.arc(x, y, r, startAngle, endAngle);
      //fill the circle with a color...
      ctx.fill();
      //close the path...
      ctx.closePath();

      //do it again (appx 60 times per second)...
      requestAnimationFrame(animate);
    }

Tested in Chrome 67.x (latest version as of this post) on macOS High Sierra.

1 个答案:

答案 0 :(得分:0)

I was stuck on it a while but, immediately after posting the question, I discovered the global click listener that starts playing the audio was also firing when I clicked the pause button. It was overriding the pause function. To fix it, I moved the audio play inside the e.target tagname exception. However, to prevent future confusion, I added a button to start the visualization rather than a global click event.

Thanks for looking.