分享个V1 哪吒面板添加音乐

我的小哪吒面板:点击打开链接

分享个哪吒面板添加音乐

</style>

<div id="music-player">
    <button id="prev" title="上一首">
        <svg viewBox="0 0 24 24"><path d="M16 19V5l-11 7z"/></svg>
    </button>
    <button id="play-pause" title="播放">
        <svg id="play-icon" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
        <svg id="pause-icon" viewBox="0 0 24 24" style="display:none;">
            <rect x="6" y="5" width="4" height="14"/>
            <rect x="14" y="5" width="4" height="14"/>
        </svg>
    </button>
    <button id="next" title="下一首">
        <svg viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
    </button>
    <span id="song-info">加载中...</span>
</div>

<script>
const songs = [
  {
    "title": "借口 - 周杰伦",
    "src": "https://music.gvrander.eu.org/music/%E5%80%9F%E5%8F%A3-%E5%91%A8%E6%9D%B0%E4%BC%A6.mp3"
  },
  {
    "title": "富士山下 - 陈奕迅",
    "src": "https://music.gvrander.eu.org/music/%E5%AF%8C%E5%A3%AB%E5%B1%B1%E4%B8%8B-%E9%99%88%E5%A5%95%E8%BF%85.mp3"
  },
  {
    "title": "小幸运 - 田馥甄",
    "src": "https://music.gvrander.eu.org/music/%E5%B0%8F%E5%B9%B8%E8%BF%90-%E7%94%B0%E9%A6%A5%E7%94%84.mp3"
  },
  {
    "title": "年少有为 - 李荣浩",
    "src": "https://music.gvrander.eu.org/music/%E5%B9%B4%E5%B0%91%E6%9C%89%E4%B8%BA-%E6%9D%8E%E8%8D%A3%E6%B5%A9.flac"
  },
  {
    "title": "搁浅 - 周杰伦",
    "src": "https://music.gvrander.eu.org/music/%E6%90%81%E6%B5%85-%E5%91%A8%E6%9D%B0%E4%BC%A6.flac"
  },
  {
    "title": "晴天 - 周杰伦",
    "src": "https://music.gvrander.eu.org/music/%E6%99%B4%E5%A4%A9%20-%20%E5%91%A8%E6%9D%B0%E4%BC%A6.mp3"
  },
  {
    "title": "最长的电影 - 周杰伦",
    "src": "https://music.gvrander.eu.org/music/%E6%9C%80%E9%95%BF%E7%9A%84%E7%94%B5%E5%BD%B1-%E5%91%A8%E6%9D%B0%E4%BC%A6.mp3"
  },
  {
    "title": "海阔天空 - Beyond",
    "src": "https://music.gvrander.eu.org/music/%E6%B5%B7%E9%98%94%E5%A4%A9%E7%A9%BA-Beyond.mp3"
  },
  {
    "title": "童话 - 光良",
    "src": "https://music.gvrander.eu.org/music/%E7%AB%A5%E8%AF%9D-%E5%85%89%E8%89%AF.flac"
  },
  {
    "title": "第一次 - 光良",
    "src": "https://music.gvrander.eu.org/music/%E7%AC%AC%E4%B8%80%E6%AC%A1-%E5%85%89%E8%89%AF.mp3"
  },
  {
    "title": "说好不哭 - 周杰伦with阿信",
    "src": "https://music.gvrander.eu.org/music/%E8%AF%B4%E5%A5%BD%E4%B8%8D%E5%93%AD-%E5%91%A8%E6%9D%B0%E4%BC%A6with%E9%98%BF%E4%BF%A1.flac"
  },
  {
    "title": "说好的幸福呢 - 周杰伦",
    "src": "https://music.gvrander.eu.org/music/%E8%AF%B4%E5%A5%BD%E7%9A%84%E5%B9%B8%E7%A6%8F%E5%91%A2-%E5%91%A8%E6%9D%B0%E4%BC%A6.flac"
  }
];

// 每次刷新页面随机一首
let currentSongIndex = Math.floor(Math.random() * songs.length);
let audio = null;
let isPlaying = false;
let hasInteracted = false;

function updateButtonState() {
    document.getElementById('play-icon').style.display = isPlaying ? 'none' : 'block';
    document.getElementById('pause-icon').style.display = isPlaying ? 'block' : 'none';
    document.getElementById('play-pause').title = isPlaying ? '暂停' : '播放';
}

function updateSongInfo() {
    document.getElementById('song-info').textContent = songs[currentSongIndex]?.title || '未知音轨';
}

function initAudio() {
    if (!audio) {
        audio = new Audio();
        audio.preload = "auto";
        audio.addEventListener('ended', () => {
            let nextIndex;
            do {
                nextIndex = Math.floor(Math.random() * songs.length);
            } while (nextIndex === currentSongIndex && songs.length > 1);
            currentSongIndex = nextIndex;
            loadAndPlay(true);
        });
        audio.addEventListener('play', () => { isPlaying = true; updateButtonState(); });
        audio.addEventListener('pause', () => { isPlaying = false; updateButtonState(); });
    }
}

