2个彼此独立的音频播放器
2 Audio Players Independently from each other
我正在尝试改编来自 codepen.io 的某人的代码,该代码制作了这个漂亮的视觉音频播放器播放列表。我想要实现的目标是在单个页面上包含多个这样的内容,因为原始代码只支持一个。我试图弄清楚如何让这些音频播放器按照自己的意愿行事,而不是当我按下一个播放器时它会暂停前一个播放器,反之亦然。目前,问题是它们都共享相同的音频控件,我正试图找出一种方法来针对每个音频播放器进行唯一定位。
我已经尝试了几天,所以我正在寻求帮助。您将在下面的 codepen.io 中看到,我最初的想法是将音频播放器的每个 div 包装在其自己独特的 div 中。然后在 JS 中,调用 div 的数组,并使用 forEach 为每个 div 上的音频播放列表迭代 JS 函数。我知道我的功能或者我的方法有问题,我很乐意得到一些反馈和指导。
目前,我只有两个音频播放器可以开始使用,所以我什至可以看看我的想法是否有效。现在他们都访问相同的 songs/album 翻唱,但是我只是想先弄清楚如何让他们以不同的方式演奏,然后再弄清楚其余的东西哈哈。如果您也注意到这个问题,我们深表歉意。
2 Audio Players Independently -- Codepen.io
最后,我正在使用一些 AHK 脚本和 Edge/IE 来实现它,所以我暂时不得不使用 Legacy JS。
谢谢。干杯!
这是 JS 的代码,以防您不想访问 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()
})
})
好吧,我已经弄明白为什么玩家不独立玩了,这似乎与某种类型的 JS 范围问题有关,以及音频变量是如何在 init
中分配的功能。我仍然不确定为什么,但似乎创建的每个音频播放器都引用了完全相同的音频实例。
如果你改变了两件事,那么它应该适合你。
首先,在立即调用的函数表达式的最开始,声明一个音频变量,设置为空。
$(function () {
let audio, playerTrack = $(
musicPlayer.audioPlayer + " > #app-cover > #player > #player-track"
),
...rest of code
接下来,进入 init
函数,并将代码更改为:
// audio = new Audio()
audio = document.createElement("audio")
对此:
audio = new Audio()
这让我很烦,因为理论上应该为每个实例分配一个新的音频实例,但显然没有。无论如何......这应该让你朝着正确的方向前进。
我正在尝试改编来自 codepen.io 的某人的代码,该代码制作了这个漂亮的视觉音频播放器播放列表。我想要实现的目标是在单个页面上包含多个这样的内容,因为原始代码只支持一个。我试图弄清楚如何让这些音频播放器按照自己的意愿行事,而不是当我按下一个播放器时它会暂停前一个播放器,反之亦然。目前,问题是它们都共享相同的音频控件,我正试图找出一种方法来针对每个音频播放器进行唯一定位。
我已经尝试了几天,所以我正在寻求帮助。您将在下面的 codepen.io 中看到,我最初的想法是将音频播放器的每个 div 包装在其自己独特的 div 中。然后在 JS 中,调用 div 的数组,并使用 forEach 为每个 div 上的音频播放列表迭代 JS 函数。我知道我的功能或者我的方法有问题,我很乐意得到一些反馈和指导。
目前,我只有两个音频播放器可以开始使用,所以我什至可以看看我的想法是否有效。现在他们都访问相同的 songs/album 翻唱,但是我只是想先弄清楚如何让他们以不同的方式演奏,然后再弄清楚其余的东西哈哈。如果您也注意到这个问题,我们深表歉意。
2 Audio Players Independently -- Codepen.io
最后,我正在使用一些 AHK 脚本和 Edge/IE 来实现它,所以我暂时不得不使用 Legacy JS。
谢谢。干杯!
这是 JS 的代码,以防您不想访问 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()
})
})
好吧,我已经弄明白为什么玩家不独立玩了,这似乎与某种类型的 JS 范围问题有关,以及音频变量是如何在 init
中分配的功能。我仍然不确定为什么,但似乎创建的每个音频播放器都引用了完全相同的音频实例。
如果你改变了两件事,那么它应该适合你。
首先,在立即调用的函数表达式的最开始,声明一个音频变量,设置为空。
$(function () {
let audio, playerTrack = $(
musicPlayer.audioPlayer + " > #app-cover > #player > #player-track"
),
...rest of code
接下来,进入 init
函数,并将代码更改为:
// audio = new Audio()
audio = document.createElement("audio")
对此:
audio = new Audio()
这让我很烦,因为理论上应该为每个实例分配一个新的音频实例,但显然没有。无论如何......这应该让你朝着正确的方向前进。