Table of Contents
Met onderstaande code kan je op een eenvoudige manier styling geven aan een audio player. Natuurlijk mist deze wat onderdelen ten opzichte van de standaard browser player, maar je hebt hiermee wel meer mogelijkheden voor de styling. Op dit moment werkt dit maar met 1 per pagina (onderstaande kan je gewoon in een Gutenburg block zetten), maar dit zal je vast op een redelijk makkelijke manier variabel kunnen maken.
HTML / PHP #
<?php
global $site_sets;
$audio_url = get_field('audio_url');
?>
<div class="audio-container">
<audio controls>
<source src="<?php echo($audio_url); ?>" type="audio/mp3">
</audio>
<div class="audio-player">
<div class="controls">
<div class="play-container">
<div class="toggle-play play"></div>
</div>
<div class="time">
<div class="current">0:00</div>
<div class="divider">/</div>
<div class="length"></div>
</div>
<div class="timeline">
<div class="progress"></div>
</div>
<div class="volume-container">
<div class="volume-button">
<div class="volume icono-volumeMedium"></div>
</div>
<div class="volume-slider">
<div class="volume-percentage"></div>
</div>
</div>
</div>
</div>
</div>
CSS #
.audio-container {
position: relative;
margin: var(--margin) 0;
audio {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
z-index: -1;
}
}
.audio-player {
width: 50%;
height: 65px;
background-color: var(--brand_primary);
color: #FFFFFF;
overflow: hidden;
display: flex;
align-items: center;
@media(max-width: 991px) {
width: 100%;
}
.timeline {
background-color: #FFFFFF;
width: 100%;
position: relative;
cursor: pointer;
justify-content: flex-start !important;
height: 5px;
.progress {
background: var(--brand_accent);
width: 0%;
height: 100%;
border-radius: 0;
}
}
.controls {
display: flex;
align-items: center;
width: 100%;
>* {
display: flex;
justify-content: center;
align-items: center;
}
.play-container {
flex-shrink: 0;
}
.toggle-play {
width: 65px;
height: 65px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
background: var(--brand_secondary);
transition: 0.2s ease-in-out;
&:before {
transition: 0.2s ease-in-out;
}
&:hover {
background: var(--brand_secondary-dark);
}
&.play {
&:before {
content: '\f04b';
font-size: 1.2rem;
font-family: "Font Awesome 5 Free";
font-weight: 900;
color: #FFFFFF;
}
}
&.pause {
&:before {
content: '\f04c';
font-size: 1.2rem;
font-family: "Font Awesome 5 Free";
font-weight: 900;
color: #FFFFFF;
}
}
}
.time {
display: flex;
padding: 0 20px;
font-size: 0.9rem;
.divider {
margin: 0 5px;
}
}
.volume-container {
flex-shrink: 0;
position: relative;
.volume-button {
width: 65px;
height: 65px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:hover {
.volume:before {
color: var(--brand_secondary-dark) !important;
}
}
}
.volume {
&:before {
transition: 0.2s ease-in-out;
}
&.icono-volumeMedium {
&:before {
content: '\f028';
font-size: 1.2rem;
font-family: "Font Awesome 5 Free";
font-weight: 900;
color: #FFFFFF;
}
}
&.icono-volumeMute {
&:before {
content: '\f6a9';
font-size: 1.2rem;
font-family: "Font Awesome 5 Free";
font-weight: 900;
color: #FFFFFF;
}
}
}
.volume-slider {
display: none;
position: absolute;
top: 0;
left: 0;
z-index: 1;
width: 100px;
height: 15px;
background: red;
transition: .25s;
.volume-percentage {
background: coral;
height: 100%;
width: 75%;
}
}
}
}
}
JS #
function audioPlayer() {
if (jQuery('.audio-container')[0]){
// Do something if class exists
const audioFile = jQuery(".audio-container").find('audio source').attr('src');
const audio = new Audio(
audioFile
);
const audioPlayer = document.querySelector(".audio-player");
console.dir(audio);
audio.addEventListener(
"loadeddata",
() => {
audioPlayer.querySelector(".time .length").textContent = getTimeCodeFromNum(
audio.duration
);
audio.volume = .75;
},
false
);
//click on timeline to skip around
const timeline = audioPlayer.querySelector(".timeline");
timeline.addEventListener("click", e => {
const timelineWidth = window.getComputedStyle(timeline).width;
const timeToSeek = e.offsetX / parseInt(timelineWidth) * audio.duration;
audio.currentTime = timeToSeek;
}, false);
//click volume slider to change volume
const volumeSlider = audioPlayer.querySelector(".controls .volume-slider");
volumeSlider.addEventListener('click', e => {
const sliderWidth = window.getComputedStyle(volumeSlider).width;
const newVolume = e.offsetX / parseInt(sliderWidth);
audio.volume = newVolume;
audioPlayer.querySelector(".controls .volume-percentage").style.width = newVolume * 100 + '%';
}, false)
//check audio percentage and update time accordingly
setInterval(() => {
const progressBar = audioPlayer.querySelector(".progress");
progressBar.style.width = audio.currentTime / audio.duration * 100 + "%";
audioPlayer.querySelector(".time .current").textContent = getTimeCodeFromNum(
audio.currentTime
);
}, 500);
//toggle between playing and pausing on button click
const playBtn = audioPlayer.querySelector(".controls .toggle-play");
playBtn.addEventListener(
"click",
() => {
if (audio.paused) {
playBtn.classList.remove("play");
playBtn.classList.add("pause");
audio.play();
} else {
playBtn.classList.remove("pause");
playBtn.classList.add("play");
audio.pause();
}
},
false
);
audioPlayer.querySelector(".volume-button").addEventListener("click", () => {
const volumeEl = audioPlayer.querySelector(".volume-container .volume");
audio.muted = !audio.muted;
if (audio.muted) {
volumeEl.classList.remove("icono-volumeMedium");
volumeEl.classList.add("icono-volumeMute");
} else {
volumeEl.classList.add("icono-volumeMedium");
volumeEl.classList.remove("icono-volumeMute");
}
});
//turn 128 seconds into 2:08
function getTimeCodeFromNum(num) {
let seconds = parseInt(num);
let minutes = parseInt(seconds / 60);
seconds -= minutes * 60;
const hours = parseInt(minutes / 60);
minutes -= hours * 60;
if (hours === 0) return `${minutes}:${String(seconds % 60).padStart(2, 0)}`;
return `${String(hours).padStart(2, 0)}:${minutes}:${String(
seconds % 60
).padStart(2, 0)}`;
}
}
}