首页 > 解决方案 > JavaScript audio.pause() 和 audio.play() 在音频可视化器中不起作用

问题描述

我有一个正在尝试添加控件的音频可视化器。不幸的是,这个问题不能轻易地在片段中复制,因为必须设置一个特殊的服务器来允许频率访问音频。但是,我会尽我所能描述这个问题。

该项目的所有JavaScript如下。我还没有尝试过跳过功能,但播放/暂停不起作用。

这个块处理所有的播放/暂停。

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();
            }*/
        }

当我单击按钮时,控制台会记录false,然后true. 但是,在额外点击后它会继续相同的行为。音频也不会暂停。我使用的音频对象是全局的,所以范围一定不是问题。我只是想让音频暂停,然后我将继续使用其他功能。

//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);
    }

在 macOS High Sierra 上的 Chrome 67.x(截至本文的最新版本)中进行了测试。

标签: javascriptaudio

解决方案


我被困了一段时间,但是,在发布问题后,我发现当我点击暂停按钮时,开始播放音频的全局点击监听器也在触发。它覆盖了暂停功能。为了解决这个问题,我将音频播放移到了e.target标记名异常中。但是,为了防止将来出现混淆,我添加了一个按钮来启动可视化,而不是全局单击事件。

感谢您的关注。


推荐阅读