npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jyostudio/lyric

v1.0.1

Published

lyric parser and formatter

Readme

English

@jyostudio/lyric

预览

一个纯 TypeScript 实现的歌词解析与渲染组件库,包含:

  • 核心解析与控制模块:dist/lyric.js(默认导出 Lyric,命名导出 LyricController
  • 原生 Web Component:dist/jyo-lyric.js(自定义元素 <jyo-lyric>

支持多种主流歌词格式:LRC、TRC、KRC、KSC、QRC(自动识别优先级:QRC → KRC → KSC → TRC → LRC)。

安装

npm install @jyostudio/lyric
# 或
pnpm add @jyostudio/lyric
# 或
yarn add @jyostudio/lyric

CDN:

  • jsDelivr: https://cdn.jsdelivr.net/npm/@jyostudio/lyric/dist/lyric.js
  • unpkg: https://unpkg.com/@jyostudio/lyric/dist/lyric.js

构建产物为 ESM,适用于现代打包器与浏览器 <script type="module">


快速开始

1) 核心解析与控制(lyric.js

适用于 Node.js(23+)与浏览器。默认导出 Lyric,命名导出 LyricController。该包为 ESM-only。

// ESM
import Lyric, { LyricController } from '@jyostudio/lyric';

// 方式 A:从 URL 直接创建(浏览器)
const lyric = await Lyric.createFromUri('/path/to/foo.lrc');

// 方式 B:从 ArrayBuffer 创建
// Node: 使用 fs 读取 Buffer 并转为 ArrayBuffer
// import { readFile } from 'node:fs/promises';
// const buf = await readFile('foo.krc');
// const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
// const lyric = new Lyric(ab);

// 推进时间(单位:毫秒)并获得当前行/词索引
const { lineIndex, wordIndex } = lyric.setCurrentTime(120_000); // 120s

// 也可用控制器封装(单位:毫秒)
LyricController.updateByTime(lyric, 120_000);

// 渲染用:获取行与词
for (const line of lyric.lines) {
  // line.startTime, line.duration, line.state: 'past'|'current'|'future'
  // line.progress, line.renderProgress
  for (const word of line.words) {
    // word.text, word.duration, word.state, word.progress
  }
}

生成其他格式(导出为 ArrayBuffer):

// 支持:'lrc' | 'trc' | 'qrc' | 'krc' | 'ksc'
const ab = Lyric.generate(lyric, 'lrc');

// 浏览器:下载为文件
const blob = new Blob([ab], { type: 'text/plain;charset=utf-8' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'output.lrc';
a.click();

// Node:写入磁盘
// import { writeFile } from 'node:fs/promises';
// await writeFile('output.lrc', Buffer.from(new Uint8Array(ab)));

辅助:判断一行是否支持逐字(词级时间轴)

import Lyric from '@jyostudio/lyric';

const supports = Lyric.supportsPerWord(lyric.lines[0]); // boolean

2) Web Component(jyo-lyric.js

开箱即用的自定义元素 <jyo-lyric>,负责将 Lyric 的结构渲染到页面,并内置平滑滚动、逐字渐变、拖动回看等交互。

  • 安装后在打包器里直接引入:
// 注册自定义元素(副作用导入即可)
import '@jyostudio/lyric/dist/jyo-lyric.js';
  • 或使用 CDN:
<script type="module" src="https://cdn.jsdelivr.net/npm/@jyostudio/lyric/dist/jyo-lyric.js"></script>
  • 最小示例:
<jyo-lyric id="view" src="/music/foo.lrc" align="center" font-size="24" line-gap="20"
  style="display:block;height:420px;--colorBefore:#42d392;--colorAfter:#ffb347;--colorHighlight:#fff;--colorTranslation:#8a8f95;"></jyo-lyric>
<script type="module">
  const audio = document.querySelector('audio');
  const view = document.getElementById('view');
  // 用 rAF 驱动,保证逐字平滑;注意:组件的 setCurrentTime 接受“秒”
  let raf = 0;
  const tick = () => { view.setCurrentTime(audio.currentTime || 0); raf = requestAnimationFrame(tick); };
  audio.addEventListener('play', () => { cancelAnimationFrame(raf); tick(); });
  audio.addEventListener('pause', () => cancelAnimationFrame(raf));
  audio.addEventListener('seeking', () => view.setCurrentTime(audio.currentTime || 0));
</script>

组件属性(Attributes)

  • src: 歌词文件 URL(支持 .lrc/.trc/.krc/.ksc/.qrc)
  • align: 文本对齐,left|center|right,默认 center
  • font-size: 行字号(px),默认 24
  • line-gap: 行距(px),默认 20
  • scroll-ms: 自动滚动动画时长(ms),默认 280
  • gradient: 是否显示渐变高亮,true|false,默认 true
  • show-lang1: 是否显示主文本,默认 true
  • show-lang2: 是否显示副文本(翻译、第二行),默认 true
  • show-refline: 参考线显隐:true|false,缺省为“交互中自动显示”

公共方法(DOM 实例方法)

  • setColors({ before?, after?, highlight?, translation? }): 设置主题色(对应下方 CSS 变量)
  • loadFromUrl(url: string): 从 URL 加载歌词
  • loadFromText(text: string): 从纯文本加载歌词
  • loadFromBuffer(buf: Uint8Array): 从二进制数据加载歌词
  • clear(): 清空数据
  • setCurrentTime(seconds: number): 设置当前播放时间(单位:秒)
  • scrollToCurrent(immediate?: boolean): 滚动至当前行(可选:是否无动画)

注意:组件的 setCurrentTime 参数是“秒”;若使用核心类 Lyric.setCurrentTime,单位是“毫秒”。

事件(CustomEvent)

  • linechange: { index, previousIndex }
  • wordchange: { lineIndex, index }
  • seeked: { time }(与 setCurrentTime 同步触发)

样式定制

  • CSS 变量:
    • --colorBefore:未播放颜色,默认 #42d392
    • --colorAfter:已播放颜色,默认 #ffb347
    • --colorHighlight:当前高亮颜色,默认 #fff
    • --colorTranslation:翻译文本颜色,默认 #8a8f95
    • --bg:容器背景色
    • --reflineColor:参考线颜色(show-refline 时)
  • Shadow Parts:wrapperinnerrowprimarysecondaryreflinerefslotsref-leftref-centerref-right
  • Slots:beforeafterref-leftref-centerref-right(对齐于参考线,可放置按钮/标签等)

示例:

jyo-lyric::part(row) { letter-spacing: 0.3px; }
jyo-lyric { --bg: #0d0d0d; --reflineColor: rgba(255,255,255,.16); }

在浏览器直接使用(无打包器)

仅用 WebComponent:

<script type="module" src="https://cdn.jsdelivr.net/npm/@jyostudio/lyric/dist/jyo-lyric.js"></script>
<jyo-lyric src="./music/1.lrc" style="display:block;height:420px;"></jyo-lyric>

仅用核心解析:

<script type="module">
  import Lyric from 'https://cdn.jsdelivr.net/npm/@jyostudio/lyric/dist/lyric.js';
  const lyric = await Lyric.createFromUri('./music/1.lrc');
  lyric.setCurrentTime(12_345); // ms
  console.log(lyric.lines[lyric.setCurrentTime(12_345).lineIndex]);
</script>

TypeScript 支持

源码基于 TypeScript 实现,提供完备的类型注释与合理的推断体验。若你在纯 TS 项目中使用,可直接按上文导入。

注:后续版本将补充正式的 .d.ts 声明文件导出,以便编辑器跳转与 API 辅助更完善。


本地开发与示例

  • 安装依赖并构建:
npm install
npm run build
  • 打开示例(建议用任意静态服务器打开 demo/index.html,确保 fetch 可访问资源):
# 任选其一
npx http-server demo
npx serve demo

浏览器访问对应地址即可(示例默认使用 dist/jyo-lyric.js)。


常见问题

  • Q:为什么我在组件里传的是“秒”?

    • A:Web Audio/HTMLAudioElement 的 currentTime 单位是秒,组件为了直连播放器,setCurrentTime 采用秒;核心类与控制器使用毫秒以获得更精细的时间分辨率。
  • Q:如何判断是否支持逐字(词级时间轴)?

    • A:使用静态方法 Lyric.supportsPerWord(line)
  • Q:如何关闭渐变,仅用纯色高亮?

    • A:给组件设置 gradient="false",同时可通过 --colorHighlight 控制当前行/词颜色。

许可

MIT © Jyo Studio