async function loadAndPlay(autoplay = true) {
    try {
        initAudio();
        if (audio.src !== songs[currentSongIndex].src) {
            audio.src = songs[currentSongIndex].src;
            await new Promise((resolve, reject) => {
                audio.addEventListener('loadedmetadata', resolve, { once: true });
                audio.addEventListener('error', reject, { once: true });
            });
        }
        updateSongInfo();
        if (autoplay) await audio.play();
    } catch (err) {
        console.log("播放失败:", err);
        isPlaying = false;
        updateButtonState();
        document.getElementById('song-info').textContent = '播放失败,换首试试';
    }
}

async function togglePlayPause() {
    if (!audio) return;
    try {
        audio.paused ? await audio.play() : audio.pause();
    } catch (err) {
        console.log("播放控制失败:", err);
    }
}

function playOnFirstInteraction() {
    if (hasInteracted) return;
    hasInteracted = true;
    window.removeEventListener('click', playOnFirstInteraction);
    window.removeEventListener('keydown', playOnFirstInteraction);
    loadAndPlay(true);
}

window.addEventListener('click', playOnFirstInteraction, { once: true });
window.addEventListener('keydown', playOnFirstInteraction, { once: true });

window.addEventListener('load', () => {
    initAudio();
    updateSongInfo();
    updateButtonState();
});

document.getElementById("play-pause").addEventListener("click", togglePlayPause);
document.getElementById("next").addEventListener("click", async () => {
    let nextIndex;
    do {
        nextIndex = Math.floor(Math.random() * songs.length);
    } while (nextIndex === currentSongIndex && songs.length > 1);
    currentSongIndex = nextIndex;
    await loadAndPlay(true);
});
document.getElementById("prev").addEventListener("click", async () => {
    let prevIndex;
    do {
        prevIndex = Math.floor(Math.random() * songs.length);
    } while (prevIndex === currentSongIndex && songs.length > 1);
    currentSongIndex = prevIndex;
    await loadAndPlay(true);
});
</script>

响应老友要求再修改一版。

位置固定在浏览器左下角,靠左边缘,点击按钮展开播放器。

<style>
#music-container {
  position: fixed;
  left: 0;
  bottom: 20px;
  display: flex;
  align-items: center;
  background: #222;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 0 6px rgba(0,0,0,0.7);
  transition: width 0.3s ease;
  width: 18px;
  height: 50px; 
  z-index: 9999;
  font-family: "微软雅黑", Arial, sans-serif;
  font-size: 9px;
}

#music-container.expanded {
  width: 190px;
  height: 50px;
}

#toggle-btn {
  width: 18px;
  height: 50px;  
  background: #333;
  border: none;
  outline: none;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 0;
  order: 2;
  flex-shrink: 0; 
  z-index: 10;    
}

#toggle-btn svg {
  fill: #fff;
  width: 11px;
  height: 11px;
  transition: transform 0.3s ease;
}

#toggle-btn.collapsed svg {
  transform: rotate(0deg);
}

#toggle-btn.expanded svg {
  transform: rotate(180deg);
}

#music-player {
  flex: 1 1 auto;  
  display: none;
  flex-direction: row;
  align-items: center;
  padding: 4px 6px;
  color: #eee;
  white-space: nowrap;
  order: 1;
  user-select: none;
  overflow: hidden; 
}

#music-container.expanded #music-player {
  display: flex;
}

#music-player button {
  background: #444;
  border: none;
  color: #eee;
  padding: 4px 5px; 
  margin: 0 2px;
  border-radius: 3px;
  cursor: pointer;
  height: 32px; 
  flex-shrink: 0;
}
#music-player button svg {
  width: 11px;
  height: 11px;
  fill: #eee;
}

#song-info {
  margin-left: 8px;
  max-width: 110px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 10px;
}
</style>

<div id="music-container" class="collapsed" aria-label="音乐播放器容器">
  <button id="toggle-btn" class="collapsed" title="展开播放器" aria-label="展开音乐播放器">
    <svg viewBox="0 0 24 24"><path d="M8 5l8 7-8 7z"/></svg>
  </button>
  <div id="music-player" aria-label="音乐播放器">
    <button id="prev" title="上一首" aria-label="上一首">
      <svg viewBox="0 0 24 24"><path d="M16 19V5l-11 7z"/></svg>
    </button>
    <button id="play-pause" title="播放" aria-label="播放/暂停">
      <svg id="play-icon" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
      <svg id="pause-icon" viewBox="0 0 24 24" style="display:none;">
        <rect x="6" y="5" width="4" height="14"/>
        <rect x="14" y="5" width="4" height="14"/>
      </svg>
    </button>
    <button id="next" title="下一首" aria-label="下一首">
      <svg viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
    </button>
    <span id="song-info">加载中...</span>
  </div>
