当前位置:首页 > JavaScript

js实现歌词同步

2026-04-04 05:21:35JavaScript

歌词同步的基本原理

歌词同步的核心是将歌词文本与音频时间轴匹配,根据当前播放时间动态高亮显示对应歌词。通常需要解析LRC格式的歌词文件(包含时间标签),并监听音频播放进度。

解析LRC歌词格式

LRC歌词格式示例:

[00:00.00]歌曲名
[00:01.50]第一句歌词
[00:04.30]第二句歌词

解析函数示例:

function parseLRC(lrcText) {
  const lines = lrcText.split('\n');
  const result = [];

  lines.forEach(line => {
    const timeTags = line.match(/\[(\d{2}):(\d{2})\.(\d{2})\]/g);
    const text = line.replace(/\[.*?\]/g, '').trim();

    if (timeTags && text) {
      timeTags.forEach(tag => {
        const minutes = parseInt(tag.match(/\[(\d{2}):/)[1]);
        const seconds = parseInt(tag.match(/:(\d{2})\./)[1]);
        const milliseconds = parseInt(tag.match(/\.(\d{2})\]/)[1]);
        const time = minutes * 60 + seconds + milliseconds / 100;
        result.push({ time, text });
      });
    }
  });

  return result.sort((a, b) => a.time - b.time);
}

实现歌词同步渲染

创建歌词渲染函数,根据当前播放时间更新显示:

function setupLyricSync(audioElement, lrcData, container) {
  let currentLine = 0;

  audioElement.addEventListener('timeupdate', () => {
    const currentTime = audioElement.currentTime;

    while (currentLine < lrcData.length - 1 && 
           currentTime >= lrcData[currentLine + 1].time) {
      currentLine++;
    }

    while (currentLine > 0 && currentTime < lrcData[currentLine].time) {
      currentLine--;
    }

    renderLyrics(lrcData, currentLine, container);
  });
}

function renderLyrics(lrcData, currentLine, container) {
  container.innerHTML = '';

  lrcData.forEach((line, index) => {
    const p = document.createElement('p');
    p.textContent = line.text;
    p.className = index === currentLine ? 'active' : '';
    container.appendChild(p);
  });
}

CSS样式增强

添加基础样式提升视觉效果:

.lyrics-container {
  text-align: center;
  line-height: 2;
  font-size: 16px;
}

.lyrics-container p.active {
  color: #1db954;
  font-size: 18px;
  font-weight: bold;
}

完整使用示例

// 获取DOM元素
const audio = document.getElementById('audio-player');
const lyricsContainer = document.getElementById('lyrics-container');

// 模拟LRC歌词数据
const lrcText = `
[00:01.50]这是第一句歌词
[00:04.30]这是第二句歌词
[00:07.20]这是第三句歌词
`;

// 解析并设置同步
const lrcData = parseLRC(lrcText);
setupLyricSync(audio, lrcData, lyricsContainer);

高级优化建议

添加平滑滚动效果,使当前歌词始终保持在可视区域中间位置:

function renderLyrics(lrcData, currentLine, container) {
  container.innerHTML = '';
  let activeElement = null;

  lrcData.forEach((line, index) => {
    const p = document.createElement('p');
    p.textContent = line.text;
    if (index === currentLine) {
      p.className = 'active';
      activeElement = p;
    }
    container.appendChild(p);
  });

  if (activeElement) {
    activeElement.scrollIntoView({
      behavior: 'smooth',
      block: 'center'
    });
  }
}

处理无歌词情况

添加占位提示提升用户体验:

js实现歌词同步

function renderLyrics(lrcData, currentLine, container) {
  if (!lrcData.length) {
    container.innerHTML = '<p class="no-lyrics">暂无歌词</p>';
    return;
  }
  // ...原有渲染逻辑
}

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

相关文章

js实现轮播图

js实现轮播图

基础轮播图实现 使用HTML、CSS和JavaScript实现一个简单的自动轮播图。HTML结构包含一个容器和多个图片项。 <div class="slider"> <div…

js实现全屏

js实现全屏

实现全屏的基本方法 使用JavaScript实现全屏功能主要依赖Element.requestFullscreen()方法。现代浏览器均支持此API,但不同浏览器可能需要添加前缀。 // 触发全屏…

js如何实现继承

js如何实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例能够访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

js实现百叶窗

js实现百叶窗

使用CSS和JavaScript实现百叶窗效果 通过CSS动画和JavaScript事件监听可以实现百叶窗效果。核心思路是将内容区域分割为多个条状元素,通过控制它们的展开/折叠状态来模拟百叶窗。…

js实现交换

js实现交换

交换变量的方法 在JavaScript中,交换两个变量的值有多种方法。以下是常见的几种实现方式: 使用临时变量 通过引入一个临时变量来存储其中一个变量的值,实现交换: let a = 1; le…

js实现视口

js实现视口

js实现视口检测的方法 使用JavaScript检测元素是否进入视口(viewport)可以通过Intersection Observer API或手动计算元素位置实现。以下是两种常见方法: Int…