惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy International News Feed
Martin Fowler
Martin Fowler
D
Docker
Y
Y Combinator Blog
云风的 BLOG
云风的 BLOG
U
Unit 42
T
Tailwind CSS Blog
J
Java Code Geeks
G
Google Developers Blog
MongoDB | Blog
MongoDB | Blog
阮一峰的网络日志
阮一峰的网络日志
WordPress大学
WordPress大学
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
美团技术团队
F
Fortinet All Blogs
N
News and Events Feed by Topic
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Hacker News - Newest:
Hacker News - Newest: "LLM"
The GitHub Blog
The GitHub Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Recorded Future
Recorded Future
N
Netflix TechBlog - Medium
Google DeepMind News
Google DeepMind News
Hacker News: Ask HN
Hacker News: Ask HN
L
LINUX DO - 最新话题
Microsoft Security Blog
Microsoft Security Blog
N
News and Events Feed by Topic
I
Intezer
TaoSecurity Blog
TaoSecurity Blog
NISL@THU
NISL@THU
小众软件
小众软件
博客园 - 聂微东
博客园 - Franky
有赞技术团队
有赞技术团队
P
Palo Alto Networks Blog
爱范儿
爱范儿
H
Hacker News: Front Page
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Cisco Blogs
P
Proofpoint News Feed
I
InfoQ
Google DeepMind News
Google DeepMind News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Vercel News
Vercel News
H
Heimdal Security Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
量子位

Hyde Blog

Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog 关于我 关于我 Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog
Hyde Blog
Hyde · 2025-10-05 · via Hyde Blog

vue

<script setup lang="ts">
// import '../../lib/iconfont/iconfont';    // vitepress 基于 nodejs 的项目,无法引入需要window对象的模块

import { onMounted, ref } from "vue";
import { ElMessage } from "element-plus";
import PauseMusicController from "./PauseMusicController.vue";
import PlayingMusicController from "./PlayingMusicController.vue";
/**
 *
 * 音乐播放器
 */
const musics = [
  "周杰伦-搁浅.mp3",
  "林俊杰-不潮不用花钱.mp3",
  "林俊杰-可惜没如果.mp3",
  "林俊杰-美人鱼.mp3",
  "林俊杰-修炼爱情.mp3",
  "周杰伦-安静.mp3",
  "周杰伦-不能说的秘密.mp3",
  "周杰伦-彩虹.mp3",
  "周杰伦-断了的弦.mp3",
  "周杰伦-搁浅.mp3",
  "周杰伦-轨迹.mp3",
  "周杰伦-回到过去.mp3",
  "周杰伦-借口.mp3",
  "周杰伦-晴天.mp3",
  "周杰伦-退后.mp3",
];
// 当前音乐
const currentMusic = ref("/music/周杰伦-搁浅.mp3");
// 播放器元素
const audio = ref<HTMLAudioElement | null>();
// 是否播放音乐: 默认: false
const isPlayed = ref(false);
// 播放音乐的随机数字
let random = ref(0);
// 开一个定时器,什么时候需要销毁播放器可以直接清除该查询定时器
let music_palyer_timer = ref<ReturnType<typeof setInterval> | null>();
const playMusic = () => {
  /**
   * 浏览器为什么不能直接播放音乐参考博客:
   * https://blog.csdn.net/s18813688772/article/details/121103802
   */
  isPlayed.value = !isPlayed.value;
  const musicName =
    currentMusic.value
      .split("/")
      .pop()
      ?.replace(/\.mp3$/, "") ?? "未知歌曲";
  ElMessage({
    message: isPlayed.value ? `正在播放: ${musicName}` : `已暂停: ${musicName}`,
    type: isPlayed.value ? "success" : "warning",
    duration: 2000,
  });
  console.log("播放状态: ", isPlayed.value ? "播放" : "不播放");

  if (isPlayed.value) {
    // 如果是播放状态,则播放音乐
    audio.value?.play();
  } else {
    // 如果是暂停状态,则暂停音乐
    audio.value?.pause();

    const handleLoadError = () => {
      ElMessage.error("音乐加载失败,请重试");
    };
  }
};
const generateRandom = () => {
  /**
   * 生成一个与上次的数字不一样的数字
   */
  let tmp: number = Math.floor(Math.random() * musics.length);
  while (tmp === random.value) {
    tmp = Math.floor(Math.random() * musics.length);
  }
  return tmp;
};
onMounted(() => {
  // 挂在完成后给一个随机音乐
  random.value = generateRandom();
  console.log(
    `%c第${random.value + 1}首音乐.`,
    "color: green; font-weight: bolder;"
  );
  currentMusic.value = `/music/${musics[random.value]}`;

  // 提示用户可以播放音乐
  /* setTimeout(() => {
        confirm('点击右侧🎵可以播放音乐哦~');
    }, 100); */

  // 组件挂在完成即开启定时器监听音乐是否播放完成的状态
  music_palyer_timer.value = setInterval(function () {
    // 如果音频播放器获取到了,就监听是否结束的事件
    if (audio.value?.ended) {
      console.log("%c音乐结束, 下一曲~", "color: oranger; font-weight: bold;");
      // 以播放结束的标志判断
      random.value = generateRandom();
      console.log(
        `%c第${random.value}首音乐.`,
        "color: green; font-weight: bolder;"
      );
      currentMusic.value = `/music/${musics[random.value]}`;
      /*audio.value.onended = function () {
                // 以播放结束的事件监听形式控制
                let random: number = Math.floor(Math.random() * musics.length);
                currentMusic.value = `/music/${musics[random]}`;
                console.log('音乐结束, 下一曲~');
            }*/
    }
  }, 1000);
});

/**
 * 播放定时器的清除看情况 ...
 * Todo...
 */
</script>

<template>
  <div class="playMusic-wrapper">
    <button class="playMusic" @click="playMusic">
      <PlayingMusicController v-if="isPlayed" />
      <PauseMusicController v-else />
      <!-- <svg class="icon" aria-hidden="true">
                <use :xlink:href="`#icon-${isPlayed ? 'music' : 'play2'}`"></use>
            </svg> -->
    </button>
    <audio
      ref="audio"
      preload="auto"
      :autoplay="isPlayed"
      :src="currentMusic"
      style="display: none"
      controls
    ></audio>
  </div>
</template>

<style scoped lang="scss">
$PlayControler-width: 20px;
$PlayControler-height: 20px;

.playMusic-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 36px;
  // width: 400px; // 测试
  height: 36px;
  margin: 0 5px;

  .playMusic {
    width: $PlayControler-width;
    height: $PlayControler-width;
    border-radius: 20%;
    font-size: 1.3rem;
    line-height: 1.3rem;

    svg {
      margin: 0;
      padding: 0;
      width: $PlayControler-width;
      height: $PlayControler-width;
    }
  }
}
</style>