YouTube Data API 概览

简介

本文档适用于想要编写与 YouTube 进行交互的应用程序的开发者。介绍 YouTube 的基本概念和 API 本身。还概述了该 API 支持的不同函数。

前期准备

  1. 您需要拥有 Google 帐号才能访问 Google API 控制台、申请 API 密钥以及注册应用。

  2. Google Developers Console 中创建项目并获取授权凭据,以便您的应用可以提交 API 请求。

  3. 创建项目后,请确保您的应用注册使用的服务之一是 YouTube Data API:

    1. 转到 API 控制台并选择您刚刚注册的项目。
    2. 访问“已启用的 API”页面。 在 API 列表中,确保 YouTube Data API v3 的状态为启用

  4. 如果您的应用所采用的 API 方法需要用户授权,则您可以参阅授权指南,了解如何采用 OAuth 2.0 授权。

  5. 选择客户端库,简化 API 执行过程。

  6. 熟悉 JSON(JavaScript 对象表示法)数据格式的核心概念。JSON 是一种与语言无关的常见数据格式,可提供任意数据结构的简单文本表示形式。如需了解详情,请参阅 json.org

资源和资源类型

资源是具有唯一标识符的单个数据实体。下表介绍了您可以使用此 API 与各种不同类型的资源进行交互。

资源
activity 包含特定用户在 YouTube 网站上执行的操作的相关信息。活动 Feed 中报告的用户操作包括对视频评分、分享视频、将视频标记为收藏和发布频道公告等等。
channel 包含单个 YouTube 频道的相关信息。
channelBanner 指定用于将新上传的图片设置为频道横幅图片的网址。
channelSection 包含频道选择推介的一组视频的相关信息。例如,版块可以展示某个频道最新上传的视频、最热门的上传视频,或者一个或多个播放列表中的视频。
guideCategory 确定 YouTube 根据频道的内容或其他指标(如热门程度)将其与频道关联的类别。导视类别旨在对频道进行整理,以便让 YouTube 用户能够更轻松地找到所需内容。虽然频道可以与一个或多个导视类别相关联,但不保证一定属于任何导视类别。
i18nLanguage 标识 YouTube 网站支持的应用语言。应用语言也称为界面语言。
i18nRegion 标识 YouTube 用户可以选为首选内容区域的地理区域。内容区域也称为内容语言区域。
playlist 表示单个 YouTube 播放列表。播放列表 是可以连续观看并与其他用户共享的视频集合。
playlistItem 标识属于播放列表中的资源,例如视频。playItem 资源也包含详细说明所含资源在播放列表中的使用方式。
search result 包含与 API 请求中指定的搜索参数匹配的 YouTube 视频、频道或播放列表的相关信息。虽然搜索结果指向可唯一标识的资源(如视频),但它没有自己的持久性数据。
subscription 包含有关 YouTube 用户订阅的信息。订阅会在频道中添加新视频或其他用户在 YouTube 上执行多项操作(例如上传视频、为视频评分或对视频发表评论)时发出通知。
thumbnail 标识与资源关联的缩略图。
video 表示单个 YouTube 视频。
videoCategory 标识已经或可能与上传的视频相关联的类别。
watermark 标识在指定频道的视频播放期间显示的图片。频道所有者还可以指定图片链接到的目标频道,以及用于确定水印何时在视频播放期间出现以及显示时长的时间详情。

请注意,在许多情况下,资源包含对其他资源的引用。例如,playlistItem 资源的 snippet.resourceId.videoId 属性用于标识视频资源,而该资源包含视频的完整信息。再比如,一个搜索结果包含的 videoIdplaylistIdchannelId 属性用于标识特定的视频、播放列表或频道资源。

支持的操作

下表显示了该 API 支持的最常用方法。某些资源还支持其他方法,这些方法可执行更特定于这些资源的功能。例如,videos.rate 方法将用户评分与视频相关联,thumbnails.set 方法会将视频缩略图上传到 YouTube 并将其与视频相关联。

