Почему играет два и более источника одновременно аудио плеере?

Пытаюсь подключить визуализацию к плееру jplayer, но почему-то создается отдельно audio и не привязывается к основному плееру.

$(function() {
    var _randomPlay = false;
    var _autoPlayNextPage = true;
    var el_jplayer = $('#jspplayer');
    var _track_id = 0;
    $("[data-player]").live('click', function() {
        $("[data-player]").not(this).removeClass('stop');
        el_jplayer.jPlayer("destroy");
        $('#set_track_title').html('Выберите трек');
        $('.jp-duration, .jp-current-time').html('00:00');
        var el = $(this);
        var el_track = el;
        var _track_title = el.attr('data-title');
        _track_id = el.attr('data-idn');
        var file_mp3 = el.attr("data-player");
        var _get_volume = $('.jp-volume-bar-value1').attr('data-volume');
        el_jplayer.jPlayer({
            ready: function() {
                $(this).jPlayer("setMedia", {
                    mp3: file_mp3
                }).jPlayer("play");
            },
            swfPath: "/player",
            supplied: "mp3",
            wmode: "window",
            volume: _get_volume,
            volumechange: function(event) {
                var myVol = event.jPlayer.options.volume,
                    myMuted = event.jPlayer.options.muted;
                $('.jp-volume-bar-value1').attr('data-volume', myVol);
            },
            cssSelectorAncestor: '',
            cssSelector: {
                volumeBar: '.jp-volume-bar1',
                volumeBarValue: '.jp-volume-bar-value1',
                seekBar: 'wave',
                playBar: 'wave>wave',
                play: ".jp-play",
                pause: ".jp-pause",
                stop: ".jp-stop",
                currentTime: ".jp-current-time",
                duration: ".jp-duration",
            }
        });
        el_jplayer.jPlayer("play");
        el.addClass('stop');
        el_jplayer.bind($.jPlayer.event.ended + ".repeat", function() {
            el.removeClass('stop');
            el.parents('li').removeClass('current');
        });
        $('#set_track_title').html(_track_title);

    
// НАЧАЛО ВИЗУАЛИЗАЦИИ
    if (! window.AudioContext) {
        if (! window.webkitAudioContext) {
            alert('no audiocontext found');
        }
        window.AudioContext = window.webkitAudioContext;
    }
    var context = new AudioContext();
    var audioBuffer;
    var sourceNode;
    var analyser;
    var javascriptNode;
    var ctx = $("#canvas").get()[0].getContext("2d");
    var gradient = ctx.createLinearGradient(0,0,0,300);
    gradient.addColorStop(1,'#000000');
    gradient.addColorStop(0.75,'#ff0000');
    gradient.addColorStop(0.25,'#ffff00');
    gradient.addColorStop(0,'#ffffff');
    setupAudioNodes();
    loadSound(file_mp3);
    function setupAudioNodes() {
        javascriptNode = context.createScriptProcessor(2048, 1, 1);
        javascriptNode.connect(context.destination);
        analyser = context.createAnalyser();
        analyser.smoothingTimeConstant = 0.3;
        analyser.fftSize = 512;
        sourceNode = context.createBufferSource();
        sourceNode.connect(analyser);
        analyser.connect(javascriptNode);
        sourceNode.connect(context.destination);
    }
    function loadSound(url) {
        var request = new XMLHttpRequest();
        request.open('GET', url, true);
        request.responseType = 'arraybuffer';
        request.onload = function() {
            context.decodeAudioData(request.response, function(buffer) {
                playSound(buffer);
            }, onError);
        }
        request.send();
    }
    function playSound(buffer) {
        sourceNode.buffer = buffer;
        sourceNode.start(0);
    }
    function onError(e) {
        console.log(e);
    }
    javascriptNode.onaudioprocess = function() {
        var array =  new Uint8Array(analyser.frequencyBinCount);
        analyser.getByteFrequencyData(array);
        ctx.clearRect(0, 0, 1000, 325);
        ctx.fillStyle=gradient;
        drawSpectrum(array);
    }
    function drawSpectrum(array) {
        for ( var i = 0; i < (array.length); i++ ){
            var value = array[i];
            ctx.fillRect(i*5,325-value,3,325);
        }
    };
// КОНЕЦ ВИЗУАЛИЗАЦИИ      
    

        return false;
    });
  

    

  

  
  

    
    
    $('[data-player]').click(function() {
        $('.jp-image').html('<a rel="ajaxlink" href="/' + $(this).data('url') + '"><img class="z-depth-1" src="' + $(this).data('image') + '" alt="' + $(this).data('title') + '"></a>');
        $('.jp-qr').html('<img src="' + $(this).data('qr') + '" alt="' + $(this).data('title') + '">');
        $('#waveform').html('');
        var wavesurfer = WaveSurfer.create({
            container: document.querySelector('#waveform'),
            waveColor: '#565f77',
            progressColor: '#1871C0',
            barWidth: 2,
            cursorWidth: 0,
            height: 50,
            barGap: 1,
            mediaType: 'audio',
            normalize: true,
            pixelRatio: 1,
            removeMediaElementOnDestroy: false,
            plugins: [
                WaveSurfer.cursor.create({
                    showTime: true,
                    opacity: 1,
                    color: '#1871C0',
                    customShowTimeStyle: {
                        'background-color': '#1871C0',
                        'color': '#fff',
                        'padding': '2px 5px',
                        'font-size': '11px',
                        'border-radius': '0 3px 3px 0',
                        'opacity': '0.9'
                    }
                })          
            ]
        });
        wavesurfer.load($(this).data('player'));
        
    


    
        });
  }); 
    
