diff --git a/lib/index.js b/lib/index.js index cda4553..a240995 100644 --- a/lib/index.js +++ b/lib/index.js @@ -97,6 +97,7 @@ async function getAlbumInfo(albumUrl, options = {}) { async function getTrackInfo(trackUrl, options = {}) { const imageConstants = await _getImageConstants(); const opts = { + trackUrl, imageBaseUrl: imageConstants.baseUrl, albumImageFormat: await _parseImageFormatArg(options.albumImageFormat, 9), artistImageFormat: await _parseImageFormatArg(options.artistImageFormat), diff --git a/lib/parser.js b/lib/parser.js index f941248..bedce8e 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -207,6 +207,19 @@ function parseAlbumInfo(html, opts) { } function parseTrackInfo(html, opts) { + // Some tracks don't have a dedicated '/track' url, + // but take this form instead: {albumUrl}#t{x}, where 'x' is the + // track position. These tracks are not displayed as links nor playable. + // Since the album page is actually loaded, we can return the track info + // from the album data returned by parseAlbumInfo(). + const { path: trackUrlPath, hash: trackUrlHash } = utils.splitUrl(opts.trackUrl); + if (trackUrlPath && trackUrlHash) { + const matchTrackPosInUrl = /^\/(album)\/(.+)#t(\d+)/.exec(trackUrlPath + trackUrlHash); + if (matchTrackPosInUrl && matchTrackPosInUrl[3]) { + return parseTrackInfoFromAlbum(html, opts, matchTrackPosInUrl[3]); + } + } + const $ = cheerio.load(html); const rawBasic = $('script[type="application/ld+json"]').html(); const rawExtra = decode($('script[data-tralbum]').attr('data-tralbum')); @@ -250,6 +263,33 @@ function parseTrackInfo(html, opts) { } } +function parseTrackInfoFromAlbum(html, opts, trackPosition) { +console.log('parseTrackInfoFromAlbum: + ' + trackPosition); + const album = parseAlbumInfo(html, opts); + let trackData = album.tracks[trackPosition - 1] || {}; + const track = { + type: 'track', + name: trackData.name, + url: trackData.url, + imageUrl: album.imageUrl, + releaseDate: album.releaseDate, + duration: trackData.duration, + streamUrl: trackData.streamUrl, + artist: { + name: album.artist.name, + url: album.artist.url, + description: album.artist.description, + imageUrl: album.artist.imageUrl + }, + album: { + name: album.name, + url: album.url, + releaseDate: album.releaseDate + } + }; + return track; +} + function parseDiscography(html, opts) { const $ = cheerio.load(html); diff --git a/lib/utils.js b/lib/utils.js index 72e57d1..02e5471 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -92,7 +92,8 @@ function splitUrl(url) { return { base: _url.protocol + '//' + _url.host, path: _url.pathname, - query: _url.search + query: _url.search, + hash: _url.hash }; }