Spotify javascript API - 在播放列表中获取歌曲的类型

时间:2016-12-19 13:51:08

标签: javascript api spotify

我目前正在使用非常酷的应用程序Exportify(https://github.com/watsonbox/exportify)将Spotify播放列表导出为CSV。

我的javascript知识非常糟糕,但我目前正试图包含每首曲目的类型,而我却无法检索它。

我假设:

我可以通过添加" item.track.artists.map(函数(艺术家){return artist.id})来获取艺术家ID。加入(','),&# 34;以下代码中的" exportify.js"文件。

      var tracks = responses.map(function(response) {
    return response.items.map(function(item) {
      return [
        item.track.uri,
        item.track.id,
        item.track.name,
        item.track.artists.map(function(artist) { return artist.name }).join(', '),
        item.track.artists.map(function(artist) { return artist.id }).join(', '),
        item.track.album.name,
        item.track.disc_number,
        item.track.track_number,
        item.track.duration_ms,
        item.added_by == null ? '' : item.added_by.uri,
        item.added_at
      ].map(function(track) { return '"' + track + '"'; })
    });
  });

有谁可以告诉我如何根据艺术家ID获取艺术家类型并将其添加为另一列?

由于

克里斯

4 个答案:

答案 0 :(得分:0)

使用"获取艺术家" Spotify中的端点:

https://developer.spotify.com/web-api/get-artist/

通过调用此终结点,您可以获得艺术家身份的艺术家身份。

答案 1 :(得分:0)

正如Potray所说,你可以连接到端点getArtist。更具体地说,返回的JSON将具有流派键。流派键直接指向一系列流派。

response.genres将访问此数组。

您可以在RapidAPI here.处对此进行测试。我已将您专门链接到getArtist端点。在这里,您可以填写artist_id,单击测试,并查看示例响应。 RapidAPI还会生成一个代码段,您只需将API调用直接复制并粘贴到您自己的代码中即可。

在这里,我使用Red Hot Chili Peppers artist_id" 0L8ExT028jH3ddEcZwqJJ5"来测试getArtist端点:

enter image description here

您会注意到该类型数组包含5个项目:['替代摇滚',' funk metal',' funk rock',&# 39;永久波浪'摇滚' ]

如果直接点击CODE右侧的回复并登录,您就可以访问代码段,并将其直接粘贴到您的代码中。一个例子是:

enter image description here

答案 2 :(得分:0)

请注意,此处引用的类型与您在大多数api中实际遇到的类型不匹配(例如,与track.artist.genres不匹配)

https://developer.spotify.com/console/get-available-genre-seeds/

此问题尚未解决: https://github.com/spotify/web-api/issues/410

答案 3 :(得分:0)

我已经实现了!

下面是https://github.com/pavelkomarov/exportify/blob/master/exportify.js中的函数,该函数进行所有必需的API查询。我的apiCall函数也在该文件中。它正在使用fetch

  1. 首先,我从播放列表中发出对大块歌曲的请求。
  2. 然后,我将这些消息聚集到一个数据表和一组艺术家中。
  3. 然后,我使用一组艺术家来查询类型信息。
  4. 然后我将其加入数据并写到csv。

因为这都是通过网络发生的,所以每个新步骤都必须包装在.then()中,这取决于先前对象的解析。值得庆幸的是,近年来JavaScript在这一方面变得更加优雅。 https://eloquentjavascript.net/11_async.html

该实时应用有效期为here。我还创建了a notebook来分析输出。

csvData(access_token, playlist) {
    // Make asynchronous API calls for 100 songs at a time, and put the results (all Promises) in a list.
    let requests = [];
    for (let offset = 0; offset < playlist.tracks.total; offset = offset + 100) {
        requests.push(utils.apiCall(playlist.tracks.href.split('?')[0] + '?offset=' + offset + '&limit=100',
                access_token));
    }

    // "returns a single Promise that resolves when all of the promises passed as an iterable have resolved"
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
    let artist_hrefs = new Set();
    let data_promise = Promise.all(requests).then(responses => {
        return responses.map(response => { // apply to all responses
            return response.items.map(song => { // appy to all songs in each response
                song.track.artists.forEach(a => { artist_hrefs.add(a.href) });
                return [song.track.uri, '"'+song.track.name.replace(/"/g,'')+'"', '"'+song.track.album.name.replace(/"/g,'')+'"',
                    song.track.duration_ms, song.track.popularity, song.track.album.release_date,
                    '"'+song.track.artists.map(artist => { return artist.name }).join(',')+'"',
                    song.added_by.uri, song.added_at]
            });
        });
    });

    // Make queries on all the artists, because this json is where genre information lives. Unfortunately this
    // means a second wave of traffic.
    let genre_promise = data_promise.then(() => {
        let artists_promises = Array.from(artist_hrefs).map(href => utils.apiCall(href, access_token));
        return Promise.all(artists_promises).then(responses => {
          let artist_genres = {};
          responses.forEach(artist => { artist_genres[artist.name] = artist.genres.join(','); });
          return artist_genres;
        });
    });

    // join genres to the table, label the columns, and put all data in a single csv string
    return Promise.all([data_promise, genre_promise]).then(values => {
        [data, artist_genres] = values;

        data = data.flat();
        data.forEach(row => {
            artists = row[6].substring(1, row[6].length-1).split(','); // strip the quotes
            deduplicated_genres = new Set(artists.map(a => artist_genres[a]).join(",").split(",")); // join and split and take set
            row.push('"'+Array.from(deduplicated_genres).filter(x => x != "").join(",")+'"'); // remove empty strings
        });
        data.unshift(["Spotify URI", "Track Name", "Album Name", "Duration (ms)",
            "Popularity", "Release Date", "Artist Name(s)", "Added By", "Added At", "Genres"]);

        csv = '';
        data.forEach(row => { csv += row.join(",") + "\n" });
        return csv;
    });
},