上传媒体内容

上传媒体内容包含两个步骤:

  1. 使用上传端点将媒体文件的字节上传到 Google 服务器。此方法会返回可识别已上传字节的上传令牌。
  2. 使用包含上传令牌的 batchCreate 调用在用户的 Google 相册账号中创建媒体内容。

以下步骤概述了上传单个媒体内容的过程。如果您要上传多个媒体项(对于任何生产应用来说,这都是很可能的情况),请查看上传最佳实践,以提高上传效率。

准备工作

所需的授权范围

如要将媒体内容上传到用户的媒体库或相册,则需使用 photoslibrary.appendonly 范围。如需详细了解范围,请参阅授权范围

接受的文件类型和大小

您可以上传下表中所列的文件类型。

媒体类型 接受的文件类型 文件大小上限
相册 AVIF、BMP、GIF、HEIC、ICO、JPG、PNG、TIFF、WEBP、部分 RAW 文件。 200 MB
视频 3GP、3G2、ASF、AVI、DIVX、M2T、M2TS、M4V、MKV、MMV、MOD、MOV、MP4、MPG、MTS、TOD、WMV。 20 GB

第 1 步:上传字节

使用上传请求将字节上传到 Google。如果上传请求成功,则会返回原始文本字符串形式的上传令牌。使用这些上传令牌通过 batchCreate 调用创建媒体内容。

REST

在 POST 请求标头中添加以下字段:

标头字段
Content-type 设为 application/octet-stream
X-Goog-Upload-Content-Type 推荐。设置为您要上传的字节的 MIME 类型。 常见的 MIME 类型包括 image/jpegimage/pngimage/gif
X-Goog-Upload-Protocol 设为 raw

以下是 POST 请求标头:

POST https://photoslibrary.googleapis.com/v1/uploads
Authorization: Bearer oauth2-token
Content-type: application/octet-stream
X-Goog-Upload-Content-Type: mime-type
X-Goog-Upload-Protocol: raw

在请求正文中添加文件的二进制文件:

media-binary-data

如果此 POST 请求成功,则返回原始文本字符串形式的上传令牌作为响应正文。若要创建媒体内容,请在 batchCreate 调用中使用这些文本字符串。

upload-token

建议上传文件大小小于 50 MB 的图片。大于 50 MB 的文件容易出现效果不佳的问题。

Google Photos Library API 支持断点续传。借助断点续传,您可以将媒体文件拆分为多个部分,并一次上传一个部分。

第 2 步:创建媒体内容

上传媒体文件的字节后,您可以使用上传令牌在 Google 相册中将这些字节创建为媒体内容。上传令牌在创建后的一天内有效。您必须始终将媒体内容添加到用户的媒体库,媒体内容只能添加到应用创建的影集。如需了解详情,请参阅授权范围

如需创建新的媒体内容,请通过指定 newMediaItems 列表来调用 mediaItems.batchCreate。每个 newMediaItem 都包含一个在 simpleMediaItem 内指定的上传令牌,以及一个向用户显示的可选说明。

说明字段仅限 1000 个字符,并且只能包含用户创建的有意义的文本。例如,“我们的公园之旅”或“节日晚餐”。请勿添加文件名、程序化标记或其他自动生成的文本等元数据。

为达到最佳性能,请在一次调用中添加多项媒体内容,进而减少对 mediaItems.batchCreate 的调用次数。只有等待上一个请求完成后,您才能为同一用户进行后续调用。

您可以指定说明内容和相应的上传令牌,进而在用户的媒体库中创建单项媒体内容或多项媒体内容:

REST

以下是 POST 请求标头:

POST https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate
Content-type: application/json
Authorization: Bearer oauth2-token

请求正文应指定 newMediaItems 的列表。

{
  "newMediaItems": [
    {
      "description": "item-description",
      "simpleMediaItem": {
        "fileName": "filename",
        "uploadToken": "upload-token"
      }
    }
   , ...
  ]
}

您还可以指定 albumIdalbumPosition,进而在影集中的特定位置插入媒体内容。

REST

{
  "albumId": "album-id",
  "newMediaItems": [
    {
      "description": "item-description",
      "simpleMediaItem": {
        "fileName": "filename",
        "uploadToken": "upload-token"
      }
    }
    , ...
  ],
  "albumPosition": {
    "position": "after-media-item",
    "relativeMediaItemId": "media-item-id"
  }
}

有关在影集中定位的详情,请参阅添加扩展内容

内容创建响应

mediaItems.batchCreate 调用会返回您尝试创建的每项媒体内容的结果。newMediaItemResults 列表会指示请求状态并包含请求的 uploadToken。非零状态代码表示存在错误。

REST

如果已成功创建所有媒体内容,则请求将返回 HTTP 状态 200 OK。如果无法创建某些媒体内容,则请求将返回 HTTP 状态 207 MULTI-STATUS,表示部分内容创建成功。

