xxxxxxxxxx
234
let tracks = null;
let maxTracks = 0;
let maxDuration = 10000;
let averageDuration = 0;
let approxTracksPerDay = 0;
let isRandom = true;
let randomlyPlayedSongs = [];
let prevTotalTime = 0;
let prevRandomTotalTime = 0;
let totalTime = 0; // get all time that has been played, in ms
let randomTotalTime = 0;
let currentTrackId = 0; // save id to not recalculate
let pseudoID = 0; // add pseudoID if playlist is shorter
const backgroundColor = '#1DB954';
const lineColor = '#000000';
const indicatorColor = '#FFFFFF';
// by how many pixels the lines should shift
let shift = 1;
function setup() {
createCanvas(600, 600);
createMusicArray();
initTimeAndId();
createRandomSongSelection();
textFont('Space Mono');
textAlign(CENTER);
textSize(12);
frameRate(10); // lower framerate to save memory
// An average is taken from an approximate of songs in 24h.
// Even though the lines are not pixel perfect anymore, it
// seems to still look reasonable.
shift = 1 + int(approxTracksPerDay / width * 10) / 10; // one decimal, to achieve better results
}
function draw() {
background(backgroundColor);
// current time in ms
let currentTime = (((hour() * 60) + minute()) * 60 + second()) * 1000;
// check where we are at
if (currentTime > totalTime) {
// count up for repeat
currentTrackId++;
console.log('Current Track ID', currentTrackId);
}
if (currentTime > randomTotalTime) {
// count up for random
let randID = int(random(99));
randomlyPlayedSongs.push(randID);
console.log('Random Song ID',randomlyPlayedSongs.length);
}
// console.log( currentTime , currentTrackId );
let currentTimePosX = 0;
// create display of all music tracks so far
push();
translate(0, height * 0.4);
// create base background
stroke(lineColor);
strokeWeight(1);
line(0, 0, width, 0);
if (isRandom) {
randomTotalTime = 0;
for (let n = 0; n < randomlyPlayedSongs.length; n++) {
let index = randomlyPlayedSongs[n];
let track = tracks[index];
pseudoID = index;
let posX = n;
let length = map(track.duration, 0, maxDuration, 0, height / 2)
line(posX * shift, length / -2, posX * shift, length / 2);
prevRandomTotalTime = randomTotalTime;
randomTotalTime = randomTotalTime + track.duration;
}
currentTimePosX = (randomlyPlayedSongs.length - 1) * shift;
} else {
// translate the current iterations
let iterations = int(currentTrackId / maxTracks) + 1;
totalTime = 0; // set time to 0 to adjust
for (let n = 0; n < iterations; n++) {
tracks.forEach((track, index) => {
// only draw the ones that are done
if ((index + (maxTracks - 1) * n) < currentTrackId) {
pseudoID = index;
let posX = index + (maxTracks - 1) * n;
let length = map(track.duration, 0, maxDuration, 0, height / 2)
line(posX * shift, length / -2, posX * shift, length / 2);
totalTime = totalTime + track.duration;
if ((index + (maxTracks - 1) * n) < (currentTrackId - 1)) {
prevTotalTime = totalTime;
}
}
});
}
currentTimePosX = currentTrackId * shift;
}
pop();
// create the current "time"
stroke(indicatorColor);
strokeWeight(1);
line(currentTimePosX, 0, currentTimePosX, height);
// display playing indicator
let thisTime = currentTime - prevTotalTime;
if(isRandom){
thisTime = currentTime - prevRandomTotalTime;
}
let playedLength = map(thisTime, 0, tracks[pseudoID].duration, 0, width);
strokeWeight(6);
strokeCap(SQUARE);
line(0, height - 3, playedLength, height - 3);
// display current track
noStroke();
fill(lineColor);
text('currently playing: ' + tracks[pseudoID].name + ' — ' + tracks[pseudoID].artist, width / 2, height - 50);
if( isRandom ){
push();
fill(indicatorColor);
textStyle(ITALIC);
text('random', width / 2, height - 30);
pop();
}
}
function createMusicArray() {
// add all spotify tracks to a better readable array
tracks = playlist.tracks.items.map((item, index) => {
// set max duration for mapping
if (item.track.duration_ms > maxDuration) {
maxDuration = item.track.duration_ms;
}
averageDuration += item.track.duration_ms;
return ({
name: item.track.name,
artist: item.track.artists[0].name,
duration: item.track.duration_ms
})
});
maxTracks = tracks.length;
averageDuration = averageDuration / maxTracks;
// one day in ms / average duration of a track
approxTracksPerDay = int(86400000 / averageDuration) + 1;
console.log('Number of tracks', tracks.length);
console.log('Average number of tracks per day: ', approxTracksPerDay);
}
function initTimeAndId() {
// current time in ms
let currentTime = (((hour() * 60) + minute()) * 60 + second()) * 1000;
for (let n = 0; n < 6; n++) {
tracks.forEach((track, index) => {
// only draw the ones that are done
if (currentTime > totalTime) {
currentTrackId = index + n * 99;
pseudoID = index;
totalTime = totalTime + track.duration;
if ((index + 99 * n) < (currentTrackId - 1)) {
prevTotalTime = totalTime;
}
}
});
}
}
function createRandomSongSelection() {
// current time in ms
let currentTime = (((hour() * 60) + minute()) * 60 + second()) * 1000;
randomlyPlayedSongs = [];
randomTotalTime = 0;
function addRandomSong() {
let randID = int(random(99));
let track = tracks[randID];
randomTotalTime = randomTotalTime + track.duration;
randomlyPlayedSongs.push(randID);
// another loop if not enough songs yet
if (randomTotalTime < currentTime) {
addRandomSong();
}
}
// start the loop
addRandomSong();
}
function keyPressed() {
// toggle between random and repeat
if (key == 'r' || key == 'R') {
isRandom = !isRandom;
// generate new random list
}else if (key == 'g' || key == 'G') {
createRandomSongSelection();
}
}