包详细信息

kashi

lucasmc641.3kGPL-3.0-only1.1.3

Singing at the top of my lungs

lyrics, song, lrc, music

自述文件

GitLabNPMCDNKo-fi

Kashi

🎤 Kashi

🎯 Goal

This project is a dependency-free library that aims to provide a way to correctly read, format, structure, and display song lyrics.

📜 Features

  • [x] 🎵 Process and list song lyrics in .lrc files
  • [x] 💪 Supports both directly inputting the .lrc file and a URL that returns it
  • [x] ✉️ Implements the Observer pattern and emits events at each step of the process whenever something changes
  • [x] ✏️ Allows you to enter custom text when the lyrics line is empty
  • [ ] 🎤 Synchronizes the lyrics with the music that is playing
  • [ ] 🎩 Supports multiple lyrics for the same song (useful to keep track of the original lyrics and their translation)
  • [ ] 🧞 Supports the Walaoke extension#Walaoke_extension)
  • [ ] 🕖️ Supports the A2 extension#A2extension(Enhanced_LRC_format))

🎨 How to use it in my project?

🙌 Classic scripts

The project is also exported using UMD, which means that all variables and classes such as the Kashi class is exposed globally, and can be used in any script imported after the library.

Note: You should change X.Y.Z to the library version number according to your needs, this is just an example. It is recommended to always use the latest version.

It is recommended that you pin to the latest stable version of the lib. However, if you always want to use the latest version, you can also use latest instead of a predefined version number. Be careful though, breaking changes may be introduced and your project may need to adapt to the changes.

<!DOCTYPE html>

<html>
  <head>
    <!-- ... -->
    <script src="https://unpkg.com/kashi@X.Y.Z/kashi.js" defer></script>
    <!-- ... -->
  </head>

  <body>
    <div id="kashi"></div>
  </body>
</html>
"use strict";

// Using the file or using a url, both works fine
new Kashi({
  // url, // Public link that returns the file when a GET request is made OR...
  file. // Loaded from an input[type="file"] or anywhere else
  container: document.getElementById("kashi"),
});

📦️ ES6 Modules

The HTML is very similar to the classic scripts version, just change the .js extension to .mjs (and maybe will be necessary to adds a type="module" too), which will result in something similar to this:

Note: Please read the previous section to get the details involved in importing and choosing a package version, they are the same here.

<script
  src="https://unpkg.com/kashi@X.Y.Z/kashi.mjs"
  type="module"
  defer
></script>
import { Kashi } from "kashi";

// Usage is essentially the same as in the previous section

// Using the file or using a url, both works fine
new Kashi({
  // url, // Public link that returns the file when a GET request is made OR...
  file. // Loaded from an input[type="file"] or anywhere else
  container: document.getElementById("kashi"),
});

⚛️ React

Install the lib using your favorite package manager.

npm install kashi

Since the library was designed primarily to be used with vanilla JS, a helper component needs to be created to encapsulate Kashi's behavior and make it simple to reuse throughout the application.

Note: There is TypeScript support, and even if your project doesn't use the JS superset, it should help VSCode and other editors provide autocomplete/code suggestions.

import { useEffect, useRef } from "react";
import { Kashi, KashiProps } from "kashi";

// Example using Vite, React and TypeScript
export const KashiWrapper = (props: KashiProps) => {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (ref.current) {
      new Kashi({
        ...props,
        container: ref.current,
      });
    }

    return () => {
      // Required to avoid duplication when React is in Strict Mode
      if (ref.current) {
        ref.current.innerHTML = "";
      }
    };
  }, [ref.current]);

  return <div className="kashi-wrapper" ref={ref} />;
};

🧐 Constructor properties

You must pass some properties to Kashi to define what lyrics display and where. Here are its specifications:

Property Type Default value Is required? Description
file Blob (or File) - No Lyrics file
url string - No Lyrics url
container HTMLDivElement - Yes Element where the lyrics will be inserted
emptyLineText string 🎝 No Custom text for empty lines of the lyrics

Neither file nor url are “mandatory”, but at least one of these properties must be specified, otherwise an error will be thrown.

👾 Generated HTML structure

The div#kashi represents the container passed to Kashi where the song lyrics will be inserted.

Each line of lyrics present in the lrc file will be wrapped by a <p></p> tag and inserted into the container.

Here's an example:

<div id="kashi">
  <!-- ... -->
  <p>Binkusu no sake wo todoke ni yuku yo</p>
  <p>Umikaze kimakase namimakase</p>
  <p>Shio no mukou de yuuhi mo sawagu</p>
  <p>Sora nya wa wo kaku tori no uta</p>
  <!-- ... -->
</div>

📂 Methods and attributes

The instance generated by Kashi has some public methods and attributes that can be used to query or change properties on the fly.

Name Type Description
url Attribute Returns the url from the current lyrics if it was fetched from a link
file Attribute Returns the file from the current lyrics
emptyLineText Attribute Returns the default text set for empty lines
setUrl Method Function capable of changing the current lyrics file by passing the url of the new file
setFile Method Function capable of changing the current lyrics file by passing the the new file
setEmptyLineText Method Function capable of changing the text defined for empty lines
subscribe Method Function capable of defining a callback to be executed when a given event is triggered
unsubscribe Method Function capable of making a callback to stop listening to an event
notify Method Function capable of triggering an event

🍾 Events

When creating a new instance using Kashi you will have access to the subscribe, unsubscribe and notify methods, these methods can be used respectively to listen for an event, stop listening for an event and manually trigger an event. Below is the list of events triggered internally:

Event Data Trigger
urlSet { url: string } When instantiating by informing url or calling the setUrl method
fileSet { file: Blob } When instantiating or calling the setFile method (when calling the setUrl method the file will be fetched and the setFile method called)
emptyLineTextSet { emptyLineText: string } When instantiating by informing emptyLineText or calling the setEmptyLineText method
lyricLinesUpdated { lyricLines: string[] } When inserting/updating lyrics in HTML

🤔 How do I run the project on my machine?

The first step is to clone the project, either via terminal or even by downloading the compressed file (.zip). After that, go ahead.

🛠️ Requirements

✨ Running the project

With the dependencies properly installed, still in the terminal, run npm start.

Create a simple demo project using vanilla HTML/JS and use the files in the dist folder for testing.

You can also create a demo project using React and use npm link.

🎉 If everything went well...

Now you are running the project beautifully!

✏️ License

This project is under the GPL v3 license. See the LICENSE for more information.


Made with 💙 by lucasmc64 👋 Get in touch!