logo
0
0
WeChat Login

LRC 歌词播放器 - 复刻实现

项目说明

这个项目复刻了一个 Vue 网站的 LRC 歌词显示功能,提取了核心的 CSS 样式和交互逻辑,实现了纯原生 HTML/CSS/JavaScript 版本。

文件结构

/workspace/ ├── lyric-player.css # 提取的核心样式 ├── lyric-player.html # 主页面 ├── lyric-player.js # 核心逻辑实现 └── README-LYRIC-PLAYER.md # 使用说明

核心功能

1. 多格式歌词解析

  • LRC: [mm:ss.xx]歌词
  • VTT: WebVTT 标准格式
  • SRT: 字幕标准格式

2. 歌词播放同步

  • 实时根据音频时间高亮当前歌词
  • 自动滚动到当前播放位置
  • 平滑滚动动画

3. 交互功能

  • 点击歌词跳转到对应时间
  • 播放/暂停控制
  • 时间偏移调整(+/- 0.3s 快速调整,+/- 0.1s 精确调整)
  • 重置偏移功能

4. 响应式设计

  • 移动端适配
  • iOS 安全区域适配
  • 平台特定样式优化

技术实现

CSS 核心样式

布局系统

/* 主容器 - 80vh 高度,固定在视口中 */ .lyric-layout { height: 80vh; overflow: hidden; } /* 滚动容器 - 支持触摸滚动 */ .scroll { overflow-y: auto; -webkit-overflow-scrolling: touch; }

移动端适配

/* Android/iOS 对话框高度适配 */ body.platform-android:not(.native-mobile) .q-dialog__inner--minimized > div, body.platform-ios .q-dialog__inner--minimized > div { max-height: calc(100vh - 108px); }

歌词高亮

.q-item.active { background-color: rgba(25, 118, 210, 0.1); animation: pulse 2s infinite; } @keyframes pulse { 0%, 100% { background-color: rgba(25, 118, 210, 0.1); } 50% { background-color: rgba(25, 118, 210, 0.2); } }

JavaScript 核心逻辑

1. LRC 解析器

parseLRC(lrcText) { const pattern = /\[(\d{2}):(\d{2})\.(\d{2,3})\](.*)/; // 解析时间戳和歌词文本 // 返回排序后的歌词数组 }

2. 歌词同步

syncLyrics() { const currentTime = this.audioElement.currentTime + this.offset; const newIndex = this.getCurrentLyricIndex(currentTime); if (newIndex !== this.currentIndex) { this.highlightLyric(newIndex); this.scrollToActiveLyric(); } }

3. 自动滚动

scrollToActiveLyric() { const containerHeight = container.clientHeight; const itemTop = activeItem.offsetTop; const itemHeight = activeItem.clientHeight; const scrollTop = itemTop - containerHeight / 2 + itemHeight / 2; container.scrollTo({ top: scrollTop, behavior: 'smooth' }); }

使用方法

基础使用

  1. 在浏览器中打开 lyric-player.html
  2. 点击顶部的文件选择器
  3. 选择 LRC/VTT/SRT 文件
  4. 如果需要播放功能,关联音频元素

关联音频元素

// 方法1:在页面中添加 audio 元素 <audio id="my-audio" src="music.mp3"></audio> // 方法2:在 JavaScript 中设置 const audioElement = document.getElementById('my-audio'); window.lyricPlayer.setAudioElement(audioElement);

API 参考

构造函数

const player = new LyricPlayer({ audioElement: document.querySelector('audio'), lyricListElement: document.getElementById('lyric-list'), playBtnElement: document.getElementById('play-btn'), offsetInputElement: document.getElementById('offset-input'), fileNameElement: document.getElementById('file-name') });

主要方法

  • parseLRC(text) - 解析 LRC 格式
  • parseVTT(text) - 解析 VTT 格式
  • parseSRT(text) - 解析 SRT 格式
  • renderLyrics() - 渲染歌词列表
  • syncLyrics() - 同步歌词高亮
  • jumpToLyric(index) - 跳转到指定歌词
  • adjustOffset(delta) - 调整时间偏移
  • resetOffset() - 重置偏移
  • togglePlay() - 切换播放/暂停

样式定制

自定义颜色

修改 CSS 中的变量和颜色值:

/* 当前歌词高亮颜色 */ .q-item.active { background-color: rgba(25, 118, 210, 0.1); /* 蓝色 */ color: #1976d2; }

自定义字体

.q-item__label { font-size: 14px; font-family: 'Your Custom Font', sans-serif; }

自定义动画

@keyframes custom-pulse { 0% { opacity: 1; } 50% { opacity: 0.7; } 100% { opacity: 1; } } .q-item.active { animation: custom-pulse 2s infinite; }

移植到其他平台

React 版本

核心思路:

  1. 使用 useEffect 监听音频 timeupdate 事件
  2. 使用 useState 管理当前歌词索引
  3. 使用 useRef 实现自动滚动

Vue 版本

核心思路:

  1. 使用 watch 监听音频时间
  2. 使用 computed 计算当前歌词
  3. 使用 nextTick 确保滚动动画

Android Compose 版本

核心思路:

  1. 使用 LaunchedEffect 监听音频播放
  2. 使用 LazyColumn + items 渲染歌词列表
  3. 使用 rememberScrollState 实现自动滚动

Flutter 版本

核心思路:

  1. 使用 StreamBuilder 监听音频流
  2. 使用 ListView.builder 渲染歌词
  3. 使用 ScrollController 实现自动滚动

性能优化建议

  1. 虚拟滚动: 歌词数量过多时使用虚拟滚动
  2. 防抖处理: 频繁的 timeupdate 事件进行节流
  3. 索引缓存: 缓存当前歌词索引,避免重复计算
  4. 懒加载: 按需加载歌词文件

浏览器兼容性

  • Chrome/Edge: ✅ 完全支持
  • Firefox: ✅ 完全支持
  • Safari: ✅ 完全支持(iOS 需要安全区域适配)
  • Mobile Safari: ✅ 支持
  • Chrome Mobile: ✅ 支持

已知问题

  1. 长时间暂停后重新播放可能需要手动同步
  2. 某些特殊格式的 LRC 文件可能需要调整正则表达式
  3. 音频和歌词文件需要手动关联

许可证

本项目基于原网站样式提取,仅供学习参考使用。

贡献

欢迎提交 Issue 和 Pull Request!