Почему играет два и более источника одновременно аудио плеере?
Пытаюсь подключить визуализацию к плееру 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, который и так уже воспроизводит трек, второй раз включает звук проигрывания трека и к тому же он не выключается в случае перехода по другой ссылке. Вы хоть обратили внимание на двоичную накладку звука? Так что просто уберите эту строку.