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

vue实现atm

Vue实现ATM机模拟功能 使用Vue.js实现ATM机模拟功能需要结合组件化开发、状态管理以及用户交互逻辑。以下是关键实现步骤: 核心组件结构 创建以下Vue组件构建ATM界面: Car…

vue异步组建实现原理

vue异步组建实现原理

Vue 异步组件实现原理 Vue 的异步组件允许将组件按需加载,通常用于代码分割或延迟加载非关键组件。其核心原理基于 Promise 和动态导入。 基本实现方式 通过 defineAsyncComp…

vue实现签约合作弹窗

vue实现签约合作弹窗

实现签约合作弹窗的步骤 使用Vue实现签约合作弹窗可以通过组件化方式完成,结合模态框和表单交互逻辑。以下是具体实现方法: 1. 创建弹窗组件 新建一个Vue组件文件(如SignContractDia…

vue实现关键词轮播

vue实现关键词轮播

Vue 实现关键词轮播 基础实现方案 使用 Vue 的 v-for 和 setInterval 实现基础轮播效果: <template> <div class="keyword…

vue实现矩阵

vue实现矩阵

Vue 实现矩阵的方法 在 Vue 中实现矩阵操作可以通过多种方式完成,以下是一些常见的方法: 使用二维数组表示矩阵 矩阵可以用二维数组来表示,每个元素对应矩阵中的一个值。在 Vue 的 data…

vue实现iframe

vue实现iframe

Vue 中实现 iframe 的方法 在 Vue 项目中,可以通过多种方式实现 iframe 的嵌入。以下是几种常见的方法: 使用原生 HTML iframe 标签 直接在 Vue 组件的模板中使…