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()

这让我很烦,因为理论上应该为每个实例分配一个新的音频实例,但显然没有。无论如何......这应该让你朝着正确的方向前进。