YouTube API v3获取播放列表中的最后一个视频

时间:2016-07-02 05:41:14

标签: youtube youtube-api

一些基本背景:我帮助在YouTube上运行游戏频道,并且我正在构建一个实用程序(使用PHP)将频道的内容与配套网站集成。我们的播放列表主要是"让我们播放"按照出版日期排序的系列,按照各种游戏的时间顺序进行,我希望该网站能够显示最新一集"来自精选的系列。

我知道我可以通过将以下呼叫链接到最后一个视频:

$youtubeService->playlistItems->listPlaylistItems(
    "snippet",
    array(
        "playlistId"  =>  $playlistId
        "pageToken"   =>  $nextPageToken
    )
)

只需在$nextPageToken未设置时抓取响应集中的最后一项。

然而,这让我觉得非常低效 - 部分是因为我认为它会影响我的API请求配额,但主要是因为它会减慢网站的整体响应时间。这些都不是理想的。

似乎应该有一种更简单的方法来抓住最新的"播放列表中的视频,可以通过更改响应的顺序,也可以使用一些方便的功能,但我无法找到任何文档。

我已经考虑使用Search上的PlaylistItems功能,但是(根据documentation),搜索仅接受频道ID作为参数,而不接受播放列表ID ,这让我认为这是错误的方向。

3 个答案:

答案 0 :(得分:0)

首先,您需要通过HTTP请求获取用户的channelId

示例请求

https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername={0}&key={1} 
  • 其中{0}是USERNAME,密钥是API密钥

然后,通过调用'PlaylistItems:list'获取视频列表,它会返回与API请求参数匹配的播放列表项集合。您可以检索指定播放列表中的所有播放列表项目,也可以按唯一ID检索一个或多个播放列表项目。

示例请求

https://www.googleapis.com/youtube/v3/search?order=date&part=snippet&channelId={0}&key={1}

从那里,您可以创建一个数组来获取播放列表中的最后一个视频。包含max-results参数,max-results指定结果集中包含的最大结果数。

答案 1 :(得分:0)

这里的简短回答是,在当前版本的API下,这似乎是不可能的。没有明显的方法来反过来选择视频,但我做了一个小的改变,导致整个过程更有效。

这是原始代码:

$items = $youtube->playlistItems->listPlaylistItems(
    "snippet",
    array(
        "playlistId"    =>  $playlistId,
        "maxResults"    => 50
    )
);

while ($items->nextPageToken) {
    $items = $youtube->playlistItems->listPlaylistItems(
        "snippet",
        array(
            "playlistId"    =>  $playlistId,
            "maxResults"    =>  50,
            "pageToken" =>  $items->nextPageToken
        )
    );
}

if ($items) {
    return end($items->getItems());
}

这是修复:

首先,我添加了一个对象来协助缓存:

class PlaylistCache {
    protected $expirationDate;
    protected $playlistId;
    protected $latestEpisode;

    __construct($playlistId, $latestEpisode) {
        $this-playlistId = $playlistId;
        $this->latestEpisode = $latestEpisode;

        $this->expirationDate = time() + 86400;
        // get current time + 24 hours
    }

    public function getLatestEpisode() {
        return $this->latestEpisode;
    }

    public function getPlaylistId() {
        return $this->playlistId;
    }

    public function isExpired() {
        return $this->expirationDate < time();
    }
}

然后,在轮询API之前,我会查看是否有可用的缓存版本,如果缓存版本已过期,我只会使用API​​。

$playlistCache = json_decode(get_option('playlist_cache_' . $playlistId));

if ($playlistCache->isExpired()) {

    $items = $youtube->playlistItems->listPlaylistItems(
        "id",
        array(
            "playlistId"    =>  $playlistId,
            "maxResults"    => 50
        )
    );

    while ($items->nextPageToken) {
        $items = $youtube->playlistItems->listPlaylistItems(
            "id",
            array(
                "playlistId"    =>  $playlistId,
                "maxResults"    =>  50,
                "pageToken" =>  $items->nextPageToken
            )
        );
    }

    if ($items) {
        $videoId = end($items->getItems()[0]->getId());
        $video = $youtube->videos->listVideos("snippet", array('id' => $videoId))
        $video = $video->getItems()[0];

        $playlistCache = new PlaylistCache($playlistId, $video);

        update_option('playlist_cache_' . $playlistId, json_encode($playlistCache)));
    }
}

return $playlistCache->getLatestEpisode();

此处的另一个重大变化是,我对listPlaylistItems()的来电正在请求id而不是snippet

根据documentationsnippet费用为2个单位的API配额,而id的请求则为0.因此,我不需要抓取代码段对于每个页面上的每个项目。我只需要抓住结果中最后一个视频的片段,我可以用更精致的调用来完成

$youtube->videos->listVideos()

添加PlaylistCache类后,当true调用的播放列表的缓存版本返回$playlistCache->isExpired()时,我只会访问API,因此我只需要轮询整个播放列表每24小时一次,而不是每个用户每次加载一次。

它仍然不完全理想,但就我所知,它是目前最好的选择。

答案 2 :(得分:-1)

通常情况下,播放列表中的最新视频会添加到前端,而不是结尾。