|
|
|
// Loads the IFrame Player API code asynchronously.
|
|
|
|
let tag = document.createElement('script');
|
|
|
|
tag.src = 'https://www.youtube.com/iframe_api';
|
|
|
|
let firstScriptTag = document.getElementsByTagName('script')[0];
|
|
|
|
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
|
|
|
|
|
|
|
let crossfader = document.querySelector('#crossfader');
|
|
|
|
|
|
|
|
crossfader.addEventListener('input', (e) => {
|
|
|
|
|
|
|
|
if (Math.abs(crossfader.value - 500) < 15) {
|
|
|
|
crossfader.value = 500;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateCrossfader(crossfader.value);
|
|
|
|
});
|
|
|
|
|
|
|
|
class player {
|
|
|
|
trackID;
|
|
|
|
// volume;
|
|
|
|
// id;
|
|
|
|
// iframe;
|
|
|
|
player;
|
|
|
|
// node;
|
|
|
|
constructor(id) {
|
|
|
|
this.id = id;
|
|
|
|
this.iframe = document.querySelector('#'+this.id);
|
|
|
|
// console.log('#'+this.id);
|
|
|
|
// console.log(this.iframe);
|
|
|
|
// this.volume = vol;
|
|
|
|
|
|
|
|
this.node = this.iframe.parentNode;
|
|
|
|
this.volume = this.node.querySelector('.volume-slider').value;
|
|
|
|
this.loadButton = this.node.querySelector('.load-button');
|
|
|
|
this.speedSlider = this.node.querySelector('.speed-slider');
|
|
|
|
this.speedSlider.previousElementSibling.innerHTML = 'Speed: ' + this.speedSlider.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
init(trackID) {
|
|
|
|
this.trackID = trackID;
|
|
|
|
let src = `https://www.youtube-nocookie.com/embed/${trackID}?disablekb=1&enablejsapi=1&playsinline=1&autoplay=0&rel=0&modestbranding=1&iv_load_policy=3&version=3`;
|
|
|
|
this.iframe.setAttribute('src', src);
|
|
|
|
this.player = new YT.Player(this.id, {
|
|
|
|
events: {
|
|
|
|
'onReady': this.onPlayerReady.bind(this),
|
|
|
|
'onStateChange': this.onPlayerStateChange.bind(this),
|
|
|
|
'onError': this.onPlayerError.bind(this)
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
onPlayerReady(e) {
|
|
|
|
// console.log(e.target);
|
|
|
|
// this.node.querySelector('.volumeSlider').value = this.player.getVolume();
|
|
|
|
// e.target.playVideo();
|
|
|
|
console.log(e.target);
|
|
|
|
// e.target.setVolume(this.volume);
|
|
|
|
this.player.setVolume(this.volume);
|
|
|
|
|
|
|
|
this.node.querySelector('.volume-slider').addEventListener('input', (e) => {
|
|
|
|
let volume = e.target.value;
|
|
|
|
this.volume = volume;
|
|
|
|
this.player.setVolume(volume);
|
|
|
|
});
|
|
|
|
|
|
|
|
this.loadButton.addEventListener('click', () => {
|
|
|
|
let url = prompt('Enter a YouTube URL (track or playlist):', 'https://www.youtube.com/watch?v=' + this.trackID);
|
|
|
|
|
|
|
|
if (url) {
|
|
|
|
let newID = getYouTubeID(url);
|
|
|
|
|
|
|
|
if (newID && newID !== this.trackID) {
|
|
|
|
// window.location.href = './?' + newID;
|
|
|
|
this.load(newID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.speedSlider.addEventListener('input', (e) => {
|
|
|
|
this.speedSlider.previousElementSibling.innerHTML = 'Speed: ' + e.target.value;
|
|
|
|
console.log(e.target.value);
|
|
|
|
console.log(this.player);
|
|
|
|
this.player.setPlaybackRate(Number(e.target.value));
|
|
|
|
});
|
|
|
|
|
|
|
|
updateCrossfader(crossfader.value)
|
|
|
|
}
|
|
|
|
|
|
|
|
onPlayerStateChange(e) {
|
|
|
|
console.log(this.id + ' state change: ' + e.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
onPlayerError(e) {
|
|
|
|
console.log(this.id + ' - Error: ' + e.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
load(trackID) {
|
|
|
|
this.player.loadVideoById(trackID);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let playerA = new player('playerA');
|
|
|
|
let playerB = new player('playerB');
|
|
|
|
|
|
|
|
|
|
|
|
function onYouTubeIframeAPIReady() {
|
|
|
|
playerA.init('anWaxGNDRJ4')
|
|
|
|
playerB.init('PhEuAuhH418');
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateCrossfader(input) {
|
|
|
|
let normVal = crossfader.value / 1000;
|
|
|
|
|
|
|
|
// let coefB = normVal ** 2;
|
|
|
|
// let coefA = (1 - normVal) ** 2;
|
|
|
|
let coefB = Math.min(normVal*2, 1);
|
|
|
|
let coefA = Math.min((1-normVal)*2, 1);
|
|
|
|
|
|
|
|
|
|
|
|
// Sets box-shadow transparency depending on crossfader position
|
|
|
|
let boxShadowStyle = '0 0 3em #ddbddd'
|
|
|
|
playerA.iframe.style.boxShadow = boxShadowStyle + componentToHex(Math.round(coefA*255));
|
|
|
|
playerB.iframe.style.boxShadow = boxShadowStyle + componentToHex(Math.round(coefB*255));
|
|
|
|
|
|
|
|
playerA.player.setVolume(playerA.volume * coefA);
|
|
|
|
playerB.player.setVolume(playerB.volume * coefB);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getYouTubeID(url){
|
|
|
|
url = url.split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/);
|
|
|
|
return (url[2] !== undefined) ? url[2].split(/[^0-9a-z_\-]/i)[0] : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function componentToHex(c) {
|
|
|
|
var hex = c.toString(16);
|
|
|
|
return hex.length == 1 ? "0" + hex : hex;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Thumbnails: https://i1.ytimg.com/vi/{trackID}/mqdefault.jpg
|