자바스크립트 가사 싱크로나이저

하이 나는 Anam 👋이고 이것은 나의 첫 번째 기사입니다 ☺️

이 기사에서는 처음부터 자바스크립트로 간단한 가사 싱크로나이저를 만드는 실험을 할 것입니다.

시작하자 🚀

LRC 파일



시작하기 전에 (*.lrc) 파일에 대해 알아야 합니다.

LRC (short for LyRiCs) is a computer file format that synchronizes song lyrics with an audio file, such as MP3, Vorbis or MIDI.
wikipedia



lrc 파일 형식 예:

[ar:Lyrics artist]
[al:Album where the song is from]
[ti:Lyrics (song) title]
[00:12.00]Line 1 lyrics
[00:17.20]Line 2 lyrics
[00:21.10]Line 3 lyrics


the lrc file has several variants, the example above is a simple variant.



lrc 파일 형식은 매우 간단합니다.
  • 1~3행은 id tags 또는 가사 앞에 표시되는 메타데이터
  • 입니다.
  • 4 - 6행은 대괄호로 묶인 타임스탬프가 있는 가사입니다. 사용된 시간 형식은 mm:ss.xx:
  • 입니다.
  • mm: 분
  • ss: 초
  • xx: 1/100초

  • 다음으로 우리는 javascript로 간단한 lrc 파서를 만들 것입니다.

    LRC 파서



    이전 예제를 기반으로 lrc 파일은 두 부분으로 구성됩니다.
  • ID 태그
  • 가사

  • 하지만 지금은 id 태그를 무시하고 가사에만 집중합니다.

    코딩 시간 👩‍💻

    // lrc (String) - lrc file text
    function parseLyric(lrc) {
        // will match "[00:00.00] ooooh yeah!"
        // note: i use named capturing group
        const regex = /^\[(?<time>\d{2}:\d{2}(.\d{2})?)\](?<text>.*)/;
    
        // split lrc string to individual lines
        const lines = lrc.split("\n");
    
        const output = [];
    
        lines.forEach(line => {
            const match = line.match(regex);
    
            // if doesn't match, return.
            if (match == null) return;
    
            const { time, text } = match.groups;
    
            output.push({
                time: parseTime(time),
                text: text.trim()
            });
        });
    
        // parse formated time
        // "03:24.73" => 204.73 (total time in seconds)
        function parseTime(time) {
            const minsec = time.split(":");
    
            const min = parseInt(minsec[0]) * 60;
            const sec = parseFloat(minsec[1]);
    
            return min + sec;
        }
    
        return output;
    }
    


    위의 함수는 정규 표현식을 사용하여 시간과 텍스트를 분리하고 객체 배열로 출력을 반환합니다.

    출력은 다음과 같습니다.

    [
        {
            text: "Faith you're driving me away",
            time: "21.16"
        },
        ...
    ]
    


    동기화 가사



    다음 작업은 가사를 동기화하는 것입니다.

    우리가 사용할 방법은 주어진 시간에 가장 가까운 가사의 타임스탬프를 찾는 것입니다. 다른 방법이 있다면 댓글로 알려주세요😻

    // lyrics (Array) - output from parseLyric function
    // time (Number) - current time from audio player
    function syncLyric(lyrics, time) {
        const scores = [];
    
        lyrics.forEach(lyric => {
            // get the gap or distance or we call it score
            const score = time - lyric.time;
    
            // only accept score with positive values
            if (score >= 0) scores.push(score);
        });
    
        if (scores.length == 0) return null;
    
        // get the smallest value from scores
        const closest = Math.min(...scores);
    
        // return the index of closest lyric
        return scores.indexOf(closest);
    }
    


    간단한 음악 플레이어



    이제 파서와 동기화라는 두 가지 필수 기능이 있습니다.

    실시간 가사 동기화로 간단한 음악 플레이어를 구축할 시간입니다 🤸

    index.html

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <title>Simple music player with lyric</title>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="style.css">
    </head>
    
    <body>
        <audio class="player" controls></audio>
        <div class="lyric"></div>
        <script src="script.js"></script>
    </body>
    
    </html>
    


    스타일.css

    * {
        box-sizing: border-box;
    }
    
    html {
        font-family: sans-serif;
        font-size: 16px;
        color: hsl(200, 20%, 25%);
    }
    
    body {
        width: 100vw;
        height: 100vh;
        margin: 0;
        padding: 40px;
        display: flex;
        flex-direction: column;
        align-items: center;
    }
    
    .lyric {
        font-size: 2rem;
        font-weight: bolder;
        line-height: 1.5;
        text-align: center;
        text-transform: uppercase;
        max-width: 300px;
        margin-top: 40px;
    }
    
    .player {
        width: 100%;
        max-width: 300px;
    }
    


    script.js

    !async function main() {
        "use strict";
    
        const dom = {
            lyric: document.querySelector(".lyric"),
            player: document.querySelector(".player")
        };
    
        // load lrc file
        const res = await fetch("./lyric.lrc");
        const lrc = await res.text();
    
        const lyrics = parseLyric(lrc);
    
        dom.player.src = "./audio.mp3";
    
        dom.player.ontimeupdate = () => {
            const time = dom.player.currentTime;
            const index = syncLyric(lyrics, time);
    
            if (index == null) return;
    
            dom.lyric.innerHTML = lyrics[index].text;
        };
    
    }();
    
    function parseLyric(lrc) {
        // same as previous code
    }
    
    function syncLyric(lyrics, time) {
        // same as previous code
    }
    


    결과:



    결론



    이 실험에서 우리는 lrc 파일이 무엇인지, 자바 스크립트를 사용하여 파일을 구문 분석하고 노래와 동기화하는 방법을 배웁니다.

    다음으로, 당신은 훨씬 멋진 🤩 자신만의 음악 플레이어 버전을 만들 수 있습니다.

    아 한 가지 더, liricle이라는 이 실험을 기반으로 간단한 자바스크립트 라이브러리를 만들었습니다. github에서 확인할 수 있습니다. 자유롭게 별표 표시 또는 포크 👉👈 농담 😅

    읽어주셔서 대단히 감사합니다. 주저하지 마시고 의견, 비판 또는 제안을 남겨주세요. 정말 감사하겠습니다 ☺️

    좋은 웹페이지 즐겨찾기