├── README.md ├── index.html ├── main.js ├── output ├── example-music-player.mp4 └── html-css.png └── style.css /README.md: -------------------------------------------------------------------------------- 1 | # js-music-player 2 | This is a simple User Interface of a music player created in HTML, CSS and JavaScript. 3 | 4 | ![Output](/output/html-css.png) 5 | 6 | ## Running the player 7 | 8 | The index.html file can be run on any modern browser to run the music player. 9 | 10 | ## Adding more tracks 11 | 12 | The tracks are currently being loaded from the tracklist array specified in main.js. More tracks can be added by adding the details of each track as an object to the tracklist. -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Simple Music Player 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |
PLAYING x OF y
17 |
18 |
Track Name
19 |
Track Artist
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
00:00
28 | 29 |
00:00
30 |
31 |
32 | 33 | 34 | 35 |
36 |
37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | let now_playing = document.querySelector(".now-playing"); 2 | let track_art = document.querySelector(".track-art"); 3 | let track_name = document.querySelector(".track-name"); 4 | let track_artist = document.querySelector(".track-artist"); 5 | 6 | let playpause_btn = document.querySelector(".playpause-track"); 7 | let next_btn = document.querySelector(".next-track"); 8 | let prev_btn = document.querySelector(".prev-track"); 9 | 10 | let seek_slider = document.querySelector(".seek_slider"); 11 | let volume_slider = document.querySelector(".volume_slider"); 12 | let curr_time = document.querySelector(".current-time"); 13 | let total_duration = document.querySelector(".total-duration"); 14 | 15 | let track_index = 0; 16 | let isPlaying = false; 17 | let updateTimer; 18 | 19 | // Create new audio element 20 | let curr_track = document.createElement('audio'); 21 | 22 | // Define the tracks that have to be played 23 | let track_list = [ 24 | { 25 | name: "Night Owl", 26 | artist: "Broke For Free", 27 | image: "https://images.pexels.com/photos/2264753/pexels-photo-2264753.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=250&w=250", 28 | path: "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/WFMU/Broke_For_Free/Directionless_EP/Broke_For_Free_-_01_-_Night_Owl.mp3" 29 | }, 30 | { 31 | name: "Enthusiast", 32 | artist: "Tours", 33 | image: "https://images.pexels.com/photos/3100835/pexels-photo-3100835.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=250&w=250", 34 | path: "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Tours/Enthusiast/Tours_-_01_-_Enthusiast.mp3" 35 | }, 36 | { 37 | name: "Shipping Lanes", 38 | artist: "Chad Crouch", 39 | image: "https://images.pexels.com/photos/1717969/pexels-photo-1717969.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=250&w=250", 40 | path: "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/ccCommunity/Chad_Crouch/Arps/Chad_Crouch_-_Shipping_Lanes.mp3", 41 | }, 42 | ]; 43 | 44 | function random_bg_color() { 45 | 46 | // Get a number between 64 to 256 (for getting lighter colors) 47 | let red = Math.floor(Math.random() * 256) + 64; 48 | let green = Math.floor(Math.random() * 256) + 64; 49 | let blue = Math.floor(Math.random() * 256) + 64; 50 | 51 | // Construct a color withe the given values 52 | let bgColor = "rgb(" + red + "," + green + "," + blue + ")"; 53 | 54 | // Set the background to that color 55 | document.body.style.background = bgColor; 56 | } 57 | 58 | function loadTrack(track_index) { 59 | clearInterval(updateTimer); 60 | resetValues(); 61 | curr_track.src = track_list[track_index].path; 62 | curr_track.load(); 63 | 64 | track_art.style.backgroundImage = "url(" + track_list[track_index].image + ")"; 65 | track_name.textContent = track_list[track_index].name; 66 | track_artist.textContent = track_list[track_index].artist; 67 | now_playing.textContent = "PLAYING " + (track_index + 1) + " OF " + track_list.length; 68 | 69 | updateTimer = setInterval(seekUpdate, 1000); 70 | curr_track.addEventListener("ended", nextTrack); 71 | random_bg_color(); 72 | } 73 | 74 | function resetValues() { 75 | curr_time.textContent = "00:00"; 76 | total_duration.textContent = "00:00"; 77 | seek_slider.value = 0; 78 | } 79 | 80 | // Load the first track in the tracklist 81 | loadTrack(track_index); 82 | 83 | function playpauseTrack() { 84 | if (!isPlaying) playTrack(); 85 | else pauseTrack(); 86 | } 87 | 88 | function playTrack() { 89 | curr_track.play(); 90 | isPlaying = true; 91 | playpause_btn.innerHTML = ''; 92 | } 93 | 94 | function pauseTrack() { 95 | curr_track.pause(); 96 | isPlaying = false; 97 | playpause_btn.innerHTML = '';; 98 | } 99 | 100 | function nextTrack() { 101 | if (track_index < track_list.length - 1) 102 | track_index += 1; 103 | else track_index = 0; 104 | loadTrack(track_index); 105 | playTrack(); 106 | } 107 | 108 | function prevTrack() { 109 | if (track_index > 0) 110 | track_index -= 1; 111 | else track_index = track_list.length; 112 | loadTrack(track_index); 113 | playTrack(); 114 | } 115 | 116 | function seekTo() { 117 | let seekto = curr_track.duration * (seek_slider.value / 100); 118 | curr_track.currentTime = seekto; 119 | } 120 | 121 | function setVolume() { 122 | curr_track.volume = volume_slider.value / 100; 123 | } 124 | 125 | function seekUpdate() { 126 | let seekPosition = 0; 127 | 128 | if (!isNaN(curr_track.duration)) { 129 | seekPosition = curr_track.currentTime * (100 / curr_track.duration); 130 | 131 | seek_slider.value = seekPosition; 132 | 133 | let currentMinutes = Math.floor(curr_track.currentTime / 60); 134 | let currentSeconds = Math.floor(curr_track.currentTime - currentMinutes * 60); 135 | let durationMinutes = Math.floor(curr_track.duration / 60); 136 | let durationSeconds = Math.floor(curr_track.duration - durationMinutes * 60); 137 | 138 | if (currentSeconds < 10) { currentSeconds = "0" + currentSeconds; } 139 | if (durationSeconds < 10) { durationSeconds = "0" + durationSeconds; } 140 | if (currentMinutes < 10) { currentMinutes = "0" + currentMinutes; } 141 | if (durationMinutes < 10) { durationMinutes = "0" + durationMinutes; } 142 | 143 | curr_time.textContent = currentMinutes + ":" + currentSeconds; 144 | total_duration.textContent = durationMinutes + ":" + durationSeconds; 145 | } 146 | } 147 | 148 | 149 | -------------------------------------------------------------------------------- /output/example-music-player.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sayantanm19/js-music-player/09a35351a564a706f01bf1394eb4d12f19c20134/output/example-music-player.mp4 -------------------------------------------------------------------------------- /output/html-css.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sayantanm19/js-music-player/09a35351a564a706f01bf1394eb4d12f19c20134/output/html-css.png -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: lightgreen; 3 | 4 | /* Smoothly transition the background color */ 5 | transition: background-color .5s; 6 | } 7 | 8 | .player { 9 | height: 95vh; 10 | display: flex; 11 | align-items: center; 12 | flex-direction: column; 13 | justify-content: center; 14 | } 15 | 16 | .details { 17 | display: flex; 18 | align-items: center; 19 | flex-direction: column; 20 | justify-content: center; 21 | margin-top: 25px; 22 | } 23 | 24 | .track-art { 25 | margin: 25px; 26 | height: 250px; 27 | width: 250px; 28 | background-image: url("https://images.pexels.com/photos/262034/pexels-photo-262034.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260"); 29 | background-size: cover; 30 | border-radius: 15%; 31 | } 32 | 33 | .now-playing { 34 | font-size: 1rem; 35 | } 36 | 37 | .track-name { 38 | font-size: 3rem; 39 | } 40 | 41 | .track-artist { 42 | font-size: 1.5rem; 43 | } 44 | 45 | .buttons { 46 | display: flex; 47 | flex-direction: row; 48 | align-items: center; 49 | } 50 | 51 | .playpause-track, .prev-track, .next-track { 52 | padding: 25px; 53 | opacity: 0.8; 54 | 55 | /* Smoothly transition the opacity */ 56 | transition: opacity .2s; 57 | } 58 | 59 | .playpause-track:hover, .prev-track:hover, .next-track:hover { 60 | opacity: 1.0; 61 | } 62 | 63 | .slider_container { 64 | width: 75%; 65 | max-width: 400px; 66 | display: flex; 67 | justify-content: center; 68 | align-items: center; 69 | } 70 | 71 | /* Modify the appearance of the slider */ 72 | .seek_slider, .volume_slider { 73 | -webkit-appearance: none; 74 | -moz-appearance: none; 75 | appearance: none; 76 | height: 5px; 77 | background: black; 78 | opacity: 0.7; 79 | -webkit-transition: .2s; 80 | transition: opacity .2s; 81 | } 82 | 83 | /* Modify the appearance of the slider thumb */ 84 | .seek_slider::-webkit-slider-thumb, .volume_slider::-webkit-slider-thumb { 85 | -webkit-appearance: none; 86 | -moz-appearance: none; 87 | appearance: none; 88 | width: 15px; 89 | height: 15px; 90 | background: white; 91 | cursor: pointer; 92 | border-radius: 50%; 93 | } 94 | 95 | .seek_slider:hover, .volume_slider:hover { 96 | opacity: 1.0; 97 | } 98 | 99 | .seek_slider { 100 | width: 60%; 101 | } 102 | 103 | .volume_slider { 104 | width: 30%; 105 | } 106 | 107 | .current-time, .total-duration { 108 | padding: 10px; 109 | } 110 | 111 | i.fa-volume-down, i.fa-volume-up { 112 | padding: 10px; 113 | } 114 | 115 | i.fa-play-circle, i.fa-pause-circle, i.fa-step-forward, i.fa-step-backward { 116 | cursor: pointer; 117 | } --------------------------------------------------------------------------------