lyrics.ovh 에서 제공하는 API를 이용하면 음악 정보 서비스나 배경음을 서비스할 수 있습니다. 배경음을 온라인에서 실시간으로 재생할 수 있고, 다운로드 서비스도 제공하지만 SSL를 제공하지 않기 때문에 HTTP 환경에서만 올바로 작동합니다.

다만 영어로만 검색이 가능합니다. 예를 들어 가수 "아이유"를 조회하고 싶다면 "IU"라고 조회해야 합니다. 

먼저 CSS 파일을 만들어야 합니다.


/* eg. assets/css/style.css */

* {
    box-sizing: border-box
}

body {
    background-color: black;
    font-family: "Source Sans Pro", sans-serif;
    margin: 0
}

button {
    cursor: pointer
}

button:active {
    transform: scale(0.95)
}

input:focus,
button:focus {
    outline: none
}

header {
    background-image: url("https://wallpaperaccess.com/full/1580344.jpg");
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center center;
    color: white;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 100px 0;
    position: relative
}

header * {
    z-index: 1
}

h1 {
    margin: 0 0 30px;
    font-size: 40px;
    font-weight: 700!important;
    text-shadow: 5px 5px 10px black
}

form {
    position: relative;
    width: 500px;
    max-width: 100%
}

form input {
    border: 0;
    outline: 0;
    border-radius: 50px;
    font-size: 16px;
    padding: 15px 30px;
    width: 100%
}

form button {
    background-color: black;
    border: 0;
    border-radius: 50px;
    color: white;
    font-size: 16px;
    padding: 13px 30px;
    position: absolute;
    top: 2px;
    right: 2px
}

.btn {
    background-color: cyan;
    border: 0;
    border-radius: 10px;
    color: white;
    font-weight: 700;
    padding: 12px 14px;
    transition: ease-out 0.4s
}

.btn:hover {
    box-shadow: inset 400px 0 0 0 #00ffffa4
}

ul.songs {
    list-style-type: none;
    padding: 0
}

ul.songs li {
    display: flex;
    align-items: center;
    justify-content: space-between
}

#form i {
    color: cyan
}

.container {
    padding: 30px auto;
    max-width: 100%;
    background-color: black;
    color: white
}

.container h2 {
    font-weight: 300
}

.container p {
    text-align: center
}

.centered {
    display: flex;
    justify-content: center
}

.centered button {
    transform: scale(1.3);
    margin: 15px
}

footer,
footer a {
    text-align: center;
    color: #fff
}


이제 JS 파일을 만들겠습니다. JS 파일이 핵심이니 CSS나 HTML은 꾸미는 것에 지나지 않습니다.


//eg. assets/js/script.js

const API_URL = "https://api.lyrics.ovh",
    form = document.getElementById("form"),
    search = document.getElementById("search"),
    result = document.getElementById("result"),
    more = document.getElementById("more");
async function getMoreSongs(t) {
    const e = await fetch(`https://cors-anywhere.herokuapp.com/${t}`);
    showSongs(await e.json())
}

function showSongs(t) {
    var e = "";
    t.data.forEach(t => {
        e += `\n    <div style="margin-top:25px;">\n      <li><span><img style="border-radius:50%;" class="song_image" alt="image.jpg" src="${t.artist.picture_small}"/></span><div style="width:300px; text-align:left;"><span><strong>${t.artist.name}</strong> - ${t.title}</span></div>\n      <audio controls width="220" height="30"><source src="${t.preview}"></audio>\n      \x3c!--button class="btn" data-artist="${t.artist.name}" data-songtitle="${t.title}">Get Lyrics</button//--\x3e</li>\n    </div>\n    `
    }), result.innerHTML = `\n  <ul class="songs">\n    ${e}\n  </ul>\n  `, t.prev || t.next ? more.innerHTML = `\n      ${t.prev?`<button class="btn" onClick="getMoreSongs('${t.prev}')"><i class="fa fa-arrow-left"></i></button>`:""}\n      ${t.next?`<button class="btn"  onClick="getMoreSongs('${t.next}')"><i class="fa fa-arrow-right"></i></button>`:""}\n    ` : more.innerHTML = ""
}
async function fetchSearchedSongs(t) {
    const e = await fetch(`${API_URL}/suggest/${t}`),
        n = await e.json();
    console.log(n), showSongs(n)
}
async function getTheLyrics(t, e) {
    const n = await fetch(`${API_URL}/v1/${t}/${e}`),
        s = await n.json();
    if (s.error) result.innerHTML = s.error;
    else {
        const n = s.lyrics.replace(/(\r\n|\r|\n)/g, "<br>");
        result.innerHTML = `\n            <h2><strong>${t}</strong> - ${e}</h2>\n            <span>${n}</span>\n        `
    }
    more.innerHTML = ""
}
form.addEventListener("submit", t => {
    t.preventDefault();
    const e = search.value.trim();
    e ? fetchSearchedSongs(e) : alert("Please enter search element.")
}), result.addEventListener("click", t => {
    const e = t.target;
    if ("BUTTON" === e.tagName) {
        getTheLyrics(e.getAttribute("data-artist"), e.getAttribute("data-songtitle"))
    }
});


코드가 완성되었으니 HTML 파일을 만들어 완성해 보겠습니다.


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Lyrics Search App</title>
  <link rel="stylesheet" href="assets/css/style.css">
  <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.2.0-beta1/css/bootstrap-grid.min.css" />
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
  <header>
    <h1>배경음악 다운로드</h1>
    <form id="form">
      <input type="text" id="search" placeholder="Search...">
      <button><i class="fa fa-search" aria-hidden="true"></i></button>
    </form>
  </header>
  <div class="container" id="result">
    <p><h3 style="text-align:center;"><i class="fa fa-search" aria-hidden="true"></i> 좋아하는 노래를 영문으로 검색하세요.</h3></p>
  </div>
  <div class="container centered mb-5" id="more"></div>

  <script src="assets/js/script.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>


완성된 모습입니다.



0 댓글