运营
list 检索 (GET) 包含零个或多个资源的列表。
insert 创建 (POST) 一个新资源。
update 修改 (PUT) 现有资源以反映您的请求中的数据。
delete 移除 (DELETE) 特定资源。

该 API 目前支持列出每种受支持的资源类型的方法,并且也支持对许多资源执行写入操作。

下表列出了不同类型的资源支持的操作。插入、更新或删除资源的操作始终需要用户授权。在某些情况下,list 方法同时支持已获授权的请求和未经授权的请求,其中未经授权的请求仅检索公开数据,而已获授权的请求也可以检索当前经过身份验证的用户的相关信息或私密数据。

支持的操作
list insert update delete
activity
caption
channel
channelBanner
channelSection
comment
commentThread
guideCategory
i18nLanguage
i18nRegion
playlist
playlistItem
search result
subscription
thumbnail
video
videoCategory
watermark

配额用量

YouTube Data API 使用配额来确保开发者按预期使用服务,并且不会创建不公平地降低服务质量或限制他人访问的应用。所有 API 请求(包括无效请求)都会产生至少 1 分的配额费用。您可以在 API Console 中找到您的应用可用的配额。

启用了 YouTube Data API 的项目每天的默认配额分配为 10,000 个单元,这个配额足以满足绝大多数 API 用户的需求。默认配额可能会发生变化,这有助于我们优化配额分配,并以对 API 用户更有意义的方式扩缩基础架构。您可以在 API 控制台的配额页面上查看配额使用情况。

注意:如果您达到配额限制,可以填写 YouTube API 服务的配额增加申请表单来申请更多配额。

计算配额用量

Google 通过为每个请求指定费用来计算您的配额用量。不同类型的操作具有不同的配额费用。例如:

  • 用于检索资源列表(频道、视频和播放列表)的读取操作通常需要 1 个单元。
  • 创建、更新或删除资源的写入操作通常需要 50 单位。
  • 搜索请求的费用为 100 单位。
  • 一次视频上传需要 1600 单元。

API 请求的配额费用表格显示了每种 API 方法的配额费用。了解这些规则后,您就可以估算您的应用每天在不超出配额的情况下可以发送的请求数。

部分资源

该 API 允许(并且实际上需要)检索部分资源,以便应用避免传输、解析和存储不需要的数据。此方法还可确保 API 更高效地使用网络、CPU 和内存资源。

该 API 支持两个请求参数(在后面几部分中介绍),您可以使用这些参数确定 API 响应中应包含的资源属性。

  • part 参数用于标识应为资源返回的属性组。
  • fields 参数可过滤 API 响应,以便仅返回所请求资源部分中的特定属性。

如何使用 part 参数

对于任何检索或返回资源的 API 请求,part 参数都是必需参数。该参数用于标识 API 响应中包含的一个或多个顶级(非嵌套)资源属性。例如,video 资源包含以下部分:

  • snippet
  • contentDetails
  • fileDetails
  • player
  • processingDetails
  • recordingDetails
  • statistics
  • status
  • suggestions
  • topicDetails

所有这些部分都是包含嵌套属性的对象,您可以将这些对象视为 API 服务器可能会(也可能不会)检索的元数据字段组。因此,part 参数要求您选择应用实际使用的资源组件。此要求有两个主要用途:

  • 它可以防止 API 服务器花时间检索应用不使用的元数据字段,从而缩短延迟时间。
  • 它通过减少(或消除)应用可能检索的不必要数据量来减少带宽使用量。

随着时间的推移,资源会越来越多,这些优势只会增加,因为您的应用不会请求不受支持的新引入属性。

如何使用 fields 参数

fields 参数用于过滤 API 响应,该响应仅包含 part 参数值中标识的资源部分,以便响应仅包含一组特定的字段。借助 fields 参数,您可以从 API 响应中移除嵌套属性,从而进一步减少带宽用量。(part 参数不能用于从响应中过滤嵌套属性。)

