본문 바로가기

카테고리 없음

[HTML, JavaScript] iTunes Search API 활용

iTunes Search API 필요성

 

다음 기획서에 쓰인 바와 같이 버튼을 누르면 무작위로 뉴진스의 노래를 추천하는 기능을 구현하고 싶었습니다. 이와 같은 기능을 구현하기 위해선 뉴진스의 노래 목록이 필요했습니다.

 

var musicList = [ "Attention", "Hype Boy", "Cookie", "Hurt", "OMG", "Ditto", "Zero",
"New Jeans","Super Shy", "ETA", "Cool With You", "Get Up", "ASAP"];

처음에는 뉴진스의 노래 제목을 직접 배열에 넣는 방법을 선택했습니다. 하지만 이는 일일이 넣어야 한다는 번거로움과, 뉴진스가 신곡을 낼 때마다 업데이트해야 한다는 문제점이 있습니다.

 

위와 같은 문제는 외부에서 노래 목록을 가져오면 해결할 수 있었기에, 관련 API를 찾던 중 iTunes에서 Search API를 지원한다는 것을 알게 되었습니다.

 


 

iTunes Search API 구성 - URL

 

iTunes Search API는 iTunes 내 앱, iBook, 영화, 팟캐스트, 음악, 뮤직비디오, 오디오북 및 TV 프로그램과 같은 다양한 콘텐츠의 검색을 지원하는 API입니다.

 

iTunes Search API의 URL 형식은 다음과 같습니다.

https://itunes.apple.com/search?parameterkeyvalue

 

 

앞선 경우는 뉴진스의 노래를 검색하고 싶은 것이니, 이 요청을 URL로 바꾸면 다음과 같은 결과가 나옵니다.

https://itunes.apple.com/lookup?id=1635469693&entity=song

 

 

여기서 id=1635469693은 뉴진스의 아티스트 ID를 의미하는데,

아티스트 ID는 아이튠즈에서 검색함으로써 알 수 있습니다.

 

 

더욱 다양한 검색 예시는 iTunes Search API 공식 사이트를 통해 확인할 수 있습니다.

https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/LookupExamples.html#//apple_ref/doc/uid/TP40017632-CH7-SW1

 


 

iTunes Search API 구성 - JSON

 

위와 같은 URL 요청 시, JSON 형식으로 요청 내용이 반환됩니다.

 

구글 검색창에 직접 URL을 입력하면 txt 파일이 다운로드가 되는데, 이는 JSON이 문자 형식이기 때문입니다. 해당 txt 파일을 열어서 요청 내용을 직접 확인할 수 있습니다.

 

