当前位置:首页 > VUE

vue实现歌词同步

2026-01-17 18:29:30VUE

实现歌词同步的基本思路

歌词同步的核心是将歌词文本与音频时间轴匹配,通过解析歌词文件(如LRC格式)获取时间戳和歌词内容,在播放时根据当前时间动态高亮显示对应歌词。

解析歌词文件

LRC格式的歌词文件通常包含时间戳和歌词文本,例如:

[00:00.00] 歌曲名
[00:01.00] 第一句歌词
[00:03.50] 第二句歌词

解析方法:

vue实现歌词同步

function parseLrc(lrcText) {
  const lines = lrcText.split('\n')
  const result = []
  for (let line of lines) {
    const parts = line.split(']')
    const timeStr = parts[0].substring(1)
    const obj = {
      time: parseTime(timeStr),
      words: parts[1]
    }
    result.push(obj)
  }
  return result
}

function parseTime(timeStr) {
  const parts = timeStr.split(':')
  return +parts[0] * 60 + +parts[1]
}

歌词组件实现

创建Lyric.vue组件:

<template>
  <div class="lyric-container">
    <ul ref="lyricList">
      <li 
        v-for="(line, index) in lyricLines" 
        :key="index"
        :class="{ active: currentLine === index }"
      >
        {{ line.words }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  props: {
    lrcText: String,
    currentTime: Number
  },
  data() {
    return {
      lyricLines: [],
      currentLine: 0
    }
  },
  watch: {
    lrcText: {
      immediate: true,
      handler(val) {
        this.lyricLines = this.parseLrc(val)
      }
    },
    currentTime(newTime) {
      this.findCurrentLine(newTime)
    }
  },
  methods: {
    parseLrc(lrcText) {
      // 使用上面的解析函数
    },
    findCurrentLine(time) {
      for (let i = 0; i < this.lyricLines.length; i++) {
        if (time < this.lyricLines[i].time) {
          this.currentLine = i - 1
          this.scrollToCurrentLine()
          return
        }
      }
    },
    scrollToCurrentLine() {
      const container = this.$refs.lyricList
      const activeItem = container.children[this.currentLine]
      if (activeItem) {
        container.scrollTop = activeItem.offsetTop - container.offsetHeight / 2
      }
    }
  }
}
</script>

<style>
.lyric-container {
  height: 300px;
  overflow-y: auto;
}
.active {
  color: #ff0000;
  font-weight: bold;
}
</style>

与音频播放器集成

在父组件中使用:

vue实现歌词同步

<template>
  <div>
    <audio 
      ref="audioPlayer"
      :src="audioSrc"
      @timeupdate="handleTimeUpdate"
    ></audio>
    <Lyric :lrc-text="lrcText" :current-time="currentTime" />
  </div>
</template>

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

export default {
  components: { Lyric },
  data() {
    return {
      audioSrc: 'your-audio-file.mp3',
      lrcText: '', // 从API或文件加载歌词
      currentTime: 0
    }
  },
  methods: {
    handleTimeUpdate() {
      this.currentTime = this.$refs.audioPlayer.currentTime
    }
  }
}
</script>

性能优化

对于长歌词列表,考虑虚拟滚动技术减少DOM渲染压力。可使用vue-virtual-scroller等库实现:

<template>
  <RecycleScroller
    class="lyric-container"
    :items="lyricLines"
    :item-size="50"
    key-field="time"
    v-slot="{ item, index }"
  >
    <li :class="{ active: currentLine === index }">
      {{ item.words }}
    </li>
  </RecycleScroller>
</template>

处理复杂歌词格式

对于双语歌词或带翻译的歌词,解析时需要额外处理:

[00:01.00] 原文歌词
[00:01.00](trans) 翻译歌词

解析时可创建多语言支持的数据结构:

{
  time: 1.00,
  original: "原文歌词",
  translation: "翻译歌词"
}

标签: 歌词同步vue
分享给朋友:

相关文章

vue菜单实现

vue菜单实现

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

vue实现setinterval

vue实现setinterval

在 Vue 中使用 setInterval Vue 中可以通过生命周期钩子和方法结合 setInterval 实现定时任务。以下是一个完整的实现示例: <template> <…

vue实现购票

vue实现购票

Vue 实现购票功能 数据结构设计 购票功能通常需要以下数据结构: 场次信息(时间、地点、价格) 座位信息(可选座位、已售座位) 用户订单信息 示例数据结构: data() { return…

vue实现定时

vue实现定时

Vue 实现定时功能的方法 使用 setInterval 和 clearInterval 在 Vue 中可以通过 setInterval 和 clearInterval 实现定时功能。在组件的 mou…

vue实现selectable

vue实现selectable

Vue 实现可选择的 Select 组件 在 Vue 中实现一个可选择的 Select 组件,可以通过以下几种方式: 使用原生 HTML select 元素 <template>…

vue多选实现

vue多选实现

Vue 多选实现方法 基础实现(v-model + multiple) 在 Vue 中实现多选可以通过 <select> 元素的 multiple 属性结合 v-model 完成。v-mo…