Reputation: 3
I'm trying to create a volume slider for the audiojs audio player. I've successfully created the slider and bound it to the audio player, but my problem is it only works with the first instance of the player. I think it requires some sort of loop to find all instances of the audio player, but I'm having trouble writing the loop.
The javascript running in my head tag is:
audiojs.events.ready(function() {
var as = audiojs.createAll();
$('.slider').each(function() {
var slider = $('.slider'),
tooltip = $('.tooltip'),
audioList = document.getElementsByTagName("audio").length;
tooltip.hide();
slider.slider({
range: "min",
min: 0,
max: 100,
value: 50,
change: function(){
var value = $(".slider").slider("value");
for (var i = 0; i > audioList; i++) {
document.getElementById("player").volume = (value / 100);
};
},
start:function(event,ui) {
tooltip.fadeIn('fast');
},
slide: function(event, ui) {
var volume = $('.volume'),
value = $(".slider").slider("value");
document.getElementById("player").volume = (value / 100);
tooltip.css('left',value / 2).text(ui.value);
if(value <= 5) {
volume.css('background-position', '0 0');
}
else if (value <= 25) {
volume.css('background-position', '0 -25px');
}
else if (value <= 75) {
volume.css('background-position', '0 -50px');
}
else {
volume.css('background-position', '0 -75px');
};
},
stop:function(event,ui) {
tooltip.fadeOut('fast');
},
});
});
});
I need a solution that's compatible across all modern browsers. I have the full files in github here.
Upvotes: 0
Views: 1037
Reputation: 30893
I couldn't use your audio.min.js
but used a hosted version for my working example from https://cdnjs.cloudflare.com/ajax/libs/audiojs/1.0.1/audio.js
I also could not use your images in my working example. So I hope this is easy for you to adapt to your personal code.
Working Example: https://jsfiddle.net/Twisty/qx4Lzu9d/4/
HTML
<div id="audio">
<div class="audio-item">
<span class="podcast-type">Audio Summary</span>
<br />
<p><strong>Defining the Optimal Interval for Colonoscopic Screening in Individuals with a Family History of Colorectal Cancer</strong>
<br />
<em>By Matthew B. Yurgelun</em></p>
<audio id="player_1" src="https://traffic.libsyn.com/jcopodcast/Yurgelun.mp3" preload="auto"></audio><div id="vol_1" class="volume-button" data-level="50" data-min="0" data-max="100" data-player-id="1">Volume</div>
<span class="podcast-type">November 2, 2015</span>
<p><strong>Related Article:</strong> <a class="related" href="https://jco.ascopubs.org/content/early/2015/10/26/JCO.2015.62.2035" target="blank">Hennick et al</a></p>
</div>
<hr />
<div class="audio-item">
<span class="podcast-type">Art of Oncology</span>
<br />
<p><strong>The Emerging Role of Gallium-68 Somatostatin-Receptor PET Imaging in Neuroendocrine Tumors</strong>
<br />
<em>By Jonathan R. Strosberg</em></p>
<audio id="player_2" src="https://traffic.libsyn.com/jcopodcast/Strosberg.mp3" preload="auto"></audio><div id="vol_2" class="volume-button" data-player-id="2">Volume</div>
<span class="podcast-type">Decenber 28, 2015</span>
<p><strong>Related Article:</strong> <a class="related" href="https://jco.ascopubs.org/content/early/2015/12/24/JCO.2015.64.0987" target="blank">Sadowski et al</a></p>
</div>
</div>
Here you can see I have added a div
to create a Volume button for each player. I have also addressed the id
issue. Thus each player has a unique ID and a volume button that associates with it.
CSS
.audio-item .audiojs {
display: inline-block;
}
.section {
position: relative;
}
.volume-button {
height: 36px;
margin: 0;
margin-top: -28px;
}
.slide-wrapper {
background: #fff;
position: absolute;
width: 28px;
height: 120px;
border: 1px solid #333;
border-radius: 6px;
z-index: 100;
}
.slider {
position: absolute;
top: 12px;
left: 6px;
}
Minor modifications just for this example.
jQuery
audiojs.events.ready(function() {
var as = audiojs.createAll();
});
$(function() {
$(".volume-button").button({
"icon": "ui-icon-volume-on",
"showLabel": false
}).click(function() {
if ($(".slide-wrapper").length) {
$(".slide-wrapper").remove();
return false;
}
var slideWrap = $("<div>", {
class: "slide-wrapper"
});
var vslide = $("<div>", {
class: "slider"
});
var pid = $(this).data("player-id");
var player = $("#player_" + pid)[0];
var lev = player.volume ? player.volume * 100 : 50;
console.log("Creating Volume Slider for #player_" + pid);
vslide.css("height", "100px");
vslide.slider({
orientation: "vertical",
range: "min",
min: 0,
max: 100,
value: lev,
slide: function(e, ui) {
console.log("Setting #player_" + pid + " volume to " +
ui.value);
player.volume = ui.value / 100;
},
stop: function(e, ui) {
slideWrap.remove();
}
});
slideWrap.append(vslide);
$(this).after(slideWrap);
slideWrap.position({
my: "left bottom",
at: "right bottom",
of: "#vol_" + pid
});
});
});
First I separated the loading of the jQuery UI items from the AudioJS. Since we want to be able to make use of the audio
attributes, it seemed best to let them load first before creating UI elements.
Assuming the page may contain 1 or more audio
elements that we want to create a volume button for, I create a broad initialization and use a class selector. These refer back to the button's data-player-id
attribute to know which player to control. Also each volume slider is created on the fly and will read the current volume
attribute from the player it is associated with.
Conditionally, we remove any existing wrappers and their sliders when the button is clicked.
Create a wrapper div
, optional, to use with the slider. Can be helpful for positioning and styling.
Create a slider div
, get the player ID, and the current volume level. Then initialize the UI Slider. I picked a vertical orientation for fun. Since the volume
attribute needs to be between 0 and 1, I set the min and max to 0 and 100 and the value to audio.volume * 100
. This will ensure we get proper representation on the slider.
On slide
, we adjust the value and pass it to the audio
element: audio.volume = ui.value / 100;
On stop
, we remove the slider.
It will be appended after the volume button and positioned.
Upvotes: 0