initial version
This commit is contained in:
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 fpgaminer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
617
index.html
Normal file
617
index.html
Normal file
@@ -0,0 +1,617 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
|
||||
<title>Vidya Intarweb Playlist - HTML5 Player</title>
|
||||
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
|
||||
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.min.js"></script>
|
||||
<script>
|
||||
var g_playlist = null;
|
||||
var g_previous = [];
|
||||
var g_previous_idx = 0;
|
||||
var g_looping = false;
|
||||
var MAX_HISTORY = 10;
|
||||
|
||||
var scrubp = 0;
|
||||
var is_dragging_scrubber = false;
|
||||
|
||||
var PLAYLISTS = {
|
||||
'VIP': '//vip.aersia.net/roster.xml',
|
||||
'Mellow': '//vip.aersia.net/roster-mellow.xml',
|
||||
'Source': '//vip.aersia.net/roster-source.xml',
|
||||
'Exiled': '//vip.aersia.net/roster-exiled.xml',
|
||||
'WAP': '//wap.aersia.net/roster.xml',
|
||||
'CPP': '//cpp.aersia.net/roster.xml',
|
||||
};
|
||||
|
||||
var DEFAULT_PLAYLIST = 'VIP';
|
||||
|
||||
function formatTimecode (seconds) {
|
||||
seconds = Math.floor (seconds);
|
||||
minutes = Math.floor (seconds / 60);
|
||||
seconds = seconds - (minutes * 60);
|
||||
minutes = "" + minutes;
|
||||
seconds = "" + seconds;
|
||||
|
||||
if (minutes.length == 1)
|
||||
minutes = "0" + minutes;
|
||||
if (seconds.length == 1)
|
||||
seconds = "0" + seconds;
|
||||
|
||||
return minutes + ":" + seconds;
|
||||
}
|
||||
|
||||
// Creates an id for a track used in the location hash
|
||||
function createTrackId (track) {
|
||||
var playlist = $('#select-playlist').val ();
|
||||
var track = track.creator + ' - ' + track.title;
|
||||
track = track.replace(/[^a-zA-Z0-9-]/g, '_');
|
||||
|
||||
return encodeURIComponent (playlist) + ':' + track;
|
||||
}
|
||||
|
||||
function parseTrackId (trackId) {
|
||||
var pieces = trackId.split (':');
|
||||
var playlist = '';
|
||||
var track = '';
|
||||
|
||||
if (pieces.length < 2) {
|
||||
playlist = decodeURIComponent (trackId);
|
||||
track = '';
|
||||
} else {
|
||||
pieces.pop ();
|
||||
playlist = decodeURIComponent (pieces.join (':'));
|
||||
track = trackId;
|
||||
}
|
||||
|
||||
if (!(playlist in PLAYLISTS))
|
||||
return null;
|
||||
|
||||
return {
|
||||
playlist: playlist,
|
||||
track: track
|
||||
};
|
||||
}
|
||||
|
||||
function parsePlaylist (playlistXML) {
|
||||
result = [];
|
||||
|
||||
$(playlistXML).find ('playlist trackList > track').each (function () {
|
||||
track = {
|
||||
creator: $(this).find ('creator').text (),
|
||||
title: $(this).find ('title').text (),
|
||||
location: $(this).find ('location').text ()
|
||||
};
|
||||
|
||||
result.push (track);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function playPreviousTrack () {
|
||||
if (g_playlist === null)
|
||||
return;
|
||||
|
||||
if (g_previous_idx <= 0)
|
||||
g_previous_idx = 0;
|
||||
else
|
||||
g_previous_idx -= 1;
|
||||
|
||||
playTrack (g_previous[g_previous_idx]);
|
||||
}
|
||||
|
||||
function playNextTrack () {
|
||||
if (g_playlist === null)
|
||||
return;
|
||||
|
||||
if (g_previous_idx >= (g_previous.length - 1)) {
|
||||
g_previous.push (Math.floor (Math.random () * g_playlist.length));
|
||||
g_previous_idx = g_previous.length - 1;
|
||||
}
|
||||
else {
|
||||
g_previous_idx += 1;
|
||||
}
|
||||
|
||||
while (g_previous.length > MAX_HISTORY) {
|
||||
g_previous.shift ();
|
||||
g_previous_idx -= 1;
|
||||
}
|
||||
|
||||
playTrack (g_previous[g_previous_idx]);
|
||||
}
|
||||
|
||||
|
||||
function playTrack (trackid) {
|
||||
var track = g_playlist[trackid];
|
||||
|
||||
$('#tracks-table .selected').removeClass ('selected');
|
||||
var trackelem = $('#tracks-table div').eq (trackid);
|
||||
trackelem.addClass ('selected');
|
||||
|
||||
window.location.hash = createTrackId (track);
|
||||
$('audio').attr ('src', track.location);
|
||||
$('audio').trigger ('play');
|
||||
|
||||
$('html, body').stop ().animate ({
|
||||
scrollTop: trackelem.offset ().top - $('.control-bar').height ()
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function loadNewPlaylist (playlist, track) {
|
||||
var playlistURL = PLAYLISTS[playlist];
|
||||
var selected_track = track;
|
||||
|
||||
localStorage['playlist'] = playlist;
|
||||
$('#select-playlist').val (playlist);
|
||||
|
||||
// Clear
|
||||
$('#tracks-table div').remove ();
|
||||
g_previous = [];
|
||||
g_previous_idx = 0;
|
||||
g_playlist = null;
|
||||
|
||||
$.ajax({
|
||||
url: playlistURL,
|
||||
success: function (data) {
|
||||
// Parse track list
|
||||
g_playlist = parsePlaylist (data);
|
||||
|
||||
// Build HTML table for track listing
|
||||
for (var i = 0; i < g_playlist.length; ++i) {
|
||||
var track = g_playlist[i];
|
||||
|
||||
var row = $('<div>');
|
||||
row.text (track.creator + ' - ' + track.title);
|
||||
row.attr ('id', createTrackId (track));
|
||||
|
||||
row.appendTo ('#tracks-table');
|
||||
(function (i) {
|
||||
row.click (function () {
|
||||
playTrack (i);
|
||||
});
|
||||
}) (i);
|
||||
}
|
||||
|
||||
// Select specified track if possible, or play random track if not.
|
||||
var elements = $('#tracks-table div').filter (function (idx, elem) {
|
||||
return elem.id == selected_track;
|
||||
});
|
||||
|
||||
if (elements.length > 0) {
|
||||
elements[0].click ();
|
||||
} else {
|
||||
playNextTrack ();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function playpause () {
|
||||
if ($('audio').get (0).paused)
|
||||
$('audio').trigger ('play');
|
||||
else
|
||||
$('audio').trigger ('pause');
|
||||
}
|
||||
|
||||
function toggleLooping () {
|
||||
g_looping = !g_looping;
|
||||
$('audio').attr ('loop', g_looping);
|
||||
$('#btn-loop i').toggleClass('fa-times', g_looping);
|
||||
$('#btn-loop i').toggleClass('fa-repeat', !g_looping);
|
||||
}
|
||||
|
||||
function populatePlaylistOptions () {
|
||||
for (var name in PLAYLISTS) {
|
||||
var option = $("<option>");
|
||||
option.val (name);
|
||||
option.text (name);
|
||||
|
||||
$('#select-playlist').append (option);
|
||||
}
|
||||
}
|
||||
|
||||
$(function () {
|
||||
// Register Events
|
||||
$('audio').on ('pause', function () {
|
||||
$('#btn-play i').removeClass ('fa-pause');
|
||||
$('#btn-play i').addClass ('fa-play');
|
||||
});
|
||||
|
||||
$('audio').on ('play', function () {
|
||||
$('#btn-play i').removeClass ('fa-play');
|
||||
$('#btn-play i').addClass ('fa-pause');
|
||||
});
|
||||
|
||||
$('audio').on ('error', function () {
|
||||
playNextTrack ();
|
||||
});
|
||||
|
||||
$('audio').on ('timeupdate', function () {
|
||||
if (isNaN (this.duration))
|
||||
return;
|
||||
if (!is_dragging_scrubber)
|
||||
$('#scrubber-progress').css('width', (this.currentTime / this.duration) * 100+'%');
|
||||
$('#time-current').text (formatTimecode (this.currentTime));
|
||||
$('#time-remaining').text (formatTimecode (this.duration - this.currentTime));
|
||||
});
|
||||
|
||||
$('#time-bar').on('mousedown mouseup', function(e) {
|
||||
if (e.which == 1) {
|
||||
is_dragging_scrubber = true;
|
||||
var sc_w = $('#scrubber-track').outerWidth();
|
||||
var p = ((e.pageX - $('#scrubber-track').offset().left) / sc_w) * 100;
|
||||
$('#scrubber-progress').css('width', p+'%');
|
||||
scrubp = p;
|
||||
$(document).on('mousemove.scrubber-track', function(e) {
|
||||
sc_w = $('#scrubber-track').outerWidth();
|
||||
p = ((e.pageX - $('#scrubber-track').offset().left) / sc_w) * 100;
|
||||
$('#scrubber-progress').css('width', p+'%');
|
||||
scrubp = p;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('mouseup.scrubber-track', function(e) {
|
||||
if (is_dragging_scrubber) {
|
||||
$('audio').get(0).currentTime = (scrubp / 100) * $('audio').get(0).duration;
|
||||
$(this).off('mousemove.scrubber-track');
|
||||
is_dragging_scrubber = false;
|
||||
}
|
||||
});
|
||||
|
||||
$('audio').on ('ended', function () {
|
||||
if (!g_looping)
|
||||
playNextTrack ();
|
||||
});
|
||||
|
||||
$('#btn-play').click (playpause);
|
||||
|
||||
$(document).keypress (function (e) {
|
||||
if (e.which == 32) {
|
||||
e.preventDefault ();
|
||||
playpause ();
|
||||
}
|
||||
});
|
||||
|
||||
$('#btn-next').click (function () {
|
||||
playNextTrack (true);
|
||||
});
|
||||
|
||||
$('#btn-previous').click (function () {
|
||||
playPreviousTrack ();
|
||||
});
|
||||
|
||||
$('#btn-loop').click (function () {
|
||||
toggleLooping ();
|
||||
});
|
||||
|
||||
$('#select-playlist').on ('change', function () {
|
||||
var playlist = $('#select-playlist').val ();
|
||||
loadNewPlaylist (playlist, '');
|
||||
});
|
||||
|
||||
$('#volume-slider').slider({
|
||||
orientation: "vertical",
|
||||
range: "min",
|
||||
min: 0,
|
||||
max: 100,
|
||||
value: $('audio').get (0).volume * 100,
|
||||
slide: function(event, ui) {
|
||||
//change volume here
|
||||
$('audio').get(0).volume = (ui.value / 100);
|
||||
if (ui.value > 50) {
|
||||
$('#btn-volume i').removeClass($('#btn-volume i').attr('class').split(' ')[1]).addClass('fa-volume-up');
|
||||
}
|
||||
else if (ui.value > 0) {
|
||||
$('#btn-volume i').removeClass($('#btn-volume i').attr('class').split(' ')[1]).addClass('fa-volume-down');
|
||||
}
|
||||
else {
|
||||
$('#btn-volume i').removeClass($('#btn-volume i').attr('class').split(' ')[1]).addClass('fa-volume-off');
|
||||
}
|
||||
|
||||
localStorage['volume'] = $('audio').get (0).volume;
|
||||
}
|
||||
});
|
||||
|
||||
$('#btn-volume').on('click', function() {
|
||||
$('#volume-slider').slideToggle(200);
|
||||
});
|
||||
|
||||
populatePlaylistOptions ();
|
||||
|
||||
// Default playlist, random track
|
||||
var playlist = DEFAULT_PLAYLIST;
|
||||
var track = '';
|
||||
|
||||
/* Load settings */
|
||||
if (localStorage.getItem ('volume') !== null)
|
||||
$('audio').get (0).volume = localStorage.getItem('volume');
|
||||
|
||||
if (localStorage.getItem ('playlist') !== null) {
|
||||
if (localStorage.getItem ('playlist') in PLAYLISTS)
|
||||
playlist = localStorage.getItem ('playlist');
|
||||
}
|
||||
|
||||
// If hash is set, override playlist and track
|
||||
var url_track = parseTrackId (window.location.hash.substr (1));
|
||||
|
||||
if (url_track !== null) {
|
||||
playlist = url_track.playlist;
|
||||
track = url_track.track;
|
||||
}
|
||||
|
||||
// Load playlist and track
|
||||
loadNewPlaylist (playlist, track);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #183c63;
|
||||
}
|
||||
|
||||
#tracks-table {
|
||||
width: 100%;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
#tracks-table div {
|
||||
background-color: #183c63;
|
||||
border: 1px solid #003366;
|
||||
color: #FF9148;
|
||||
padding: 5px;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 8pt;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#tracks-table div.selected {
|
||||
background-color: #e5874a;
|
||||
color: #183c63;
|
||||
}
|
||||
|
||||
#tracks-table div:hover {
|
||||
background-color: #4e91ff;
|
||||
color: #183c63;
|
||||
}
|
||||
|
||||
.control-bar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 18px;
|
||||
background: linear-gradient(to bottom, rgba(192,204,217,1) 0%, rgba(0,12,25,1) 100%);
|
||||
}
|
||||
|
||||
.control-buttons {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-spacing: 1px;
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
.control-buttons td {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 7pt;
|
||||
color: #FF9148;
|
||||
border-width: 0px;
|
||||
background: linear-gradient(to bottom, rgba(61,99,137,1) 0%, rgba(3,41,79,1) 100%);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.control-buttons td:hover {
|
||||
color: #4e91ff;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.control-volume {
|
||||
width: 60px;
|
||||
font-size: 9pt;
|
||||
}
|
||||
|
||||
.control-playlist {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.control-playlist select {
|
||||
height: 16px;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 7pt;
|
||||
padding: 0;
|
||||
color: #FF9148;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.credits {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 100px;
|
||||
background-color: #000;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
color: #FF9148;
|
||||
padding: 5px;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 8pt;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.credits a {
|
||||
color: #a96030;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 8pt;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#time-current, #time-remaining {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
#time-bar:hover #scrubber {
|
||||
background: rgb(78,145,255);
|
||||
}
|
||||
|
||||
#scrubber-track {
|
||||
width: 100%;
|
||||
height: 5px;
|
||||
background: #7f6157;
|
||||
}
|
||||
|
||||
#scrubber-progress {
|
||||
background: #FF9148;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#scrubber {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
height: 8px;
|
||||
width: 3px;
|
||||
display: inline-block;
|
||||
border: 1px solid #7f6157;
|
||||
background: #FF9148;
|
||||
-ms-transform: translateY(-25%);
|
||||
-webkit-transform: translateY(-25%);
|
||||
transform: translateY(-25%);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background-color: #7f6157;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #FF9148;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: rgb(78,145,255);
|
||||
}
|
||||
|
||||
#volume-slider {
|
||||
width: 10px;
|
||||
height: 65px;
|
||||
position: absolute;
|
||||
background: linear-gradient(to bottom, rgba(61,99,137,1) 0%, rgba(3,41,79,1) 100%);
|
||||
border: 1px solid gray;
|
||||
top: 19px;
|
||||
margin-left: -1px;
|
||||
display: none;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.ui-slider-range-min {
|
||||
background-color: #FF9148;
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
}
|
||||
@media(max-device-width: 700px) {
|
||||
.control-bar {
|
||||
height: 70px;
|
||||
}
|
||||
.control-buttons {
|
||||
height: 50px;
|
||||
}
|
||||
.control-button {
|
||||
width: 30px;
|
||||
}
|
||||
#time-bar {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
#tracks-table {
|
||||
margin-top: 70px;
|
||||
}
|
||||
#tracks-table div {
|
||||
font-size: 11pt;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class='control-bar'>
|
||||
<table class='control-buttons' cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td id='btn-play' class='control-button'><i class="fa fa-play"></i></td>
|
||||
<td id='btn-previous' class='control-button'><i class="fa fa-step-backward"></i></td>
|
||||
<td id='btn-next' class='control-button'><i class="fa fa-step-forward"></i></td>
|
||||
<td id='btn-loop' class='control-button'><i class="fa fa-repeat"></i></td>
|
||||
<td id='time-current'></td>
|
||||
<td id='time-bar'><div id="scrubber-track"><div id="scrubber-progress"><div id="scrubber"></div></div></div></td>
|
||||
<td id='time-remaining'></td>
|
||||
<td id='btn-volume' class='control-button'><i class="fa fa-volume-up"></i><div id="volume-slider"></div></td>
|
||||
<td class='control-playlist'>
|
||||
<select id='select-playlist'></select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<audio></audio>
|
||||
|
||||
<div id='tracks-table'></div>
|
||||
|
||||
<div class='credits'>
|
||||
<a href="//aersia.net" target="_blank">playlist by Cats777</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user