当前位置:首页 > VUE

vue实现歌词同步

2026-01-17 18:29:30VUE

实现歌词同步的基本思路

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

解析歌词文件

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

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

解析方法:

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>

与音频播放器集成

在父组件中使用:

<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) 翻译歌词

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

vue实现歌词同步

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

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

相关文章

vue实现视窗

vue实现视窗

Vue 实现视窗功能 在 Vue 中实现视窗功能通常涉及监听浏览器窗口大小变化、响应式布局或创建自定义弹窗组件。以下是几种常见实现方式: 监听浏览器窗口大小变化 使用 Vue 的 mounted 和…

vue实现旋转

vue实现旋转

Vue 实现旋转效果的方法 在 Vue 中实现旋转效果可以通过多种方式完成,以下是几种常见的方法: 使用 CSS 动画 通过 Vue 的 :class 或 :style 绑定 CSS 动画实现旋转效…

vue权限实现

vue权限实现

Vue 权限实现方案 基于路由的权限控制 通过路由守卫实现权限验证,在路由配置中添加meta字段标记权限要求。在router.beforeEach中检查用户权限与路由要求的匹配情况。 // rout…

vue实现刷卡

vue实现刷卡

Vue 实现刷卡效果 在 Vue 中实现刷卡效果可以通过 CSS 动画和 Vue 的过渡系统结合完成。以下是一种常见的实现方式: 基础实现方法 安装 Vue 过渡依赖(如果尚未安装): npm i…

vue实现标注

vue实现标注

Vue 实现标注功能的方法 使用 Vue 实现标注功能可以通过多种方式实现,以下介绍几种常见的方法: 1. 使用 HTML5 Canvas 实现标注 Canvas 提供了强大的绘图能力,适合实现复…

vue实现openoffice

vue实现openoffice

Vue 中集成 OpenOffice 的实现方法 在 Vue 项目中集成 OpenOffice 通常需要通过后端服务或现有库实现文档的预览和编辑功能。以下是几种常见的实现方式: 使用 OnlyOff…