{
  "newMediaItemResults": [
    {
      "uploadToken": "upload-token",
      "status": {
        "message": "Success"
      },
      "mediaItem": {
        "id": "media-item-id",
        "description": "item-description",
        "productUrl": "https://photos.google.com/photo/photo-path",
        "mimeType": "mime-type",
        "mediaMetadata": {
          "width": "media-width-in-px",
          "height": "media-height-in-px",
          "creationTime": "creation-time",
          "photo": {}
        },
        "filename": "filename"
      }
    },
    {
      "uploadToken": "upload-token",
      "status": {
        "code": 13,
        "message": "Internal error"
      }
    }
  ]
}

如果成功添加媒体内容,则系统会返回包含 mediaItemIdproductUrlmediaMetadatamediaItem。如需了解详情,请参阅访问媒体内容

如果媒体内容为视频,则必须先对其进行处理。mediaItemmediaMetadata 中包含 status,用于描述视频文件的处理状态。新上传的文件首先会返回 PROCESSING 状态,然后才能成为 READY 状态,以待使用。有关详情,请参阅访问媒体内容

如果您在此次调用中遇到错误,请按照最佳实践进行操作,然后重试请求。您可能想要跟踪成功的添加案例,以便在下一个请求期间将图片插入到影集的正确位置。如需了解详情,请参阅创建相册

返回结果的顺序始终与提交上传令牌的顺序相同。

上传方面的最佳实践

以下最佳实践和资源有助于提高上传的整体效率:

  • 遵循重试和错误处理最佳实践,同时牢记以下几点:
    • 如果您的配额已用尽,或者您因在短时间内调用次数过多而受到速率限制,则可能会出现 429 错误。请确保在上一个请求完成之前,您不会为同一用户调用 batchCreate
    • 429 错误需要至少 30s 的延迟时间才能重试。重试请求时,请使用指数退避算法策略。
    • 当服务器遇到错误时,会发生 500 错误。在上传时,这很可能是因为同时为同一用户进行了多次写入调用(例如 batchCreate)。检查请求的详细信息,请勿并行调用 batchCreate
  • 使用可续传上传流程可在网络中断的情况下提高上传的稳定性,并允许您恢复部分完成的上传,从而减少带宽使用量。从客户端移动设备上传文件或上传大型文件时,此功能非常重要。

此外,在上传流程的每个步骤中,请参考以下提示:上传字节,然后创建媒体项

上传字节

  • 上传字节(以检索上传令牌)可以并行完成。
  • 请务必在每次上传调用时,在 X-Goog-Upload-Content-Type 标头中设置正确的 MIME 类型。

创建媒体内容

  • 请勿针对单个用户并行调用 batchCreate

    • 对于每位用户,依次(串行)调用 batchCreate
    • 对于多个用户,请始终为每个用户依次进行 batchCreate 调用。仅针对不同用户并行发出调用。
  • 在每次对 batchCreate 的调用中,尽可能包含尽可能多的 NewMediaItems,以最大限度地减少您需要进行的调用总数。您最多可以添加 50 个项目。

  • 设置用户创建的有意义的说明文字。请勿在说明字段中添加文件名、程序化标记或其他自动生成的文字等元数据。

示例演示

此示例使用伪代码逐步演示如何为多位用户上传媒体项。本指南旨在概述上传流程的两个步骤(上传原始字节创建媒体内容),并详细介绍构建高效且富有弹性的上传集成方案的最佳实践。

第 1 步:上传原始字节

首先,创建一个队列,用于上传所有用户的媒体内容的原始字节。跟踪每位用户返回的每个 uploadToken。请记住以下要点:

  • 并发上传线程的数量取决于您的操作系统环境。
  • 根据需要考虑重新排序上传队列。例如,您可以根据每个用户的剩余上传次数、用户的总体进度或其他要求来确定上传的优先级。

伪代码

CREATE uploadQueue FROM users, filesToUpload
// Upload media bytes in parallel.
START multiple THREADS
  WHILE uploadQueue is not empty
    POP uploadQueue
    UPLOAD file for user
    GET uploadToken
    CHECK and HANDLE errors
    STORE uploadToken for user in uploadTokensQueue
  END

第 2 步:创建媒体项

在第 1 步中,您可以并行上传多位用户的多个字节,但在第 2 步中,您一次只能为每位用户进行一次调用。

伪代码

// For each user, create media items once 50 upload tokens have been
// saved, or no more uploads are left per user.
WHEN uploadTokensQueue for user is >= 50 OR no more pending uploads for user
  // Calls can be made in parallel for different users,
  // but only make a single call per user at a time.
  START new thread for (this) user if there is no thread yet
    POP 50 uploadTokens from uploadTokensQueue for user
    CALL mediaItems.batchCreate with uploadTokens
    WAIT UNTIL batchCreate call has completed
    CHECK and HANDLE errors (retry as needed)
  DONE.

继续执行此流程,直到所有上传和媒体创建调用都已完成。