以下规则说明了 fields 参数值支持的语法,大致基于 XPath 语法:

  • 使用英文逗号分隔列表 (fields=a,b) 选择多个字段。
  • 使用星号 (fields=*) 作为通配符来标识所有字段。
  • 使用括号 (fields=a(b,c)) 指定一组将包含在 API 响应中的嵌套属性。
  • 使用正斜杠 (fields=a/b) 标识嵌套属性。

在实践中,这些规则通常允许使用多个不同的 fields 参数值检索同一 API 响应。例如,如果您想要检索播放列表中每一项的播放列表项 ID、标题和位置,则可以使用以下任一值:

  • fields=items/id,playlistItems/snippet/title,playlistItems/snippet/position
  • fields=items(id,snippet/title,snippet/position)
  • fields=items(id,snippet(title,position))

注意:与所有查询参数值一样,fields 参数值也必须采用网址编码。为了便于阅读,本文中的示例省略了编码。

部分请求示例

以下示例演示了如何使用 partfields 参数来确保 API 响应仅包含应用使用的数据:

  1. 示例 1 返回的视频资源包含四个部分以及 kindetag 属性。
  2. 示例 2 返回的视频资源包含两个部分以及 kindetag 属性。
  3. 示例 3 返回的视频资源包含两个部分,但不包括 kindetag 属性。
  4. 示例 4 返回了一个视频资源,其中包含两部分,但不包括 kindetag 以及该资源的 snippet 对象中的一些嵌套属性。
示例 1
URL: https://www.googleapis.com/youtube/v3/videos?id=7lCDEYXw3mM&key=YOUR_API_KEY
&part=snippet,contentDetails,statistics,status
Description: This example retrieves a video resource and identifies several resource parts that should be included in the API response. API response:
{ "kind": "youtube#videoListResponse", "etag": "\"UCBpFjp2h75_b92t44sqraUcyu0/sDAlsG9NGKfr6v5AlPZKSEZdtqA\"", "videos": [ { "id": "7lCDEYXw3mM", "kind": "youtube#video", "etag": "\"UCBpFjp2h75_b92t44sqraUcyu0/iYynQR8AtacsFUwWmrVaw4Smb_Q\"", "snippet": { "publishedAt": "2012-06-20T22:45:24.000Z", "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw", "title": "Google I/O 101: Q&A On Using Google APIs", "description": "Antonio Fuentes speaks to us and takes questions on working with Google APIs and OAuth 2.0.", "thumbnails": { "default": { "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/default.jpg" }, "medium": { "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/mqdefault.jpg" }, "high": { "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/hqdefault.jpg" } }, "categoryId": "28" }, "contentDetails": { "duration": "PT15M51S", "aspectRatio": "RATIO_16_9" }, "statistics": { "viewCount": "3057", "likeCount": "25", "dislikeCount": "0", "favoriteCount": "17", "commentCount": "12" }, "status": { "uploadStatus": "STATUS_PROCESSED", "privacyStatus": "PRIVACY_PUBLIC" } } ] }
示例 2
URL: https://www.googleapis.com/youtube/v3/videos?id=7lCDEYXw3mM&key=YOUR_API_KEY
&part=snippet,statistics
Description: This example modifies the part parameter value so that the contentDetails and status properties are not included in the response. API response:
{ "kind": "youtube#videoListResponse", "etag": "\"UCBpFjp2h75_b92t44sqraUcyu0/sDAlsG9NGKfr6v5AlPZKSEZdtqA\"", "videos": [ { "id": "7lCDEYXw3mM", "kind": "youtube#video", "etag": "\"UCBpFjp2h75_b92t44sqraUcyu0/iYynQR8AtacsFUwWmrVaw4Smb_Q\"", "snippet": { "publishedAt": "2012-06-20T22:45:24.000Z", "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw", "title": "Google I/O 101: Q&A On Using Google APIs", "description": "Antonio Fuentes speaks to us and takes questions on working with Google APIs and OAuth 2.0.", "thumbnails": { "default": { "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/default.jpg" }, "medium": { "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/mqdefault.jpg" }, "high": { "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/hqdefault.jpg" } }, "categoryId": "28" }, "statistics": { "viewCount": "3057", "likeCount": "25", "dislikeCount": "0", "favoriteCount": "17", "commentCount": "12" } } ] }
示例 3
URL: https://www.googleapis.com/youtube/v3/videos?id=7lCDEYXw3mM&key=YOUR_API_KEY
&part=snippet,statistics&fields=items(id,snippet,statistics)
Description: This example adds the fields parameter to remove all kind and etag properties from the API response. API response:
{ "videos": [ { "id": "7lCDEYXw3mM", "snippet": { "publishedAt": "2012-06-20T22:45:24.000Z", "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw", "title": "Google I/O 101: Q&A On Using Google APIs", "description": "Antonio Fuentes speaks to us and takes questions on working with Google APIs and OAuth 2.0.", "thumbnails": { "default": { "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/default.jpg" }, "medium": { "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/mqdefault.jpg" }, "high": { "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/hqdefault.jpg" } }, "categoryId": "28" }, "statistics": { "viewCount": "3057", "likeCount": "25", "dislikeCount": "0", "favoriteCount": "17", "commentCount": "12" } } ] }
示例 4
URL: https://www.googleapis.com/youtube/v3/videos?id=7lCDEYXw3mM&key=YOUR_API_KEY
&fields=items(id,snippet(channelId,title,categoryId),statistics)&part=snippet,statistics
Description: This example modifies the fields parameter from example 3 so that in the API response, each video resource's snippet object only includes the channelId, title, and categoryId properties. API response:
{ "videos": [ { "id": "7lCDEYXw3mM", "snippet": { "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw", "title": "Google I/O 101: Q&A On Using Google APIs", "categoryId": "28" }, "statistics": { "viewCount": "3057", "likeCount": "25", "dislikeCount": "0", "favoriteCount": "17", "commentCount": "12" } } ] }

