当前位置:首页 > VUE

vue音乐播放实现

2026-03-08 06:13:35VUE

Vue 音乐播放实现

基础播放器组件

创建一个基础的音频播放器组件,使用 HTML5 的 <audio> 元素,结合 Vue 的数据绑定和控制方法。

<template>
  <div class="audio-player">
    <audio ref="audio" :src="currentSong.url" @timeupdate="updateTime"></audio>
    <div class="controls">
      <button @click="togglePlay">{{ isPlaying ? '暂停' : '播放' }}</button>
      <input type="range" v-model="currentTime" max="100" @input="seek">
      <span>{{ formatTime(currentTime) }} / {{ formatTime(duration) }}</span>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      currentSong: {
        url: 'https://example.com/song.mp3',
        title: '示例歌曲'
      },
      isPlaying: false,
      currentTime: 0,
      duration: 0
    }
  },
  methods: {
    togglePlay() {
      const audio = this.$refs.audio
      this.isPlaying ? audio.pause() : audio.play()
      this.isPlaying = !this.isPlaying
    },
    updateTime() {
      const audio = this.$refs.audio
      this.currentTime = (audio.currentTime / audio.duration) * 100
      this.duration = audio.duration
    },
    seek(e) {
      const audio = this.$refs.audio
      const seekTime = (e.target.value / 100) * audio.duration
      audio.currentTime = seekTime
    },
    formatTime(seconds) {
      const mins = Math.floor(seconds / 60)
      const secs = Math.floor(seconds % 60)
      return `${mins}:${secs < 10 ? '0' : ''}${secs}`
    }
  }
}
</script>

播放列表管理

实现一个播放列表功能,允许用户切换歌曲。

<template>
  <div>
    <ul class="playlist">
      <li v-for="(song, index) in playlist" :key="index" @click="playSong(index)">
        {{ song.title }}
      </li>
    </ul>
    <audio-player :currentSong="currentSong" ref="player"></audio-player>
  </div>
</template>

<script>
import AudioPlayer from './AudioPlayer.vue'

export default {
  components: { AudioPlayer },
  data() {
    return {
      playlist: [
        { url: 'https://example.com/song1.mp3', title: '歌曲1' },
        { url: 'https://example.com/song2.mp3', title: '歌曲2' }
      ],
      currentSong: {},
      currentIndex: 0
    }
  },
  created() {
    this.currentSong = this.playlist[0]
  },
  methods: {
    playSong(index) {
      this.currentIndex = index
      this.currentSong = this.playlist[index]
      this.$nextTick(() => {
        this.$refs.player.togglePlay()
      })
    }
  }
}
</script>

音频可视化

使用 Web Audio API 实现音频可视化效果。

methods: {
  setupVisualizer() {
    const audioContext = new (window.AudioContext || window.webkitAudioContext)()
    const analyser = audioContext.createAnalyser()
    const source = audioContext.createMediaElementSource(this.$refs.audio)

    source.connect(analyser)
    analyser.connect(audioContext.destination)
    analyser.fftSize = 256

    const bufferLength = analyser.frequencyBinCount
    const dataArray = new Uint8Array(bufferLength)

    const canvas = this.$refs.canvas
    const ctx = canvas.getContext('2d')

    function draw() {
      requestAnimationFrame(draw)
      analyser.getByteFrequencyData(dataArray)

      ctx.fillStyle = 'rgb(0, 0, 0)'
      ctx.fillRect(0, 0, canvas.width, canvas.height)

      const barWidth = (canvas.width / bufferLength) * 2.5
      let x = 0

      for(let i = 0; i < bufferLength; i++) {
        const barHeight = dataArray[i] / 2
        ctx.fillStyle = `rgb(${barHeight + 100}, 50, 50)`
        ctx.fillRect(x, canvas.height - barHeight, barWidth, barHeight)
        x += barWidth + 1
      }
    }

    draw()
  }
}

响应式设计

确保播放器在不同设备上都能良好显示。

.audio-player {
  max-width: 500px;
  margin: 0 auto;
  padding: 20px;
  background: #f5f5f5;
  border-radius: 8px;
}

.controls {
  display: flex;
  align-items: center;
  gap: 10px;
}

input[type="range"] {
  flex-grow: 1;
}

.playlist {
  list-style: none;
  padding: 0;
}

.playlist li {
  padding: 10px;
  cursor: pointer;
  border-bottom: 1px solid #eee;
}

.playlist li:hover {
  background: #f0f0f0;
}

canvas {
  width: 100%;
  height: 100px;
  margin-top: 20px;
}

进阶功能

添加歌词同步功能,需要准备时间戳标记的歌词文件。

methods: {
  loadLyrics() {
    fetch('lyrics.json')
      .then(response => response.json())
      .then(data => {
        this.lyrics = data
        this.startLyricsSync()
      })
  },
  startLyricsSync() {
    this.lyricsInterval = setInterval(() => {
      const currentTime = this.$refs.audio.currentTime
      this.currentLyric = this.lyrics.find(line => 
        currentTime >= line.time && currentTime < line.time + line.duration
      )?.text || ''
    }, 100)
  }
}

性能优化

使用懒加载技术,仅在需要时加载音频文件。

vue音乐播放实现

methods: {
  playSong(index) {
    if (!this.playlist[index].loaded) {
      this.loadSong(index).then(() => {
        this.playLoadedSong(index)
      })
    } else {
      this.playLoadedSong(index)
    }
  },
  loadSong(index) {
    return new Promise(resolve => {
      const audio = new Audio()
      audio.src = this.playlist[index].url
      audio.addEventListener('canplaythrough', () => {
        this.playlist[index].loaded = true
        resolve()
      })
    })
  }
}

标签: 音乐播放vue
分享给朋友:

相关文章

vue实现目录

vue实现目录

Vue 实现目录功能 在 Vue 中实现目录功能通常需要动态生成目录结构,并支持点击跳转到对应内容区域。以下是几种常见实现方式: 基于滚动监听和动态生成 安装依赖(如需): npm install…

vue实现裁剪头像

vue实现裁剪头像

Vue 实现头像裁剪功能 实现头像裁剪功能通常需要结合第三方库如 cropperjs 或 vue-cropper。以下是两种常见实现方式: 使用 vue-cropper 库 安装依赖: npm i…

vue评分实现

vue评分实现

Vue 评分组件实现方法 使用第三方库(如 Element UI) 安装 Element UI: npm install element-ui 引入并注册组件: import Vue from '…

vue菜单实现

vue菜单实现

Vue 菜单实现方法 使用 Element UI 的菜单组件 Element UI 提供了现成的菜单组件,适合快速实现导航菜单。安装 Element UI 后,可以直接使用 el-menu 相关组件。…

vue实现keepalive

vue实现keepalive

Vue 中实现 keep-alive 在 Vue 中,keep-alive 是一个内置组件,用于缓存动态组件或组件的状态,避免重复渲染和销毁。以下是实现 keep-alive 的几种方法: 基本用法…

vue实现webshell

vue实现webshell

Vue 实现 WebShell 使用 Vue 实现 WebShell 需要结合前端与后端的交互,通常通过 WebSocket 或 HTTP 协议与服务器通信。以下是一个基于 Vue 和 WebSock…