Делаем нашу разметку HTML:
Пишем стиль CSS:
И добавляем функциональность с помощью jquery:
Смотрим наш результат:
HTML:
<div id="player-body" class="list-group">
<div id="player-controls" class="list-group-item text-center">
<input id="player-volume" type="text" data-slider-id="player-volume-slider" />
<span class="player-backward fa-stack fa-lg" title="Backward">
<span class="fa fa-square fa-stack-2x"></span>
<span class="fa fa-backward fa-stack-1x fa-inverse icon"></span>
</span>
<span class="player-play-pause fa-stack fa-lg" title="Play">
<span class="fa fa-square fa-stack-2x"></span>
<span class="fa fa-play fa-stack-1x fa-inverse icon"></span>
</span>
<span class="player-stop fa-stack fa-lg" title="Stop">
<span class="fa fa-square fa-stack-2x"></span>
<span class="fa fa-stop fa-stack-1x fa-inverse icon"></span>
</span>
<span class="player-forward fa-stack fa-lg" title="Forward">
<span class="fa fa-square fa-stack-2x"></span>
<span class="fa fa-forward fa-stack-1x fa-inverse icon"></span>
</span>
<br />
<span class="player-repeat fa-stack fa-lg" title="Repeat">
<span class="fa fa-circle fa-stack-2x border"></span>
<span class="fa fa-repeat fa-stack-1x fa-inverse icon"></span>
</span>
<span class="player-shuffle fa-stack fa-lg" title="Shuffle">
<span class="fa fa-circle fa-stack-2x border"></span>
<span class="fa fa-random fa-stack-1x fa-inverse icon"></span>
</span>
<span class="player-mute fa-stack fa-lg" title="Mute">
<span class="fa fa-circle fa-stack-2x border"></span>
<span class="fa fa-volume-up fa-stack-1x fa-inverse icon"></span>
</span>
</div>
<div id="player-nav" class="list-group-item text-center">
<span id="player-time"></span>
<input id="player-seek" type="text" data-slider-id="player-seek-slider" />
<span id="player-nav-title"></span>
</div>
<div id="player-list" class="list-group list-group-item"></div>
</div>
<audio id="player"></audio>
CSS:
#player-body ::-webkit-scrollbar {
width: 15px;
height: 15px;
}
#player-body ::-webkit-scrollbar-button {
width: 0;
height: 0;
}
#player-body ::-webkit-scrollbar-thumb {
background: #666666;
border: 1px solid #ffffff;
border-radius: 10px;
}
#player-body ::-webkit-scrollbar-thumb:hover {
background: #444444;
}
#player-body ::-webkit-scrollbar-thumb:active {
background: #444444;
}
#player-body ::-webkit-scrollbar-track {
background: #ffffff;
border: 1px none #ffffff;
border-radius: 10px;
}
#player-body ::-webkit-scrollbar-track:hover {
background: #ffffff;
}
#player-body ::-webkit-scrollbar-track:active {
background: #ffffff;
}
#player-body ::-webkit-scrollbar-corner {
background: transparent;
}
#player-body {
width: 300px;
qtop: 5px;
position: fixed;
margin: 10px;
font-size: 10pt;
z-index: 99;
border: 1px solid #000;
border-radius: 10px;
}
#player-controls {
background: #777;
border-radius: 10px 10px 0 0;
}
#player-controls > span {
cursor: pointer;
}
#player-controls .fa-square, #player-controls .fa-circle {
text-shadow: 0 0 1px #fff, 0 0 10px #000;
}
#player-controls .player-repeat, #player-controls .player-shuffle, #player-controls .player-mute {
margin: 10px 2px 0;
}
#player-nav {
color: #333;
font-weight: 600;
background: #777;
}
#player-nav #player-seek-slider {
width: 100%;
}
#player-nav #player-seek-slider .slider-track {
border: 1px solid #000;
box-shadow: 0 0 6px #000;
}
#player-nav #player-seek-slider .slider-selection {
background: #333;
}
#player-nav #player-seek-slider .slider-handle {
background: #333;
border: 2px solid #999;
box-shadow: 0 0 6px #000;
}
#player-nav #player-seek-slider .slider-handle:hover {
background: #000;
border: 2px solid #ccc;
}
#player-volume-slider {
position: absolute;
right: 5px;
top: 5px;
height: 80px;
z-index: 100;
}
#player-volume-slider .slider-track {
border: 1px solid #000;
box-shadow: 0 0 6px #000;
}
#player-volume-slider .slider-track-high {
background: #333;
}
#player-volume-slider .slider-handle {
background: #333;
border: 2px solid #999;
box-shadow: 0 0 6px #000;
}
#player-volume-slider .slider-handle:hover {
background: #000;
border: 2px solid #ccc;
}
#player-time, #player-nav-title {
text-shadow: 0 0 5px #000, 0 0 10px #000;
text-border: 1px solid #000;
color: #fff;
font-size: 12pt;
}
#player-list {
overflow: auto;
height: 400px;
padding: 0;
border-radius: 0 0 10px 10px;
}
.player-track {
padding: 5px 0 5px 10px;
}
.player-track > .number, .player-track > .duration {
position: absolute;
}
.player-track > .number{
top: 0;
right: 0;
background: rgba(51,51,51,.5);
color: #fff;
padding: 3px 7px 3px 7px;
width: 2em;
heigth: 2em;
border-radius: 0 0 0 15px;
}
.player-track > .duration {
bottom: 0;
right: 0;
padding: 2px 0 3px 7px;
}
.player-track > .player-play-pause {
}
.player-track > .band, .player-track > .track {
display: block;
qwidth: 230px;
color: #666;
text-shadow: 0 0 2px #fff, 0 0 4px #000;
}
.player-track.active {
}
.player-track > .band {
font-size: 11pt;
font-weight: 600;
heigth: 20px;
}
.player-track > .track {
font-size: 10pt;
heigth: 19px;
}
JavaScript:
$(document).ready(function() {
var player = $('#player'),
playerID = player[0],
exportTracks = "",
loadedTracks = loadTracks();
$.each(loadedTracks, function(key, val){
exportTracks += '<a class="player-track list-group-item" href="'+val.url+'">' +
'<span class="number text-center">'+val.number+'</span>' +
'<span class="duration text-center">'+val.duration+'</span>' +
'<span class="player-play-pause fa fa-play-circle fa-3x pull-left"></span>' +
'<span class="band">'+val.artist+'</span>' +
'<span class="track">'+val.track+'</span>' +
'</a>';
});
$('#player-list').html(exportTracks);
var trackList = $('#player-list > .player-track');
var currentTrack,
currentPlay,
currentPause,
isShuffle = 0,
lastShuffle = [],
isRepeat = 1,
isMute = 0;
var slider = $('#player-seek').slider({
formatter: function(value) {
return formatTime(value);
},
})
.on('change', function(value){
playerID.currentTime = value.value.newValue;
});
var volume = $('#player-volume').slider({
reversed: true,
orientation: 'vertical',
min: 0,
max: 100,
value: 50,
}).on('change', function(value){
playerID.volume = value.value.newValue/100;
});
trackList.bind('click', function(e) {
e.preventDefault();
play($(this).index());
});
init();
$('#player-controls > span').bind('click', function(e) {
e.preventDefault();
if($(this).hasClass('player-stop')){
init();
playerID.load();
} else if ($(this).hasClass('player-play-pause')) {
play(currentTrack);
} else if ($(this).hasClass('player-forward')) {
next('forward');
} else if ($(this).hasClass('player-backward')) {
next('backward');
} else if ($(this).hasClass('player-repeat')) {
if(isRepeat) {
isRepeat = 0;
$(this).css('opacity', .5).attr('title', 'On Repeat');
} else {
isRepeat = 1;
$(this).css('opacity', 1).attr('title', 'Off Repeat');
}
} else if ($(this).hasClass('player-shuffle')) {
if(isShuffle) {
isShuffle = 0;
lastShuffle = [];
$(this).css('opacity', .5).attr('title', 'On Shuffle');
} else {
isShuffle = 1;
$(this).css('opacity', 1).attr('title', 'Off Shuffle');
}
} else if ($(this).hasClass('player-mute')) {
if(isMute) {
isMute = 0;
playerID.muted = false;
$(this).css('opacity', 1).attr('title', 'On Mute');
} else {
isMute = 1;
playerID.muted = true;
$(this).css('opacity', .5).attr('title', 'Off Mute');
}
}
});
player.bind('playing', function(){
$('#player-controls > .player-play-pause > .icon').removeClass('fa-play').addClass('fa-pause');
$('#player-controls > .player-play-pause').attr('title', 'Pause')
trackList.removeClass('active');
trackList.eq(currentTrack).addClass('active');
$('> .player-play-pause', trackList).removeClass('fa-pause-circle fa-pulse').addClass('fa-play-circle');
$('> .player-play-pause', trackList.eq(currentTrack)).removeClass('fa-play-circle').addClass('fa-pause-circle');
});
player.bind('pause', function(){
$('#player-controls > .player-play-pause > .icon').removeClass('fa-pause').addClass('fa-play');
$('#player-controls > .player-play-pause').attr('title', 'Play');
$('> .player-play-pause', trackList).removeClass('fa-pause-circle').addClass('fa-play-circle');
});
player.bind('timeupdate', function(){
slider.slider('setAttribute', 'max', playerID.duration);
slider.slider('setValue', playerID.currentTime);
$('#player-nav > #player-time').html(formatTime(playerID.currentTime)+" / "+formatTime(playerID.duration));
});
player.bind('ended', function(){
next();
});
player.bind('volumechange', function(){
volume.slider('setValue', playerID.volume*100);
});
function init() {
currentTrack = 0;
currentPlay = -1;
currentPause = -1;
trackList.removeClass('active');
if(isRepeat) {
$('#player-controls > .player-repeat').css('opacity', 1).attr('title', 'Off Repeat');
} else {
$('#player-controls > .player-repeat').css('opacity', .5).attr('title', 'On Repeat');
}
if(isShuffle) {
$('#player-controls > .player-shuffle').css('opacity', 1).attr('title', 'Off Shuffle');
} else {
$('#player-controls > .player-shuffle').css('opacity', .5).attr('title', 'On Shuffle');
}
if(isMute) {
$('#player-controls > .player-mute').css('opacity', .5).attr('title', 'Off Mute');
playerID.muted = true;
} else {
$('#player-controls > .player-mute').css('opacity', 1).attr('title', 'On Mute');
playerID.muted = false;
}
$('#player-nav > #player-time').html(' ');
$('#player-nav > #player-nav-title').html(' ');
$('#player-controls > .player-play-pause > .icon').removeClass('fa-pause').addClass('fa-play');
$('#player-controls > .player-play-pause').attr('title', 'Play')
$('> .player-play-pause', trackList).removeClass('fa-pause-circle fa-pulse').addClass('fa-play-circle');
slider.slider('setAttribute', 'min', '0');
slider.slider('setAttribute', 'max', '0');
slider.slider('setAttribute', 'step', '1');
slider.slider('setValue', '0');
player.attr('src', '#');
}
function loadTracks() {
var tracks = {
0: {
artist: "The Cure",
track: "Painsong",
number: 1,
duration: "05:13",
url: "http://www.ex.ua/load/3392898"
},
1: {
artist: "The Cure",
track: "Pictures Of You",
number: 2,
duration: "07:26",
url: "http://www.ex.ua/load/3392899"
},
2: {
artist: "The Cure",
track: "Closedown",
number: 3,
duration: "04:19",
url: "http://www.ex.ua/load/3392916"
},
3: {
artist: "The Cure",
track: "Love Song",
number: 4,
duration: "03:28",
url: "http://www.ex.ua/load/3392903"
},
4: {
artist: "The Cure",
track: "Last Dance",
number: 5,
duration: "04:45",
url: "http://www.ex.ua/load/3392906"
},
5: {
artist: "The Cure",
track: "Lullaby",
number: 6,
duration: "04:10",
url: "http://www.ex.ua/load/3392907"
},
6: {
artist: "The Cure",
track: "Fascination Street",
number: 7,
duration: "05:14",
url: "http://www.ex.ua/load/3392909"
},
7: {
artist: "The Cure",
track: "Prayers For Rain",
number: 8,
duration: "06:05",
url: "http://www.ex.ua/load/3392911"
},
8: {
artist: "The Cure",
track: "The Same Deep Water As You",
number: 9,
duration: "09:20",
url: "http://www.ex.ua/load/3392912"
},
9: {
artist: "The Cure",
track: "Disintegration",
number: 10,
duration: "08:21",
url: "http://www.ex.ua/load/3392913"
},
10: {
artist: "The Cure",
track: "Homesick",
number: 11,
duration: "07:07",
url: "http://www.ex.ua/load/3392914"
},
11: {
artist: "The Cure",
track: "Untitled",
number: 12,
duration: "06:28",
url: "http://www.ex.ua/load/3392917"
}
};
return tracks;
}
function next(dirrection = 'forward') {
var track;
switch(dirrection) {
case 'forward':
if(isShuffle) {
do { track = randomTrack(); }
while(track == lastShuffle[0] || track == lastShuffle[1]);
lastShuffle.splice(0, 0, track);
} else if(currentTrack < trackList.length-1){
track = ++currentTrack;
} else {
if (isRepeat) {
track = 0;
} else {
init();
return 0;
}
}
break;
case 'backward':
if(isShuffle) {
var track;
if(lastShuffle.length>0) {
track = lastShuffle[1];
lastShuffle.shift();
} else {
track = randomTrack();
}
} else if(currentTrack > 0) {
track = --currentTrack;
} else {
track = trackList.length-1;
}
break;
}
play(track);
}
function play(index=currentTrack) {
currentTrack = index;
console.log($('#player-list'));
if(currentPlay == currentTrack) {
currentPause = currentTrack;
currentPlay = -1;
playerID.pause();
} else if(currentPause == currentTrack) {
currentPlay = currentTrack;
currentPause = -1;
playerID.play();
} else {
$('#player-list').animate({ scrollTop: trackList.eq(index)[0].offsetTop + 54 - $('#player-list')[0].offsetHeight/2}, 1000);
$('> .player-play-pause', trackList.eq(index)).removeClass('fa-play-circle').addClass('fa-spinner fa-pulse');
player.attr('src', trackList.eq(index).attr('href'));
currentPlay = currentTrack;
currentPause = -1;
playerID.play();
}
$('#player-nav-title').html($('> .band', trackList.eq(index)).html() + " - <span style='font-weight: 400;'>" + $('> .track', trackList.eq(index)).html() + "</span>");
}
function randomTrack(){
return Math.floor(Math.random() * 1000)%trackList.length;
}
function formatTime(time) {
time = isNaN(time) ? 0 : time ;
var min = Math.floor(time/60);
var sec = Math.floor(time%60);
//return (min < 10 ? "0" + min : min) + ":" + (sec < 10 ? "0" + sec : sec);
return (min < 10 ? "0" + min : min) + ":" + (sec < 10 ? "0" + sec : sec);
}
});