canvas {
    width: 100%;
}


.player-panel {
    background: #fff linear-gradient(to bottom, rgba(0, 0, 0, 0) 50%, rgba(0, 39, 59, 0.15) 100%);
    bottom: 0;
    box-shadow: 0 -3px 0 0 #565f77;
    height: 70px;
    line-height: 1.3;
    position: fixed;
    transition: all 0.3s ease-in-out 0s;
    width: 100%;
    z-index: 999;
    left: 0;
}
#waveform {
    position: relative;
    height: 50px;
}
.horizontal-images.content ul, .vertical-images.content ul {
    list-style: outside none none;
    margin: 0;
    overflow: hidden;
    padding: 3px 0 0;
}
.horizontal-images.content li {
    float: left;
    margin: 0 3px;
}
.jp-image, .jp-qr {
    float: left;
    height: 70px;
    position: relative;
    width: 70px;
}
.jp-image img, .jp-qr img {
    height: 70px;
    width: 70px;
    font-size: 0;
}
.jp-play {
    cursor: pointer;
    float: left;
    height: 70px;
    padding: 22px 0 0;
    position: relative;
    text-align: center;
    width: 90px;
    border-right: 1px solid rgb(220,220,220);
}
.jp-pause {
    cursor: pointer;
    display: none;
    float: left;
    height: 70px;
    padding: 22px 0 0;
    position: relative;
    text-align: center;
    width: 90px;
    border-right: 1px solid rgb(220,220,220);
}
     

.jp-volume-controls {
    float: right;
    height: 70px;
    margin-left: 0; /* -110px */
    transition: all 0.3s ease-in-out 0s;
    padding: 0 20px;
    border-left: 1px solid rgb(220,220,220);
}
.jp-volume-controls:hover {
    margin-left: 0;
}
.jp-volume-controls span {
    line-height: 0;
}
.jp-volume-controls button {
    background: transparent;
    border: medium none;
    color: #777;
    cursor: pointer;
    padding: 10px 5px 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.jp-volume-controls button i {
    font-size: 28px;
}
.jp-volume-controls:hover {
    box-shadow: 0 0 0 #aaa, 0 0 1px #aaa inset;
}
.jp-mute, .jp-volume-max {
    float: left;
}
.jp-volume-bar1 {
    background: #808080;
    cursor: pointer;
    float: left;
    height: 5px;
    margin: 22px 0 0;
    overflow: hidden;
    width: 50px;
}
.jp-volume-bar-value1 {
    background: #FF0000;
    height: 5px;
    width: 0;
}
.v_p_title {
    height: 24px;
    overflow: hidden;
    padding: 4px 0 0 20px;
    position: relative;
    float: left;
    font-size: 14px;
}
.v_p_progs {
    height: 70px;
    overflow: hidden;
    position: relative;
}

.jp-current-time, .jp-duration, .jp-slash {
    float: left;
    font-size: 13px;
    font-weight: bold;
    line-height: 1.8;
    padding: 0 0 0 7px;
}

.jp-repeat-toggles, .jp-reads {
    background: #fff linear-gradient(to bottom, rgba(0, 0, 0, 0) 50%, rgba(0, 39, 59, 0.15) 100%);
    float: right;
    height: 70px;
    width: 100px;
    border-left: 1px solid rgb(220,220,220);
}
.jp-repeat-toggles a {
    transition: all 0.3s ease 0s;
}
.jp-reads {
    color: #777;
    text-align: center;
    transition: all 0.3s ease-in-out 0s;
    display: flex;
    flex-direction: column;
    cursor: help;
}
.jp-reads a {
    color: #777;
    cursor: pointer;
    height: 70px;
    text-align: center;
    transition: all 0.3s ease-in-out 0s;
    width: 100px;
    display: flex;
    flex-direction: column;
}
.jp-reads i {
    font-size: 28px;
    padding-top: 10px;
}
.jp-reads:hover, .jp-repeat-toggles a:hover, .jp-reads a:hover {
    background: rgba(0, 0, 0, 0) radial-gradient(ellipse at center center , rgba(255, 255, 255, 1) 40%, rgba(0, 0, 0, 0.2) 100%) repeat scroll 0 0;
    box-shadow: 0 0 0 #aaa, 0 0 1px #aaa inset;
}

.jp-repeat {
    color: #777;
    height: 70px;
    padding-top: 10px;
    position: absolute;
    text-align: center;
    width: 100px;
    display: flex;
    flex-direction: column;
}
.jp-repeat-off {
    background: rgba(0, 0, 0, 0) radial-gradient(ellipse at center center , rgba(255, 255, 255, 1) 40%, rgba(0, 0, 0, 0.2) 100%) repeat scroll 0 0;
    color: #777;
    height: 70px;
    padding-top: 10px;
    position: absolute;
    text-align: center;
    width: 100px;
    box-shadow: 0 0 0 #aaa, 0 0 1px #aaa inset;
    display: flex;
    flex-direction: column;
}            
.jp-repeat i, .jp-repeat-off i {
    font-size: 28px;
}
#lightSwitch span, .jp-reads span, .jp-repeat span, .jp-repeat-off span, .jp-volume-controls button span, .jp-volume-controls span {
    display: block;
    text-align: center;
}
.jp-wave {
    position: absolute;
    width: 100%;
    height: 50px;
    margin-top: -2px;
}
.jp-wave > img {
    height: 50px;
    opacity: 0.6;
    width: 100%;
}
.jp-seek-bar1:not(:hover) .thumb {
  display: none;
}
.thumb {
    background-color: #fff !important;
    position: absolute;
    pointer-events: none;
    top: 0;
    width: 1px;
    opacity: 0;
}
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/material-design-icons/3.0.2/iconfont/material-icons.min.css">
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://jplayer.org/latest/dist/jplayer/jquery.jplayer.min.js"></script>
<script src="https://unpkg.com/wavesurfer.js/dist/wavesurfer.js"></script>
<script src="https://unpkg.com/wavesurfer.js/dist/plugin/wavesurfer.cursor.js"></script>


<a href="#" 
   class="play" 
   id="Player001" 
   data-player="https://geo-samples.beatsource.com/0/d/7/0d7b19b7-06d3-4833-8d0d-213920b7bbca.LOFI.mp3" 
   data-title="Heuse, Woolley - Dont Hold Me Down" 
   data-qr="https://chart.googleapis.com/chart?cht=qr&chl=heuse-woolley-dont-hold-me-down.mp3&chs=113x113&choe=UTF-8&chld=L|0" 
   data-id="001" 
   data-idn="play001" 
   data-image="https://geo-media.beatsource.com/image_size/500x500/f/9/5/f9566075-8128-44c6-8061-22341d8fca4f.jpg">
  play001
</a>
<hr>
<a href="#" 
   class="play" 
   id="Player002" 
   data-player="https://geo-samples.beatsource.com/7/9/e/79eb724e-3f11-428e-8535-8bcfa7ee4498.LOFI.mp3" 
   data-qr="https://chart.googleapis.com/chart?cht=qr&chl=heuse-woolley-dont-hold-me-down.mp3&chs=113x113&choe=UTF-8&chld=L|0" 
   data-title="Holotrope - Microbe" 
   data-id="002" 
   data-idn="play002" 
   data-image="https://geo-media.beatsource.com/image_size/500x500/c/4/b/c4b40d66-514d-4437-8f35-4dc42c945a6e.jpg">
  play002
</a>

<canvas id="canvas" width="1000" height="325" style="display: block;"></canvas>


<div id="player-panel" class="player-panel"> 
<div class="jp-image "><img src="https://b-tm.com.ua/assets/galleries/105/noimage.png" alt="logo"></div>
<a href="#"><div class="jp-qr"><img src="https://b-tm.com.ua/assets/galleries/105/noimage.png" alt="qr-код"></div></a>

<div class="jp-play"><i class="material-icons">play_circle_outline</i></div>
<div class="jp-pause"><i class="material-icons">replay</i></div>
<div class="jp-volume-controls">
   <button tabindex="0" role="button" class="jp-mute"><i class="material-icons">volume_down</i></button>
   <div class="jp-volume-bar1">
       <div class="jp-volume-bar-value1" style="width: 80%;"></div>
   </div>
   <button tabindex="0" role="button" class="jp-volume-max"><i class="material-icons">volume_up</i></button>
<span>Громкость</span>    
</div>

<div class="v_p_progs">
  <div id="waveform"></div>
    <div class="jp-current-time">00:00</div>
    <div class="jp-slash">/</div>
    <div class="jp-duration">00:00</div>
    <div class="v_p_title" id="set_track_title"></div>
</div>
<div id="jspplayer"></div>
</div>


Ответы (1 шт):

Автор решения: Опан

В предыдущем ответе Вы сказали, что использование createMediaElementSource(audio) - это не привязка. А вот createBufferSource() + XMLHttpRequest() - это якобы совсем другое дело. Но суть похожая, только чуть сложнее. И если уже пошли по такому пути, то при каждом переходе по другой ссылке нужно удалять предыдущий window.AudioContext(), т. к , если каждый раз созаётся новый, но потом его не удалять, то напросно нагромождается оперативная память.

Играет два и более источника одновременно аудио плеере из-за того, что в коде не нужна строка

sourceNode.connect(context.destination);

внутри функции setupAudioNodes(). Она паралельно с wavesurfer, который и так уже воспроизводит трек, второй раз включает звук проигрывания трека и к тому же он не выключается в случае перехода по другой ссылке. Вы хоть обратили внимание на двоичную накладку звука? Так что просто уберите эту строку.

→ Ссылка