【问题标题】:YouTube API v3 get last video in playlistYouTube API v3 获取播放列表中的最后一个视频
【发布时间】:2016-07-02 05:41:13
【问题描述】:

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

我知道我可以通过将调用链接到以下内容来找到最后一个视频:

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

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

但是,这让我觉得效率极低——部分原因是我认为它会消耗我的 API 请求配额,但主要是因为它会减慢网站的整体响应时间。这些都不理想。

似乎应该有一种更简单的方法来获取播放列表中的“最新”视频,或者通过更改响应顺序或使用一些方便的功能,但我找不到任何文档。

我已经研究过使用Search 函数而不是PlaylistItems,但是(根据documentation),搜索只接受频道ID 作为参数而不是播放列表ID,这让我认为它是前进方向错误。

【问题讨论】:

  • 是的,它肯定会耗尽每日配额

标签: youtube youtube-api


【解决方案1】:

这里的简短回答是,在当前版本的 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。因此,我不需要为每个项目的每个项目都设置 sn-p单页。我只需要在结果中抓取最终视频的 sn-p,我可以通过更精细的调用来做到这一点

$youtube->videos->listVideos()

添加PlaylistCache 类后,我仅在播放列表的缓存版本在$playlistCache-&gt;isExpired() 调用上返回true 时才访问API,因此我只需每24 次轮询整个播放列表一次为每个用户加载每个页面的时间而不是 1 次。

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

【讨论】:

  • 感谢您定位正确的实施伙伴!
【解决方案2】:

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

示例请求:

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

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

示例请求:

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

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

【讨论】:

  • 这种方法的缺点是(根据文档,max-results 参数上限为 50。目前,这已经足够了,但我们有几个系列将超过该限制并且仍然需要多次调用分页结果。
【解决方案3】:

通常,播放列表中的最新视频添加到前面,而不是末尾。

【讨论】:

  • 正如我在问题中所说,我合并的播放列表是按发布日期排序的,所以这实际上是不准确的。我正在提取我创建的播放列表,并且我知道视频的顺序。我希望按照频道上出现的相反顺序从 YT 获得回复。
  • 好吧,迈克,我不知道还能告诉你什么。您以这种方式订购它们,这样 API 将返回结果。
  • 这在 Google 看来是短视的。在以这种方式排序的播放列表中抓取“最新”视频不可能是一种不常见的需求。似乎“升序”/“降序”切换应该存在于某处。感谢您的反馈,但听起来我的问题的答案是令人失望的“不”
猜你喜欢
  • 1970-01-01
  • 2015-08-20
  • 2018-06-11
  • 2017-06-25
  • 2015-11-24
  • 2017-07-14
  • 2015-07-05
  • 2022-01-08
  • 2015-08-21
相关资源
最近更新 更多