优化性能

使用 ETag

ETagsHTTP 协议的标准部分,可让应用引用特定 API 资源的特定版本。资源可以是整个 Feed,也可以是该 Feed 中的商品。此功能支持以下用例:

  • 缓存和条件检索 - 您的应用可以缓存 API 资源及其 ETag。然后,当应用再次请求存储的资源时,它会指定与该资源关联的 ETag。如果资源已更改,则 API 会返回修改后的资源以及与该资源版本关联的 ETag。如果资源未更改,该 API 会返回 HTTP 304 响应 (Not Modified),这表示资源并未更改。通过以这种方式提供缓存资源,您的应用可以减少延迟时间和带宽使用量。

    Google API 的客户端库在支持 ETag 方面有所不同。例如,JavaScript 客户端库通过许可名单(包含 If-MatchIf-None-Match)允许的请求标头来支持 ETag。白名单允许进行正常的浏览器缓存,以便在资源的 ETag 未更改的情况下,从浏览器缓存提供资源。另一方面,Obj-C 客户端不支持 ETag。

  • 防止意外覆盖更改 – ETag 有助于确保多个 API 客户端不会无意间覆盖彼此的更改。在更新或删除资源时,您的应用可以指定该资源的 ETag。如果 ETag 与该资源的最新版本不匹配,则 API 请求会失败。

在应用中使用 ETag 有以下几项优势:

  • API 能更快地响应对已缓存但未更改资源的请求,从而缩短延迟时间并降低带宽使用量。
  • 您的应用不会意外覆盖通过其他 API 客户端对资源所做的更改。

Google APIs Client Library for JavaScript 支持 If-MatchIf-None-Match HTTP 请求标头,因此 ETag 可以在正常浏览器缓存环境中工作。

使用 gzip

您还可以通过启用 gzip 压缩,减少每个 API 响应所需的带宽。虽然您的应用需要额外的 CPU 时间来解压缩 API 响应,但消耗的网络资源更少的好处通常远远超过此成本。

要接收 gzip 编码的响应,您必须执行以下两项操作:

  • Accept-Encoding HTTP 请求标头设置为 gzip
  • 修改用户代理,使其包含字符串 gzip

以下示例 HTTP 标头演示了启用 gzip 压缩的这些要求:

Accept-Encoding: gzip
User-Agent: my program (gzip)