I'm trying to adapt someone's code from codepen.io that made this pretty visual audio player playlist. My goal I want to achieve is to have multiple of these on a single page since the original code only supported one. I'm trying to figure out how to get these audio players to behave on their own accord rather than, when I press play on one it will pause the previous or vice versa. At the moment, the problem is that they're all sharing the same audio controls and I'm trying to figure out a way to target each audio player uniquely.
Been trying at this for a couple days so I'm reaching out for help. My initial thought which you'll see in the codepen.io below was to wrap each div of the audio player in its own unique div. Then in JS, call an array of the divs and with forEach iterate the JS function for the audio playlist on each div. I know there is something wrong with my functions or perhaps my approach in general and I would love to have some feedback and direction.
Currently, I have just two audio players to start with so I can even see if my idea is working. Right now their both accessing the same songs/album covers, however I just wanted to figure out how to get them to play differently first before figuring out the rest of the stuff haha. So apologies if you notice that problem too.
2 Audio Players Independently -- Codepen.io
Lastly, I'm implementing this with some AHK scripts & Edge/IE, so I'm forced for the time being to use Legacy JS.
Thank you. Cheers!
Here is the code for the JS in case you don't want to visit codepen.io.
let musicPlayers = [
{
audioPlayer: ".audio-1",
trackInfo: [
{
song: "https://raw.githubusercontent.com/himalayasingh/music-player-1/master/music/1.mp3",
title: "Dawn",
album: "Skylike - Dawn",
art: "https://raw.githubusercontent.com/himalayasingh/music-player-1/master/img/_1.jpg",
},
{
song: "https://raw.githubusercontent.com/himalayasingh/music-player-1/master/music/2.mp3",
title: "Me & You",
album: "Alex Skrindo - Me & You",
art: "https://raw.githubusercontent.com/himalayasingh/music-player-1/master/img/_2.jpg",
},
],
},
{
audioPlayer: ".audio-2",
trackInfo: [
{
song: "https://raw.githubusercontent.com/himalayasingh/music-player-1/master/music/3.mp3",
title: "Electro Boy",
album: "Kaaze - Electro Boy",
art: "https://raw.githubusercontent.com/himalayasingh/music-player-1/master/img/_3.jpg",
},
{
song: "https://raw.githubusercontent.com/himalayasingh/music-player-1/master/music/4.mp3",
title: "Home",
album: "Martin Garrix - Home",
art: "https://raw.githubusercontent.com/himalayasingh/music-player-1/master/img/_5.jpg",
},
],
},
]
console.log("number of audio players:", musicPlayers.length)
musicPlayers.forEach(function (musicPlayer, index) {
let tracksObj = { song: [], title: [], album: [], art: [] }
musicPlayer.trackInfo.forEach(function (track) {
tracksObj.song.push(track.song)
tracksObj.title.push(track.title)
tracksObj.album.push(track.album)
tracksObj.art.push(track.art)
})
console.log(tracksObj.art)
// console.log(index, musicPlayer.trackInfo[0].song)
$(function () {
let playerTrack = $(
musicPlayer.audioPlayer + " > #app-cover > #player > #player-track"
),
bgArtwork = $(musicPlayer.audioPlayer + " > #app-cover > #bg-artwork"),
bgArtworkUrl,
albumName = playerTrack.children("#album-name"),
trackName = playerTrack.children("#track-name"),
trackTime = playerTrack.children("#track-time"),
tProgress = trackTime.children("#current-time"),
tTime = trackTime.children("#track-length"),
sArea = playerTrack.children("#s-area"),
insTime = sArea.children("#ins-time"),
sHover = sArea.children("#s-hover"),
seekBar = sArea.children("#seek-bar"),
playerContent = $(
musicPlayer.audioPlayer + " > #app-cover > #player > #player-content"
),
albumArt = playerContent.children("#album-art"),
playerControls = playerContent.children("#player-controls"),
playPauseButton = playerControls
.children(".control")
.children("#play-pause-button"),
i = playPauseButton.find("i"),
seekT,
seekLoc,
seekBarPos,
cM,
ctMinutes,
ctSeconds,
curMinutes,
curSeconds,
durMinutes,
durSeconds,
playProgress,
bTime,
nTime = 0,
buffInterval = null,
tFlag = false,
albums = tracksObj.album,
trackNames = tracksObj.title,
albumArtworks = tracksObj.art,
trackUrl = tracksObj.song,
playPreviousTrackButton = playerControls
.children(".control")
.children("#play-previous"),
playNextTrackButton = playerControls
.children(".control")
.children("#play-next"),
currIndex = -1
function playPause() {
setTimeout(function () {
if (audio.paused) {
playerTrack.addClass("active")
albumArt.addClass("active")
checkBuffering()
i.attr("class", "fas fa-pause")
audio.play()
console.log(currIndex)
} else {
playerTrack.removeClass("active")
albumArt.removeClass("active")
clearInterval(buffInterval)
albumArt.removeClass("buffering")
i.attr("class", "fas fa-play")
audio.pause()
}
}, 300)
}
function showHover(event) {
seekBarPos = sArea.offset()
seekT = event.clientX - seekBarPos.left
seekLoc = audio.duration * (seekT / sArea.outerWidth())
sHover.width(seekT)
cM = seekLoc / 60
ctMinutes = Math.floor(cM)
ctSeconds = Math.floor(seekLoc - ctMinutes * 60)
if (ctMinutes < 0 || ctSeconds < 0) return
if (ctMinutes < 0 || ctSeconds < 0) return
if (ctMinutes < 10) ctMinutes = "0" + ctMinutes
if (ctSeconds < 10) ctSeconds = "0" + ctSeconds
if (isNaN(ctMinutes) || isNaN(ctSeconds)) insTime.text("--:--")
else insTime.text(ctMinutes + ":" + ctSeconds)
insTime.css({ left: seekT, "margin-left": "-21px" }).fadeIn(0)
}
function hideHover() {
sHover.width(0)
insTime
.text("00:00")
.css({ left: "0px", "margin-left": "0px" })
.fadeOut(0)
}
function playFromClickedPos() {
audio.currentTime = seekLoc
seekBar.width(seekT)
hideHover()
}
function updateCurrTime() {
nTime = new Date()
nTime = nTime.getTime()
if (!tFlag) {
tFlag = true
trackTime.addClass("active")
}
curMinutes = Math.floor(audio.currentTime / 60)
curSeconds = Math.floor(audio.currentTime - curMinutes * 60)
durMinutes = Math.floor(audio.duration / 60)
durSeconds = Math.floor(audio.duration - durMinutes * 60)
playProgress = (audio.currentTime / audio.duration) * 100
if (curMinutes < 10) curMinutes = "0" + curMinutes
if (curSeconds < 10) curSeconds = "0" + curSeconds
if (durMinutes < 10) durMinutes = "0" + durMinutes
if (durSeconds < 10) durSeconds = "0" + durSeconds
if (isNaN(curMinutes) || isNaN(curSeconds)) tProgress.text("00:00")
else tProgress.text(curMinutes + ":" + curSeconds)
if (isNaN(durMinutes) || isNaN(durSeconds)) tTime.text("00:00")
else tTime.text(durMinutes + ":" + durSeconds)
if (
isNaN(curMinutes) ||
isNaN(curSeconds) ||
isNaN(durMinutes) ||
isNaN(durSeconds)
)
trackTime.removeClass("active")
else trackTime.addClass("active")
seekBar.width(playProgress + "%")
if (playProgress == 100) {
i.attr("class", "fa fa-play")
seekBar.width(0)
tProgress.text("00:00")
albumArt.removeClass("buffering").removeClass("active")
clearInterval(buffInterval)
}
}
function checkBuffering() {
clearInterval(buffInterval)
buffInterval = setInterval(function () {
if (nTime == 0 || bTime - nTime > 1000) albumArt.addClass("buffering")
else albumArt.removeClass("buffering")
bTime = new Date()
bTime = bTime.getTime()
}, 100)
}
function selectTrack(flag) {
// console.log("flag = ", flag)
if (flag == 0 || flag == 1) ++currIndex
else --currIndex
if (currIndex > -1 && currIndex < albumArtworks.length) {
if (flag == 0) i.attr("class", "fa fa-play")
else {
albumArt.removeClass("buffering")
i.attr("class", "fa fa-pause")
}
seekBar.width(0)
trackTime.removeClass("active")
tProgress.text("00:00")
tTime.text("00:00")
currAlbum = albums[currIndex]
currTrackName = trackNames[currIndex]
currArtwork = albumArtworks[currIndex]
audio.src = trackUrl[currIndex]
nTime = 0
bTime = new Date()
bTime = bTime.getTime()
if (flag != 0) {
audio.play()
playerTrack.addClass("active")
albumArt.addClass("active")
clearInterval(buffInterval)
checkBuffering()
}
albumName.text(currAlbum)
trackName.text(currTrackName)
albumArt.find("img.active").removeClass("active")
albumArt.find("#current-album-art").addClass("active")
albumArt.find("img.active").attr("src", currArtwork)
bgArtworkUrl = albumArt.find("img.active").attr("src")
bgArtwork.css({ "background-image": "url(" + bgArtworkUrl + ")" })
} else {
if (flag == 0 || flag == 1) --currIndex
else ++currIndex
}
}
function initPlayer() {
// audio = new Audio()
audio = document.createElement("audio")
selectTrack(0)
audio.loop = false
playPauseButton.on("click", playPause)
sArea.mousemove(function (event) {
showHover(event)
})
sArea.mouseout(hideHover)
sArea.on("click", playFromClickedPos)
$(audio).on("timeupdate", updateCurrTime)
playPreviousTrackButton.on("click", function () {
selectTrack(-1)
console.log(currIndex)
})
playNextTrackButton.on("click", function () {
selectTrack(1)
})
}
initPlayer()
})
})
Alright, I've figured out why the players won't play independently, and it seems to be related to some type of JS scoping issue, and how the audio variable was being assigned in the init
function. I'm still not exactly sure why, but it seems as every audio player created was referencing the same exact audio instance.
If you change two things, then it should work for you.
First, at the very beginning of the immediately invoked function expression, declare an audio variable, set to nothing.
$(function () {
let audio, playerTrack = $(
musicPlayer.audioPlayer + " > #app-cover > #player > #player-track"
),
...rest of code
Next, go into the init
function, and change the code from this:
// audio = new Audio()
audio = document.createElement("audio")
to this:
audio = new Audio()
This is bugging me, because in theory it looks like a new audio instance should have been assigned to each, but apparently not. Anyways...this should get you headed in the right direction.