需要帮助检索多个播放列表中的项目

问题描述 投票:0回答:1

得到了一些工作正常的代码,并将检索指定播放列表中的所有项目,但需要修改它,以便它可以循环播放一组播放列表并检索每个列表中的所有项目。

我已经尝试在代码中的不同位置放置for-next循环但是,由于我的javascript很差,这些努力都失败了,我不知道接下来该做什么。

function onGoogleLoad() {
  showhide('hidden');
  getSearchParameters();
  gapi.client.setApiKey(APIKEY);
  gapi.client.load('youtube', 'v3', function () {

    GatherVideos("", function () {
      for (var i = 0; i < allVideos.length; i++) {
        console.log(allVideos[i].snippet.title + " published at " + allVideos[i].snippet.publishedAt)
      }

      showhide('visible');
      build_html(allVideos);
    });

  });
}
ORIGINAL CODE ...


        function GatherVideos(pageToken, finished) {
            var request = gapi.client.youtube.playlistItems.list({
                part: 'snippet, contentDetails',
                playlistId: 'UU_FksrzP3q-IuoWTiG501LQ',
                maxResults: 50,
                pageToken: pageToken
            });

            request.execute(function(response) {
                allVideos = allVideos.concat(response.items);
                if (!response.nextPageToken)
                    finished();
                else
                    GatherVideos(response.nextPageToken, finished);
            });
        }
END ORIGINAL CODE

NEW CODE WITH ATTEMPT AT LOOPING ...

        function GatherVideos(pageToken, finished) {
                for (var p=0;p<allPlaylists.length;p++)
                {
                    console.log('Gathering: ' + allPlaylists[p]);
                var request = gapi.client.youtube.playlistItems.list({
                 part: 'snippet, contentDetails',
                  playlistId: allPlaylists[p],
                   maxResults: 50,
                    pageToken: pageToken
                });             

                request.execute(function(response) {
                        console.log('Executing: ' + request);               
                   allVideos = allVideos.concat(response.items);
                    if (!response.nextPageToken)
                       finished();
                   else
                    GatherVideos(response.nextPageToken, finished);
                    });
           } //End for loop
        }
END NEW CODE ...

  function build_html(parArray) {
    var n = 0;
    var playlistHtml = '';
    var rows = Math.floor(parArray.length / vinrow);
    var rem = (allVideos.length % vinrow);
    if (rem > 0) {
      rows++;
    }

    for (var i = 0; i < rows; i++) {
      playlistHtml += '<div class="row">';

      for (var k = 0; k < vinrow; k++) {
        if (n < parArray.length) {
          playlistHtml += '<div id=' + n + ' class="col item"><img class="img-responsive fit-image" src="' + 
            parArray[n].snippet.thumbnails.default.url + '"><div class="vtitle">' + 
            parArray[n].snippet.title + '</div></div>';

          n++;
        } else {
          playlistHtml += '<div class="col item"><div class="vtitle"> </div></div>';
        }
      }

      playlistHtml += "</div>";
    }

    playlist_div.innerHTML = playlistHtml;
  }
}

所以,需要一些帮助来放置代码的位置,这些代码将遍历播放列表数组。

javascript youtube-api youtube-data-api
1个回答
0
投票

你遍历allPlaylists,构建请求并将其保存在request变量中。问题是,这个循环在每次执行时都会覆盖request变量。当您稍后调用request.execute(...)时,您只执行最后一个请求构建(数组中的最后一个播放列表)。

您应该在for循环中移动请求执行。

for (var p = 0; p < allPlaylists.length; p++)
{
    console.log('Gathering: ' + allPlaylists[p]);
    var request = gapi.client.youtube.playlistItems.list({ /* ... */ });
    request.execute(/* ... */);
}

以上内容已经解决了部分问题。然而,这并不能完全解决问题。你递归地调用GatherVideos(如果有超过1页),然后再次遍历整个allPlaylists数组。为每个播放列表设置新请求。

要解决上述问题,请从单个播放列表中检索视频,并将其移至自己的方法中。由于不同的原因,使用当前结构有点麻烦,所以我使用一种不同的方法从头开始重建它。这可能不是您正在寻找的确切答案,但我希望它会给您一些灵感:

async function listPlaylist(options = {}) {
    var maxResults, pendingMaxResults, response;

    options = Object.assign({}, options);
    maxResults = options.maxResults;

    if (Number.isInteger(maxResults) && maxResults > 0) {
        // set options.maxResults to a value 1-50
        options.maxResults = (maxResults - 1) % 50 + 1;
        pendingMaxResults = maxResults - options.maxResults;
    } else if (maxResults === "all") {
        pendingMaxResults = "all";
    }

    response = await Promise.resolve(gapi.client.youtube.list(options));

    if (response.nextPageToken && (pendingMaxResults === "all" || pendingMaxResults > 0)) {
        options.maxResults = pendingMaxResults;
        options.pageToken = response.nextPageToken;
        return response.items.concat(await listPlaylist(options));
    } else {
        return response.items;
    }
}

(async function () {
    var playlistsVideos, videos;

    // retrieve all videos of all playlists
    playlistsVideos = await Promise.all(allPlaylists.map(function (playlistId) {
        return listPlaylist({ 
            id: playlistId,
            part: "snippet, contentDetails",
            maxResults: "all"
        });
    }));

    // the above variable `playlistsVideos` is in the format:
    // [[p1v1, p1v2, p1v3], [p2v1, p2v2, p2v3]] (p = playlist, v = video)
    // this needs to be flattened to have the result you want
    videos = playlistsVideos.reduce((videos, playlistVideos) => videos.concat(playlistVideos), []);
})();

我建议查看指南Using Promises并查看async/await的文档。以上是基于YouTube API V3。我希望我能够清楚地编写代码,让它自己说话。如果您有任何疑问,请在评论中提出。

© www.soinside.com 2019 - 2024. All rights reserved.