{
"resultCount":36,
"results": [
{"wrapperType":"artist", "artistType":"Artist", 
"artistName":"NewJeans", 
"artistLinkUrl":"https://music.apple.com/us/artist/newjeans/1635469693?uo=4", 
"artistId":1635469693, "primaryGenreName":"K-Pop", "primaryGenreId":51},
{"wrapperType":"track", "kind":"song", "artistId":1635469693, 
"collectionId":1659513441, "trackId":1659513445, "artistName":"NewJeans", 
"collectionName":"NewJeans 'OMG' - Single", "trackName":"OMG", 
"collectionCensoredName":"NewJeans 'OMG' - Single", 
"trackCensoredName":"OMG", 
"artistViewUrl":"https://music.apple.com/us/artist/newjeans/1635469693?uo=4", 
"collectionViewUrl":"https://music.apple.com/us/album/omg/1659513441?i=1659513445&uo=4", 
"trackViewUrl":"https://music.apple.com/us/album/omg/1659513441?i=1659513445&uo=4",
"previewUrl":"https://audio-ssl.itunes.apple.com/itunes-assets/AudioPreview122/v4/bb/3c/83/bb3c836c-dc38-f24d-7305-de24d9241943/mzaf_9385892341590501525.plus.aac.p.m4a", 
"artworkUrl30":"https://is1-ssl.mzstatic.com/image/thumb/Music113/v4/48/96/08/4896085e-b550-cb0a-3e5b-1f203521cb82/196922265464_Cover.jpg/30x30bb.jpg", 
"artworkUrl60":"https://is1-ssl.mzstatic.com/image/thumb/Music113/v4/48/96/08/4896085e-b550-cb0a-3e5b-1f203521cb82/196922265464_Cover.jpg/60x60bb.jpg", 
"artworkUrl100":"https://is1-ssl.mzstatic.com/image/thumb/Music113/v4/48/96/08/4896085e-b550-cb0a-3e5b-1f203521cb82/196922265464_Cover.jpg/100x100bb.jpg", 
"collectionPrice":1.99, "trackPrice":1.29, "releaseDate":"2023-01-02T12:00:00Z", 
"collectionExplicitness":"notExplicit", 
"trackExplicitness":"notExplicit", 
"discCount":1, "discNumber":1, "trackCount":2, "trackNumber":1, "trackTimeMillis":212253, 
"country":"USA", "currency":"USD", "primaryGenreName":"K-Pop", "isStreamable":true},

앞서 설명한 https://itunes.apple.com/lookup?id=1635469693&entity=song URL의 2024년 1월 8일 기준 요청 내용입니다. 지금의 경우에는 노래 제목이 필요한 것이니 "results"의 "trackName"에 접근해야 합니다.

 

추가로, 해당 사이트에서 더욱 자세한 요청 내용 설명을 찾아볼 수 있습니다.

https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/UnderstandingSearchResults.html#//apple_ref/doc/uid/TP40017632-CH8-SW1

 

 

fetch('https://itunes.apple.com/lookup?id=1635469693&entity=song') 
// URL 요청
    .then(function (response) {
        return response.json(); 
        // 요청 시 요청 내용을 JSON 형식으로 반환하기 때문에, response.json()
    })
    .then((json) => {
        for (let i = 1; i < json["results"].length; i++) {
        // "results"의 0번 "trackName"이 존재하지 않기 때문에, let i = 1

            console.log(json["results"][i]["trackName"]);
            // "results"의 "trackName"에 접근
        }
    });

다음은 콘솔 창에 뉴진스의 노래 목록을 출력하는 예제입니다.

 


 

iTunes Search API 활용

 

앞선 내용을 바탕으로, 버튼을 누르면 무작위로 뉴진스의 노래를 추천하는 기능을 구현하였습니다.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>[HTML, JavaScript] iTunes Search API 활용</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
    </head>
    <body>

        <button id = "music_button" class="btn btn-dark" type="button"
        data-bs-toggle="modal" data-bs-target="#exampleModal">노래 추천</button>
        <!-- 버튼을 누르면 모달 창이 나오게 하기 위해,
          data-bs-toggle="modal" data-bs-target="#exampleModal" 속성 추가-->
          
          <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
            <div class="modal-dialog">
              <div class="modal-content">
                <div class="modal-header">
                  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body" id = "modal-body">
                </div>
                <div class="modal-footer">
                </div>
              </div>
            </div>
          </div>
          <!-- 모달 창-->

        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script>
        <script>

          fetch('https://itunes.apple.com/lookup?id=1635469693&entity=song') 
          // URL 요청
              .then(function (response) {
                  return response.json(); 
                  // 요청 시 요청 내용을 JSON 형식으로 반환하기 때문에, response.json()
              })
              .then((json) => {
                function musicClick() {

                    var numberIndex = Math.floor(Math.random() * json["results"].length) + 1;
                    /* "results"의 0번 "trackName"이 존재하지 않기 때문에,
                    1 <= numberINdex < json["results"].length + 1 */
                    const mbody = document.querySelector("#modal-body");
                    let trs = ''

                    trs += `<h5>${json["results"][numberIndex]["trackName"]}</h5>`
                    // "results"의 "trackName"에 접근

                    mbody.innerHTML = trs;
                }

                var musicButton = document.querySelector("#music_button");
                musicButton.addEventListener("click", musicClick);
              });

        </script>

      </body>
</html>

 

 

구현 결과는 다음과 같습니다.

 


 

해당 기능을 구현하는 과정에서 CORS 문제가 생겼는데, 서버 관련 지식이 전무했기에 Allow CORS: Access-Control-Allow-Origin 크롬 확장 프로그램을 통해 해결했습니다.

https://chromewebstore.google.com/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf

 

 

하지만 이는 개인 PC에서만 적용할 수 있는 임시적인 조치이기 때문에, 다음에 다른 해결 방법을 게시하겠습니다.