html5-css3-audio-player-wit.../script.js
2024-08-13 14:23:01 +02:00

354 lines
No EOL
14 KiB
JavaScript

// Creating everything
var ap_apwp, apwp_audio, apwp_album, apwp_cover, apwp_title, apwp_artist, apwp_controls, apwp_progress, apwp_volume, apwp_v_slider, apwp_v_num, apwp_others;
// Multiple events to a listener
function addEventListener_multi(element, eventNames, handler) {
var events = eventNames.split(' ');
events.forEach(e => element.addEventListener(e, handler, false));
}
// Random numbers in a specific range
function getRandom(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Position element inside element
function getRelativePos(elm) {
var pPos = elm.parentNode.getBoundingClientRect(); // Parent pos
var cPos = elm.getBoundingClientRect(); // ... and Target pos
var pos = {};
pos.top = cPos.top - pPos.top + elm.parentNode.scrollTop,
pos.right = cPos.right - pPos.right,
pos.bottom = cPos.bottom - pPos.bottom,
pos.left = cPos.left - pPos.left;
return pos;
}
function formatTime(val) {
var h = 0, m = 0, s;
val = parseInt(val, 10);
if (val > 60 * 60) {
h = parseInt(val / (60 * 60), 10);
val -= h * 60 * 60;
}
if (val > 60) {
m = parseInt(val / 60, 10);
val -= m * 60;
}
s = val;
val = (h > 0)? h + ':' : '';
val += (m > 0)? ((m < 10 && h > 0)? '0' : '') + m + ':' : '0:';
val += ((s < 10)? '0' : '') + s;
return val;
}
function apwp_initTime() {
apwp_controls.querySelector('.start-time').innerHTML = formatTime(apwp_audio.currentTime); // Calculate current value time
if (!apwp_isStream) {
apwp_controls.querySelector('.end-time').innerHTML = formatTime(apwp_audio.duration); // Calculate total value time
apwp_progress.value = apwp_audio.currentTime / apwp_audio.duration * 100; // Progress bar
}
// Ended of the audio
if (apwp_audio.currentTime == apwp_audio.duration) {
apwp_controls.querySelector('.apwp-plause').classList.remove('fa-pause');
apwp_controls.querySelector('.apwp-plause').classList.add('fa-play');
apwp_audio.removeEventListener('timeupdate', apwp_initTime);
if (apwp_isNext) { // Autoload next audio
var elem;
apwp_a_index++;
if (apwp_a_index == apwp_a_url.length) { // Repeat all audio
apwp_a_index = 0;
elem = apwp_a_url[0];
} else {
elem = apwp_a_url[apwp_a_index];
}
apwp_changeAudio(elem);
apwp_setAlbum(apwp_a_index);
} else {
apwp_isPlaying = false;
}
}
}
function apwp_initAudio() {
// If readyState more than 2, audio file has loaded
apwp_isLoaded = apwp_audio.readyState == 4 ? true : false;
apwp_isStream = apwp_audio.duration == 'Infinity' ? true : false;
apwp_controls.querySelector('.apwp-plause').disabled = false;
apwp_progress.disabled = apwp_isStream ? true : false;
if (!apwp_isStream) {
apwp_progress.parentNode.classList.remove('apwp-load', 'apwp-loading');
apwp_controls.querySelector('.end-time').innerHTML = formatTime(apwp_audio.duration);
}
apwp_audio.addEventListener('timeupdate', apwp_initTime); // Tracking load progress
if (apwp_isLoaded && apwp_isPlaying) apwp_audio.play();
// Progress bar click event
addEventListener_multi(apwp_progress, 'touchstart mousedown', function (e) {
if (apwp_isStream) {
e.stopPropagation();
return false;
}
if (apwp_audio.readyState == 4) {
apwp_audio.removeEventListener('timeupdate', apwp_initTime);
apwp_audio.pause();
}
});
addEventListener_multi(apwp_progress, 'touchend mouseup', function (e) {
if (apwp_isStream) {
e.stopPropagation();
return false;
}
if (apwp_audio.readyState == 4) {
apwp_audio.currentTime = apwp_progress.value * apwp_audio.duration / 100;
apwp_audio.addEventListener('timeupdate', apwp_initTime);
if (apwp_isPlaying) apwp_audio.play();
}
});
// Add event listener for next track
apwp_audio.addEventListener('ended', playNextTrack);
}
function playNextTrack() {
apwp_a_index++;
if (apwp_a_index >= apwp_a_url.length) {
apwp_a_index = 0; // Repeat playlist from the beginning
}
// Load next track
apwp_changeAudio(apwp_a_url[apwp_a_index]);
apwp_setAlbum(apwp_a_index);
// Replay next track
apwp_audio.play();
apwp_isPlaying = true;
apwp_controls.querySelector('.apwp-plause').classList.remove('fa-play');
apwp_controls.querySelector('.apwp-plause').classList.add('fa-pause');
}
function apwp_changeAudio(elem) {
apwp_isLoaded = false;
apwp_controls.querySelector('.apwp-prev').disabled = apwp_a_index == 0 ? true : false;
apwp_controls.querySelector('.apwp-plause').disabled = apwp_auto_load ? true : false;
apwp_controls.querySelector('.apwp-next').disabled = apwp_a_index == apwp_a_url.length - 1 ? true : false;
apwp_progress.parentNode.classList.add('apwp-load');
apwp_progress.disabled = true;
apwp_progress.value = 0;
apwp_controls.querySelector('.start-time').innerHTML = '00:00';
apwp_controls.querySelector('.end-time').innerHTML = '00:00';
elem = apwp_isRandom && apwp_isNext ? apwp_a_url[getRandom(0, apwp_a_url.length - 1)] : elem;
// Playlist, audio is running
for (var i = 0; i < apwp_a_url.length; i++) {
apwp_a_url[i].parentNode.classList.remove('apwp-active');
if (apwp_a_url[i] == elem) {
apwp_a_index = i;
apwp_a_url[i].parentNode.classList.add('apwp-active');
}
}
// Scrolling to element inside element
var apwp_active = getRelativePos(apwp_source[apwp_a_index]);
apwp_source[apwp_a_index].parentNode.scrollTop = apwp_active.top;
// Load the new track
apwp_loadAudio(elem);
if (apwp_isPlaying) {
apwp_controls.querySelector('.apwp-plause').classList.remove('fa-play');
apwp_controls.querySelector('.apwp-plause').classList.add('fa-pause');
}
}
function apwp_loadAudio(elem) {
apwp_progress.parentNode.classList.add('apwp-loading');
apwp_controls.querySelector('.apwp-plause').disabled = true;
apwp_audio.querySelector('source').src = elem.dataset.src;
apwp_audio.load();
apwp_audio.volume = parseFloat(apwp_v_num / 100); // Based on volume input value
apwp_audio.addEventListener('canplaythrough', apwp_initAudio); // Play audio without stop for buffering
// If audio fails to load, only IE/Edge 9.0 or above
apwp_audio.addEventListener('error', function() {
alert('Please reload the page.');
});
}
function apwp_setAlbum(index) {
apwp_cover.innerHTML = apwp_a_url[index].dataset.cover ? '<div style="background:url(' + apwp_a_url[index].dataset.cover + ') no-repeat;background-size:cover;width:80px;height:80px;"></div>' : '<i class="fa fa-music fa-5x"></i>';
apwp_title.innerHTML = apwp_source[index].querySelector('.apwp-source').innerHTML;
apwp_artist.innerHTML = apwp_source[index].querySelector('.apwp-desc') ? apwp_source[index].querySelector('.apwp-desc').innerHTML : '';
}
function apwp_startScript() {
ap_apwp = document.querySelector('#apwp');
apwp_audio = ap_apwp.querySelector('#audio');
apwp_album = ap_apwp.querySelector('.apwp-album');
apwp_cover = apwp_album.querySelector('.apwp-cover');
apwp_title = apwp_album.querySelector('.apwp-title');
apwp_artist = apwp_album.querySelector('.apwp-artist');
apwp_controls = ap_apwp.querySelector('.apwp-controls');
apwp_progress = apwp_controls.querySelector('.apwp-progress');
apwp_volume = apwp_controls.querySelector('.apwp-volume');
apwp_v_slider = apwp_volume.querySelector('.apwp-v-slider');
apwp_v_num = apwp_v_slider.value; // Default volume
apwp_others = apwp_controls.querySelector('.apwp-others');
apwp_auto_load = apwp_config.auto_load; // Autoload audio file
if (apwp_config.shide_top) apwp_album.parentNode.classList.toggle('apwp-hide');
if (apwp_config.shide_btm) {
apwp_playlist.classList.add('apwp-display');
apwp_playlist.classList.toggle('apwp-hide');
}
if (apwp_a_url.length <= 1) {
apwp_controls.querySelector('.apwp-prev').style.display = 'none';
apwp_controls.querySelector('.apwp-next').style.display = 'none';
apwp_others.querySelector('.apwp-plext').style.display = 'none';
apwp_others.querySelector('.apwp-random').style.display = 'none';
}
// Playlist listeners
apwp_source.forEach(function(item, index) {
if (item.classList.contains('apwp-active')) apwp_a_index = index; // Playlist contains '.apwp-active'
item.addEventListener('click', function() {
apwp_audio.removeEventListener('timeupdate', apwp_initTime);
apwp_a_index = index;
apwp_changeAudio(this.querySelector('.apwp-source'));
apwp_setAlbum(apwp_a_index);
});
});
// FIRST AUDIO LOAD =======
apwp_changeAudio(apwp_a_url[apwp_a_index]);
apwp_setAlbum(apwp_a_index);
// FIRST AUDIO LOAD =======
// Controls listeners
apwp_controls.querySelector('.apwp-plauseward').addEventListener('click', function(e) {
var eles = e.target.classList;
if (eles.contains('apwp-plause')) {
if (apwp_audio.paused) {
if (!apwp_isLoaded) apwp_loadAudio(apwp_a_url[apwp_a_index]);
apwp_audio.play();
apwp_isPlaying = true;
eles.remove('fa-play');
eles.add('fa-pause');
} else {
apwp_audio.pause();
apwp_isPlaying = false;
eles.remove('fa-pause');
eles.add('fa-play');
}
} else {
if (eles.contains('apwp-prev') && apwp_a_index != 0) {
apwp_a_index = apwp_a_index-1;
e.target.disabled = apwp_a_index == 0 ? true : false;
} else if (eles.contains('apwp-next') && apwp_a_index != apwp_a_url.length-1) {
apwp_a_index = apwp_a_index+1;
e.target.disabled = apwp_a_index == apwp_a_url.length-1 ? true : false;
}
apwp_audio.removeEventListener('timeupdate', apwp_initTime);
apwp_changeAudio(apwp_a_url[apwp_a_index]);
apwp_setAlbum(apwp_a_index);
}
});
// Audio volume
apwp_volume.addEventListener('click', function(e) {
var eles = e.target.classList;
if (eles.contains('apwp-mute')) {
if (eles.contains('fa-volume-up')) {
eles.remove('fa-volume-up');
eles.add('fa-volume-off');
apwp_v_slider.value = 0;
} else {
eles.remove('fa-volume-off');
eles.add('fa-volume-up');
apwp_v_slider.value = apwp_v_num;
}
} else {
apwp_v_num = apwp_v_slider.value;
if (apwp_v_num != 0) {
apwp_controls.querySelector('.apwp-mute').classList.remove('fa-volume-off');
apwp_controls.querySelector('.apwp-mute').classList.add('fa-volume-up');
}
}
apwp_audio.volume = parseFloat(apwp_v_slider.value / 100);
});
// Others
apwp_others.addEventListener('click', function(e) {
var eles = e.target.classList;
if (eles.contains('apwp-plext')) {
apwp_isNext = apwp_isNext && !apwp_isRandom ? false : true;
if (!apwp_isRandom) apwp_isRanext = apwp_isRanext ? false : true;
eles.contains('apwp-active') && !apwp_isRandom ? eles.remove('apwp-active') : eles.add('apwp-active');
} else if (eles.contains('apwp-random')) {
apwp_isRandom = apwp_isRandom ? false : true;
if (apwp_isNext && !apwp_isRanext) {
apwp_isNext = false;
apwp_others.querySelector('.apwp-plext').classList.remove('apwp-active');
} else {
apwp_isNext = true;
apwp_others.querySelector('.apwp-plext').classList.add('apwp-active');
}
eles.contains('apwp-active') ? eles.remove('apwp-active') : eles.add('apwp-active');
} else if (eles.contains('apwp-shide-top')) {
apwp_album.parentNode.classList.toggle('apwp-hide');
} else if (eles.contains('apwp-shide-bottom')) {
apwp_playlist.classList.add('apwp-display');
apwp_playlist.classList.toggle('apwp-hide');
}
});
}
// Start apwple player
if (document.querySelector('#apwp')) {
var apwp_auto_load, apwp_audio, apwp_album, apwp_cover, apwp_title, apwp_artist, apwp_controls, apwp_progress, apwp_volume, apwp_v_slider, apwp_v_num, apwp_others;
var ap_apwp = document.querySelector('#apwp');
var apwp_playlist = ap_apwp.querySelector('.apwp-playlist');
var apwp_source = apwp_playlist.querySelectorAll('li');
var apwp_a_url = apwp_playlist.querySelectorAll('[data-src]');
var apwp_a_index = 0;
var apwp_isPlaying = false;
var apwp_isNext = false; // Auto play
var apwp_isRandom = false; // Play random
var apwp_isRanext = false; // Check if before random starts, apwp_isNext value is true
var apwp_isStream = false; // Radio streaming
var apwp_isLoaded = false; // Audio file has loaded
var apwp_config = ap_apwp.dataset.config ? JSON.parse(ap_apwp.dataset.config) : {
shide_top: false, // Show/hide album
shide_btm: false, // Show/hide playlist
auto_load: false // Autoload audio file
};
var apwp_elem = '';
apwp_elem += '<audio id="audio" preload><source src="" type="audio/mpeg"></audio>';
apwp_elem += '<div class="apwp-display"><div class="apwp-album w-full flex-wrap"><div class="apwp-cover"><i class="fa fa-music fa-5x"></i></div><div class="apwp-info"><div class="apwp-title">Title</div><div class="apwp-artist">Artist</div></div></div></div>';
apwp_elem += '<div class="apwp-controls flex-wrap flex-align">';
apwp_elem += '<div class="apwp-plauseward flex flex-align"><button type="button" class="apwp-prev fa fa-backward" disabled></button><button type="button" class="apwp-plause fa fa-play" disabled></button><button type="button" class="apwp-next fa fa-forward" disabled></button></div>';
apwp_elem += '<div class="apwp-tracker apwp-load"><input class="apwp-progress" type="range" min="0" max="100" value="0" disabled/><div class="apwp-buffer"></div></div>';
apwp_elem += '<div class="apwp-time flex flex-align"><span class="start-time">00:00</span><span class="apwp-slash">&#160;/&#160;</span><span class="end-time">00:00</span></div>';
apwp_elem += '<div class="apwp-volume flex flex-align"><button type="button" class="apwp-mute fa fa-volume-up"></button><input class="apwp-v-slider" type="range" min="0" max="100" value="100"/></div>';
apwp_elem += '<div class="apwp-others flex flex-align"><button type="button" class="apwp-plext fa fa-play-circle" title="Auto Play"></button><button type="button" class="apwp-random fa fa-random" title="Random"></button><div class="apwp-shide"><button type="button" class="apwp-shide-top fa fa-caret-up" title="Show/Hide Album"></button><button type="button" class="apwp-shide-bottom fa fa-caret-down" title="Show/Hide Playlist"></button></div></div>';
apwp_elem += '</div>'; //apwp-controls
var apwp_player = document.createElement('div');
apwp_player.classList.add('apwp-player');
apwp_player.innerHTML = apwp_elem;
ap_apwp.insertBefore(apwp_player, apwp_playlist);
apwp_startScript();
}