HTML5 introduces built-in media support with the audio tag, which makes it very easy to embed media straight into any HTML document with limited code. It comes with built in browser controls, if you specify and plays audio nice and effectively.
This is typically what it will look like in your browser.
You might be thinking: “Well what if I wanted to style my own audio player with it’s own buttons and scroll bar?”
With the audio element, the progress element and a few buttons, you can build your own audio player in no time! The progress element is mainly used to track the completion of a task and can be manipulated easily with Javascript. In our case, it would be to keep track of the length of a song. And the great thing is, HTML5 and browser capabilities make it easy to grab song lengths, current time and more.
If you’d like to play with the code, go for it! Unfortunately Codepen embeds aren't working for me so the link is below.
And below is the code. Note that their are two separate functions. One that keeps track of the audio player actually playing audio (initPlayers function) and the other that is keeping track of the audio for the progress element (initProgressBar function). I tried to keep jQuery to a minimum but used it to actually call the function, sorry, i’m not sorry JS purists.
<div class="audio-player"> | |
<div id="play-btn"></div> | |
<div class="audio-wrapper" id="player-container" href="javascript:;"> | |
<audio id="player" ontimeupdate="initProgressBar()"> | |
<source src="https://dl-web.dropbox.com/get/Oslo.mp3?_subject_uid=199049471&w=AABuDNt9BDJnaZOelVFws9FXTufkXCvAPS5SYpy_gRZ2GQ&duc_id=dropbox_duc_id" type="audio/mp3"> | |
</audio> | |
</div> | |
<div class="player-controls scrubber"> | |
<p>Oslo <small>by</small> Holy Esque</p> | |
<span id="seek-obj-container"> | |
<progress id="seek-obj" value="0" max="1"></progress> | |
</span> | |
<small style="float: left; position: relative; left: 15px;" id="start-time"></small> | |
<small style="float: right; position: relative; right: 20px;" id="end-time"></small> | |
</div> | |
<div class="album-image" style="background-image: url(https://img.discogs.com/smajEDf4MJk3Le7gG9oi-cke6e4=/fit-in/600x598/filters:strip_icc():format(jpeg):mode_rgb():quality(90)/discogs-images/R-7859768-1452996483-9325.jpeg.jpg)"></div> | |
</div> |
function initProgressBar() { | |
var player = document.getElementById('player'); | |
var length = player.duration | |
var current_time = player.currentTime; | |
// calculate total length of value | |
var totalLength = calculateTotalValue(length) | |
document.getElementById("end-time").innerHTML = totalLength; | |
// calculate current value time | |
var currentTime = calculateCurrentValue(current_time); | |
document.getElementById("start-time").innerHTML = currentTime; | |
var progressbar = document.getElementById('seek-obj'); | |
progressbar.value = (player.currentTime / player.duration); | |
progressbar.addEventListener("click", seek); | |
if (player.currentTime == player.duration) { | |
document.getElementById('play-btn').className = ""; | |
} | |
function seek(event) { | |
var percent = event.offsetX / this.offsetWidth; | |
player.currentTime = percent * player.duration; | |
progressbar.value = percent / 100; | |
} | |
}; | |
function initPlayers(num) { | |
// pass num in if there are multiple audio players e.g 'player' + i | |
for (var i = 0; i < num; i++) { | |
(function() { | |
// Variables | |
// ---------------------------------------------------------- | |
// audio embed object | |
var playerContainer = document.getElementById('player-container'), | |
player = document.getElementById('player'), | |
isPlaying = false, | |
playBtn = document.getElementById('play-btn'); | |
// Controls Listeners | |
// ---------------------------------------------------------- | |
if (playBtn != null) { | |
playBtn.addEventListener('click', function() { | |
togglePlay() | |
}); | |
} | |
// Controls & Sounds Methods | |
// ---------------------------------------------------------- | |
function togglePlay() { | |
if (player.paused === false) { | |
player.pause(); | |
isPlaying = false; | |
document.getElementById('play-btn').className = ""; | |
} else { | |
player.play(); | |
document.getElementById('play-btn').className = "pause"; | |
isPlaying = true; | |
} | |
} | |
}()); | |
} | |
} | |
function calculateTotalValue(length) { | |
var minutes = Math.floor(length / 60), | |
seconds_int = length - minutes * 60, | |
seconds_str = seconds_int.toString(), | |
seconds = seconds_str.substr(0, 2), | |
time = minutes + ':' + seconds | |
return time; | |
} | |
function calculateCurrentValue(currentTime) { | |
var current_hour = parseInt(currentTime / 3600) % 24, | |
current_minute = parseInt(currentTime / 60) % 60, | |
current_seconds_long = currentTime % 60, | |
current_seconds = current_seconds_long.toFixed(), | |
current_time = (current_minute < 10 ? "0" + current_minute : current_minute) + ":" + (current_seconds < 10 ? "0" + current_seconds : current_seconds); | |
return current_time; | |
} | |
initPlayers(jQuery('#player-container').length); |
.audio-player { | |
border: 1px solid lighten(#acacac, 20%); | |
text-align: center; | |
display: flex; | |
flex-flow: row; | |
margin: 4rem 0 4rem 0; | |
width: 600px; | |
.album-image { | |
min-height: 100px; | |
width: 100px; | |
background-size: cover; | |
} | |
.player-controls { | |
align-items: center; | |
justify-content: center; | |
margin-top: 2.5rem; | |
flex: 3; | |
progress { | |
width: 90%; | |
} | |
progress[value] { | |
-webkit-appearance: none; | |
appearance: none; | |
background-color: white; | |
color: blue; | |
height: 5px; | |
} | |
progress[value]::-webkit-progress-bar { | |
background-color: white; | |
border-radius: 2px; | |
border: 1px solid lighten(#acacac, 20%); | |
color: blue; | |
} | |
progress::-webkit-progress-value { | |
background-color: blue; | |
} | |
p { | |
font-size: 1.6rem; | |
} | |
} | |
#play-btn { | |
background-image: url('http://imgur.com/JzQP8td.png'); | |
background-size: cover; | |
width: 75px; | |
height: 75px; | |
margin: 2rem 0 2rem 2rem; | |
&.pause { | |
background-image: url('http://imgur.com/MbJn41l.png'); | |
} | |
} | |
} |
If you have any questions or suggestions, i’m all ears! Email me at luke.will.duncan@gmail.com or hit me up on twitter @luke__duncan
Top comments (1)
can we implement seek functionality ourselves ?