当前位置:首页 > 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实现erp

vue实现erp

Vue实现ERP系统的关键步骤 技术选型与架构设计 采用Vue 3 + TypeScript构建前端,搭配Pinia状态管理,Element Plus或Ant Design Vue作为UI框架。后端可…

vue 实现拖动

vue 实现拖动

Vue 实现拖动的几种方法 在Vue中实现拖动功能可以通过多种方式,包括原生HTML5的拖放API、第三方库如vuedraggable等。以下是几种常见的实现方法: 使用HTML5拖放API HTM…

vue 实现单选

vue 实现单选

使用 v-model 绑定单选值 在 Vue 中,可以通过 v-model 绑定单选按钮的值。定义一个响应式数据(如 selectedOption),并将其与单选按钮的 value 属性关联。…

vue实现mouseout

vue实现mouseout

Vue 实现 mouseout 事件的方法 在 Vue 中实现 mouseout 事件可以通过多种方式完成,以下是几种常见的方法: 使用 v-on 指令 Vue 提供了 v-on 指令(或简写为…

vue diff实现

vue diff实现

Vue Diff 算法实现原理 Vue 的虚拟 DOM Diff 算法(即 patch 过程)是其高效渲染的核心,主要通过对比新旧虚拟节点的差异,最小化 DOM 操作。以下是关键实现要点: 同层级比…

vue实现尺子

vue实现尺子

Vue 实现尺子组件 实现一个尺子组件可以通过 Canvas 或纯 CSS 完成。以下是两种常见实现方式: 使用 Canvas 绘制尺子 通过 Canvas 动态绘制刻度线和数字,适合需要高精度…