A Pen by Sven Neumann on CodePen.
Last active
December 27, 2015 13:33
-
-
Save killroy42/c8b8a77df979cd2e0433 to your computer and use it in GitHub Desktop.
Music player for streaming
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<link href="style.css" rel="stylesheet"> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/1.1.28/howler.min.js"></script> | |
<script src="script.js"></script> | |
<body> | |
<div id="display"> | |
<span id="label">Drop songs here</span> | |
<span id="time"></span> | |
<span id="song"></span> | |
</div> | |
<div id="help" class="display flash"> | |
<p>[Scroll Up/Down]: Volume</p> | |
<p>[m]: Mute/un-mute</p> | |
<p>[s]: Skip to next song</p> | |
<p>[r]: Toggle randomize</p> | |
</div> | |
<div id="info" class="display"></div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var d = document, url = window.URL; | |
var toArray = [].slice.apply.bind([].slice); | |
var KEYCODE_H = 104; | |
var KEYCODE_M = 109; | |
var KEYCODE_P = 112; | |
var KEYCODE_R = 114; | |
var KEYCODE_S = 115; | |
var FADE_TIME = 3000; | |
var currentVolume = 0.1; | |
var randomize = false; | |
function createSound(name, url) { | |
return new Promise(function(resolve, reject) { | |
var sound = new Howl({ | |
urls: [url], | |
format: 'mp3', | |
buffer: true, | |
rate: 1.0, | |
onload: function() { resolve(sound); }, | |
onloaderror: reject, | |
}); | |
sound.name = name; | |
}); | |
} | |
function flashElement(elem) { | |
elem = $(elem); | |
elem.addClass('flash'); | |
setTimeout(function() { | |
elem.removeClass('flash'); | |
}, 500); | |
} | |
function flashMessage(msg) { | |
$('#info').text(msg); | |
flashElement($('#info')); | |
} | |
function setVolume(volume) { | |
volume = Math.max(0, Math.min(1, volume)); | |
var volumeVal = Math.pow(volume, 1.3); | |
flashMessage('vol: '+Math.round(volumeVal*100)+'%'); | |
Howler.volume(volumeVal); | |
} | |
var main = function() { | |
console.clear(); | |
var curSong, nextSong, timerInterval, fadeTimeout, files, soundUrls; | |
var i = -1; | |
function startSong(name, url) { | |
createSound(name, url) | |
.then(function(song) { | |
if(nextSong) nextSong.unload(); | |
nextSong = song; | |
nextSong.startTime = Date.now(); | |
nextSong.play(); | |
nextSong.fade(0, 1, FADE_TIME, function() { | |
if(curSong) curSong.unload(); | |
curSong = nextSong; | |
}); | |
if(curSong) curSong.fade(1, 0, FADE_TIME); | |
var fadeNext = (nextSong._duration*1000)-FADE_TIME; | |
clearTimeout(fadeTimeout); | |
fadeTimeout = setTimeout(startNextSong, fadeNext); | |
}); | |
} | |
function startNextSong() { | |
if(files === undefined || files.length === 0) return; | |
i++; | |
if(i >= files.length) i = 0; | |
if(randomize) { | |
var ii = Math.floor(Math.random() * files.length); | |
startSong(files[ii].name, soundUrls[ii]); | |
} else { | |
startSong(files[i].name, soundUrls[i]); | |
} | |
} | |
function updateSongTimer() { | |
var song = nextSong || curSong; | |
if(song === undefined) return; | |
var progress = Math.round((Date.now()-song.startTime)/1000); | |
var dur = [Math.round(song._duration / 60), Math.round(song._duration % 60)]; | |
var cur = [Math.round(progress / 60), Math.round(progress % 60)]; | |
$('#display #label').text('Now playing '); | |
$('#display #song').text('"'+song.name.replace(/\.mp3$/, '')+'"'); | |
$('#display #time').html( | |
'('+ | |
[cur[0]]+':'+('0'+cur[1]).slice(-2)+' / '+ | |
[dur[0]]+':'+('0'+dur[1]).slice(-2)+ | |
'):' | |
); | |
} | |
setVolume(currentVolume); | |
d.addEventListener('dragenter', cancel); | |
d.addEventListener('dragover', cancel); | |
d.addEventListener('keypress', function(e) { | |
switch(e.keyCode) { | |
case KEYCODE_H: | |
flashElement($('#help')); | |
break; | |
case KEYCODE_M: | |
if(Howler._muted) { | |
flashMessage('unmute'); | |
Howler.unmute(); | |
} else { | |
flashMessage('mute'); | |
Howler.mute(); | |
} | |
break; | |
case KEYCODE_S: | |
flashMessage('skip to next song'); | |
startNextSong(); | |
break; | |
case KEYCODE_R: | |
randomize = !randomize; | |
if(randomize) { | |
flashMessage('Randomize'); | |
} else { | |
flashMessage('Play in sequence'); | |
} | |
break; | |
default: console.log(e.keyCode); | |
} | |
}); | |
d.addEventListener('wheel', function(e) { | |
currentVolume += Math.sign(e.wheelDelta) * 1/20; | |
setVolume(currentVolume); | |
}); | |
d.addEventListener('drop', function(e) { | |
cancel(e); | |
files = [].slice.apply.call([].slice, e.dataTransfer.files); | |
soundUrls = files.map(url.createObjectURL.bind(url)); | |
$('#help').removeClass('flash'); | |
clearInterval(timerInterval); | |
timerInterval = setInterval(updateSongTimer, 500); | |
startNextSong(); | |
}); | |
} | |
var cancel = function(e) {e.stopPropagation(); e.preventDefault(); } | |
window.addEventListener('DOMContentLoaded', main); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/1.1.28/howler.min.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
background: #000; margin: 0; | |
font-size: 1.5rem; | |
font-weight: normal; | |
font-family: sans-serif; | |
color: #fff; | |
text-shadow: | |
0 0 3px #000, 0 0 3px #000, 0 0 3px #000, | |
0 0 3px #000, 0 0 3px #000, 0 0 3px #000; | |
} | |
#display { | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
padding: 0.5rem; | |
margin: 1rem; | |
} | |
#help, #info { | |
position: absolute; | |
top: 0; | |
left: 0; | |
padding: 0.5rem; | |
margin: 1rem; | |
font-size: 1rem; | |
} | |
.display { | |
transition: opacity 1s ease-in; | |
opacity: 0; | |
} | |
.flash { | |
transition: opacity 0.1s ease-out; | |
opacity: 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment