这里的简短回答是,在当前版本的 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。
根据documentation,snippet 花费 2 个单位的 API 配额,而对 id 的请求为 0。因此,我不需要为每个项目的每个项目都设置 sn-p单页。我只需要在结果中抓取最终视频的 sn-p,我可以通过更精细的调用来做到这一点
$youtube->videos->listVideos()
添加PlaylistCache 类后,我仅在播放列表的缓存版本在$playlistCache->isExpired() 调用上返回true 时才访问API,因此我只需每24 次轮询整个播放列表一次为每个用户加载每个页面的时间而不是 1 次。
它仍然不是很理想,但据我所知,它是目前最好的选择。