diff --git a/lib/services/ytmusic/index.js b/lib/services/ytmusic/index.js index 9e16713..16aa9a7 100644 --- a/lib/services/ytmusic/index.js +++ b/lib/services/ytmusic/index.js @@ -114,25 +114,35 @@ function parse_result_content(contents, type) { } async function lookupTrack(id) { - let endpoint = "https://www.youtube.com/get_video_info" - const { body } = await request.get(endpoint).query({ video_id: id, hl: "en", el: "detailpage" }) + let request_body = {'video_id': id, ...standard_body } - if (body.player_response === undefined) { - throw new Error(); + const { body } = await request.post("https://music.youtube.com/youtubei/v1/player") + .set(standard_headers) + .query(standard_params) + .send(request_body) + let song_meta = body.videoDetails + + let description = body.microformat.microformatDataRenderer.description.split(' · ') + let possible_album_name = description[description.length - 1].split("℗")[0] + if (!description[description.length - 1].includes("℗")) { + possible_album_name = ""; } - let player_response = JSON.parse(body.player_response) - let song_meta = player_response.videoDetails - - let description = song_meta.shortDescription.split("\n\n") - let album_name = description[2] - let artists = description[1].split(' · ').slice(1) + let tags = body.microformat.microformatDataRenderer.tags + let album_name = "" + for (const tag of tags) { + if(possible_album_name.includes(tag)){ + album_name = tag; + } + } + let artists = song_meta.author + artists = artists.replace(" - Topic", "") const artwork = { small: song_meta.thumbnail.thumbnails[0].url, large: song_meta.thumbnail.thumbnails[song_meta.thumbnail.thumbnails.length-1].url, }; - return Promise.resolve({ + let track_info = { service: 'ytmusic', type: 'track', id: song_meta.videoId, @@ -141,12 +151,14 @@ async function lookupTrack(id) { purchaseUrl: null, artwork, artist: { - name: artists.join(", "), + name: artists, }, album: { name: album_name, }, - }); + } + debug(track_info) + return Promise.resolve(track_info); } async function lookupAlbum(id) { diff --git a/test/services/ytmusic.js b/test/services/ytmusic.js index ad10834..618535a 100644 --- a/test/services/ytmusic.js +++ b/test/services/ytmusic.js @@ -10,8 +10,25 @@ describe('ytmusic', function(){ it('should find track by ID', async function (){ const result = await ytmusic.lookupId('9zrYXvUXiQk', 'track'); - result.name.should.equal('One Vision (Remastered 2011)'); + result.name.should.equal('One Vision'); result.artist.name.should.equal('Queen'); + result.album.name.should.equal('A Kind Of Magic') + }); + it('should find track by ID', async function (){ + const result = await ytmusic.lookupId('rAzfNuU1f8E', 'track'); + result.name.should.equal('Erre (Live)'); + result.artist.name.should.equal('Boogarins'); + // The copyright notice is too long and is the only place where the album name is. + result.album.name.should.equal('') + }); + it('should find track by ID', async function (){ + const result = await ytmusic.lookupId('Wst0la_TgTY', 'track'); + result.name.should.equal('Às Vezes Bate Uma Saudade'); + // XXX: This is very odd. Sometimes, google will return the first artist "Rodrigo Alarcon", sometimes "Rodrigo Alarcon, Ana Muller & Mariana Froes" and sometimes + // "Rodrigo Alarcon, Ana Muller, Mariana Froes". Same API call, same everything. Go figure. + // result.artist.name.should.equal('Rodrigo Alarcon, Ana Muller, Mariana Froes'); + result.artist.name.should.startWith('Rodrigo Alarcon'); + result.album.name.should.equal('Taquetá Vol.1') }); }); describe('search', () => {