</div>

<script>
  const toggleBtn = document.getElementById('toggle-btn');
  const musicContainer = document.getElementById('music-container');

  toggleBtn.addEventListener('click', () => {
    const isExpanded = musicContainer.classList.toggle('expanded');
    if (isExpanded) {
      musicContainer.classList.remove('collapsed');
      toggleBtn.classList.remove('collapsed');
      toggleBtn.classList.add('expanded');
      toggleBtn.title = "收起播放器";
      toggleBtn.setAttribute('aria-label', '收起音乐播放器');
    } else {
      musicContainer.classList.remove('expanded');
      musicContainer.classList.add('collapsed');
      toggleBtn.classList.remove('expanded');
      toggleBtn.classList.add('collapsed');
      toggleBtn.title = "展开播放器";
      toggleBtn.setAttribute('aria-label', '展开音乐播放器');
    }
  });

  // 播放列表示例,这里只放了1首,替换为你的列表即可
  const songs = [
    {
      "title": "说好的幸福呢 - 周杰伦",
      "src": "https://music.gvrander.eu.org/music/%E8%AF%B4%E5%A5%BD%E7%9A%84%E5%B9%B8%E7%A6%8F%E5%91%A2-%E5%91%A8%E6%9D%B0%E4%BC%A6.flac"
    }
  ];

  let currentSongIndex = Math.floor(Math.random() * songs.length);
  let audio = null;
  let isPlaying = false;
  let hasInteracted = false;

  function updateButtonState() {
      document.getElementById('play-icon').style.display = isPlaying ? 'none' : 'block';
      document.getElementById('pause-icon').style.display = isPlaying ? 'block' : 'none';
      document.getElementById('play-pause').title = isPlaying ? '暂停' : '播放';
  }

  function updateSongInfo() {
      document.getElementById('song-info').textContent = songs[currentSongIndex]?.title || '未知音轨';
  }

  function initAudio() {
      if (!audio) {
          audio = new Audio();
          audio.preload = "auto";
          audio.addEventListener('ended', () => {
              let nextIndex;
              do {
                  nextIndex = Math.floor(Math.random() * songs.length);
              } while (nextIndex === currentSongIndex && songs.length > 1);
              currentSongIndex = nextIndex;
              loadAndPlay(true);
          });
          audio.addEventListener('play', () => { isPlaying = true; updateButtonState(); });
          audio.addEventListener('pause', () => { isPlaying = false; updateButtonState(); });
      }
  }

  async function loadAndPlay(autoplay = true) {
      try {
          initAudio();
          if (audio.src !== songs[currentSongIndex].src) {
              audio.src = songs[currentSongIndex].src;
              await new Promise((resolve, reject) => {
                  audio.addEventListener('loadedmetadata', resolve, { once: true });
                  audio.addEventListener('error', reject, { once: true });
              });
          }
          updateSongInfo();
          if (autoplay) await audio.play();
      } catch (err) {
          console.log("播放失败:", err);
          isPlaying = false;
          updateButtonState();
          document.getElementById('song-info').textContent = '播放失败,换首试试';
      }
  }

  async function togglePlayPause() {
      if (!audio) return;
      try {
          audio.paused ? await audio.play() : audio.pause();
      } catch (err) {
          console.log("播放控制失败:", err);
      }
  }

  function playOnFirstInteraction() {
      if (hasInteracted) return;
      hasInteracted = true;
      window.removeEventListener('click', playOnFirstInteraction);
      window.removeEventListener('keydown', playOnFirstInteraction);
      loadAndPlay(true);
  }

  window.addEventListener('click', playOnFirstInteraction, { once: true });
  window.addEventListener('keydown', playOnFirstInteraction, { once: true });

  window.addEventListener('load', () => {
      initAudio();
      updateSongInfo();
      updateButtonState();
  });

  document.getElementById("play-pause").addEventListener("click", togglePlayPause);
  document.getElementById("next").addEventListener("click", async () => {
      let nextIndex;
      do {
          nextIndex = Math.floor(Math.random() * songs.length);
      } while (nextIndex === currentSongIndex && songs.length > 1);
      currentSongIndex = nextIndex;
      await loadAndPlay(true);
  });
  document.getElementById("prev").addEventListener("click", async () => {
      let prevIndex;
      do {
          prevIndex = Math.floor(Math.random() * songs.length);
      } while (prevIndex === currentSongIndex && songs.length > 1);
      currentSongIndex = prevIndex;
      await loadAndPlay(true);
  });
</script>
3 个赞

看看好用不,支持一下

正好需要,感谢

学习一下

看看2

学习一下

操作这么骚的吗

我天!我在上班打开的,是个大光腚 :xhj43:

看看呢

看看

就问你爱不爱看

学习一下

图爱看