上傳媒體內容

上傳媒體項目包含兩個步驟:

  1. 使用上傳端點將媒體檔案的位元組上傳至 Google 伺服器。 這會傳回用來識別上傳位元組的上傳憑證。
  2. 使用 batchCreate 呼叫搭配上傳憑證,以便: 為使用者的 Google 相簿帳戶建立媒體項目。

以下步驟概述單一媒體項目的上傳程序。如果您是 上傳多個媒體項目 (非常可能適用於任何生產應用程式) 請參閱上傳的最佳做法,以改善 上傳效率

事前準備

必要的授權範圍

如要將媒體項目上傳至使用者的媒體庫或相簿,您必須有 photoslibrary.appendonlyphotoslibrary 範圍。

您也可以使用 photoslibrary.sharing 範圍建立媒體項目。目的地: 建立含有 photoslibrary.sharing 範圍的項目,您必須先建立 相簿,並使用 shareAlbum 將其標示為已分享。可用於建立媒體項目 與相簿中使用者分享的內容無法直接在 中建立項目 使用者的媒體庫或應用程式未分享的相簿。

列出相簿時,isWriteable 屬性會指出 應用程式擁有權限,可建立特定相簿的媒體。

接受的檔案類型和大小

您可以上傳下表列出的檔案類型。

媒體類型 接受的檔案類型 檔案大小上限
相片 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

Java

// Open the file and automatically close it after upload
try (RandomAccessFile file = new RandomAccessFile(pathToFile, "r")) {
  // Create a new upload request
  UploadMediaItemRequest uploadRequest =
      UploadMediaItemRequest.newBuilder()
              // The media type (e.g. "image/png")
              .setMimeType(mimeType)
              // The file to upload
              .setDataFile(file)
          .build();
  // Upload and capture the response
  UploadMediaItemResponse uploadResponse = photosLibraryClient.uploadMediaItem(uploadRequest);
  if (uploadResponse.getError().isPresent()) {
    // If the upload results in an error, handle it
    Error error = uploadResponse.getError().get();
  } else {
    // If the upload is successful, get the uploadToken
    String uploadToken = uploadResponse.getUploadToken().get();
    // Use this upload token to create a media item
  }
} catch (ApiException e) {
  // Handle error
} catch (IOException e) {
  // Error accessing the local file
}

PHP

try {
    // Create a new upload request by opening the file
    // and specifying the media type (e.g. "image/png")
    $uploadToken = $photosLibraryClient->upload(file_get_contents($localFilePath), null, $mimeType);
} catch (\GuzzleHttp\Exception\GuzzleException $e) {
    // Handle error
}

建議的圖片檔案大小不超過 50 MB。超過 50 MB 的檔案為 容易出現效能問題

Google Photos Library API 支援 支援續傳的上傳作業。支援續傳 上傳即可將媒體檔案分割成多個部分,然後 載入部分

步驟 2:建立媒體項目

上傳媒體檔案的位元組後,即可建立媒體檔案做為媒體檔案。 Google 相簿中的項目。上傳權杖有效 建立後一天媒體項目一律會加入使用者的 資源庫。媒體項目只能 已新增至相簿 您應用程式所建立的資料檢視詳情請參閱授權範圍

如要建立新的媒體項目,請呼叫 mediaItems.batchCreate敬上 方法是指定 newMediaItems 清單每個 newMediaItem 都包含一張上傳作業 在 simpleMediaItem 中指定的符記,並視需要提供說明 向使用者顯示的圖表

說明欄位的字數上限為 1,000 個字元,而且只能包含 讓使用者產生有意義的文字例如:「我們的公園之旅」或 「節慶晚餐」。請勿加入檔案名稱、程式輔助格式等中繼資料 標記或其他自動產生的文字。

為獲得最佳效能,請減少對 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"
      }
    }
   , ...
  ]
}

Java

try {
  // Create a NewMediaItem with the following components:
  // - uploadToken obtained from the previous upload request
  // - filename that will be shown to the user in Google Photos
  // - description that will be shown to the user in Google Photos
  NewMediaItem newMediaItem = NewMediaItemFactory
          .createNewMediaItem(uploadToken, fileName, itemDescription);
  List<NewMediaItem> newItems = Arrays.asList(newMediaItem);

  BatchCreateMediaItemsResponse response = photosLibraryClient.batchCreateMediaItems(newItems);
  for (NewMediaItemResult itemsResponse : response.getNewMediaItemResultsList()) {
    Status status = itemsResponse.getStatus();
    if (status.getCode() == Code.OK_VALUE) {
      // The item is successfully created in the user's library
      MediaItem createdItem = itemsResponse.getMediaItem();
    } else {
      // The item could not be created. Check the status and try again
    }
  }
} catch (ApiException e) {
  // Handle error
}

PHP

try {
    $newMediaItems = [];
    // Create a NewMediaItem with the following components:
    // - uploadToken obtained from the previous upload request
    // - filename that will be shown to the user in Google Photos
    // - description that will be shown to the user in Google Photos
    $newMediaItems[0] = PhotosLibraryResourceFactory::newMediaItemWithDescriptionAndFileName(
            $uploadToken, $itemDescription, $fileName);

    $response = $photosLibraryClient->batchCreateMediaItems($newMediaItems);
    foreach ($response->getNewMediaItemResults() as $itemResult) {
        $status = $itemResult->getStatus();
        if ($status->getCode() != Code::OK) {
            // Error while creating the item.
        }
    }
} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}


如要將媒體項目新增到媒體庫和相簿,請指定 專輯《id》。若需更多資訊,請參閲 建立相簿

每個相簿最多可包含 20,000 個媒體項目。建立媒體的要求 超出此上限的相簿中,項目會失敗。

REST

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

Java

try {
  // Create new media items in a specific album
  BatchCreateMediaItemsResponse response = photosLibraryClient
      .batchCreateMediaItems(albumId, newItems);
  // Check the response
} catch (ApiException e) {
  // Handle error
}

PHP

try {
    $response = $photosLibraryClient->batchCreateMediaItems($newMediaItems, ['albumId' => $albumId]);
} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}

也可以將 albumIdalbumPosition 指定 在相簿的特定位置插入媒體項目。

REST

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

Java

try {
  // Create new media items in a specific album, positioned after a media item
  AlbumPosition positionInAlbum = AlbumPositionFactory.createFirstInAlbum();
  BatchCreateMediaItemsResponse response = photosLibraryClient
      .batchCreateMediaItems(albumId, newItems, positionInAlbum);
  // Check the response
} catch (ApiException e) {
  // Handle error
}

PHP

try {
    $albumPosition = PhotosLibraryResourceFactory::albumPositionAfterMediaItem($mediaItemId);
    $response = $photosLibraryClient->batchCreateMediaItems($newMediaItems,
        ['albumId' => $albumId, 'albumPosition' => $albumPosition]);
} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}

如要進一步瞭解相簿位置,請參閱 新增擴充功能

商品建立回應

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"
      }
    }
  ]
}

Java

BatchCreateMediaItemsResponse response = photosLibraryClient.batchCreateMediaItems(newItems);

// The response contains a list of NewMediaItemResults
for (NewMediaItemResult result : response.getNewMediaItemResultsList()) {
  // Each result item is identified by its uploadToken
  String uploadToken = result.getUploadToken();
  Status status = result.getStatus();

  if (status.getCode() == Code.OK_VALUE) {
    // If the request is successful, a MediaItem is returned
    MediaItem mediaItem = result.getMediaItem();
    String id = mediaItem.getId();
    String productUrl = mediaItem.getProductUrl();
    // ...
  }
}

PHP

// The response from a call to batchCreateMediaItems returns a list of NewMediaItemResults
foreach ($response->getNewMediaItemResults() as $itemResult) {
    // Each result item is identified by its uploadToken
    $itemUploadToken = $itemResult->getUploadToken();
    // Verify the status of each entry to ensure that the item has been uploaded correctly
    $itemStatus = $itemResult->getStatus();
    if ($itemStatus->getCode() != Code::OK) {
        // Error when item is being created
    } else {
        // Media item is successfully created
        // Get the MediaItem object from the response
        $mediaItem = $itemResult->getMediaItem();
        // It contains details such as the Id of the item, productUrl
        $id = $mediaItem->getId();
        $productUrl = $mediaItem->getProductUrl();
        // ...
    }
}

如果成功新增項目,系統會傳回包含下列內容的 mediaItem mediaItemIdproductUrlmediaMetadata。若需更多資訊,請參閲 存取媒體項目

如果媒體項目是影片,則必須先處理。mediaItemmediaMetadata 包含 status,用於說明處理程序 影片檔案的狀態新上傳的檔案會傳回 PROCESSING 狀態 才是 READY。詳情請參閱 存取媒體項目

如果系統在這場通話期間發生錯誤,請按照 最佳做法並重試要求。 建議你追蹤新增成功的項目 下一次要求時,移到相簿的正確位置上。如要 資訊,請參閱 建立相簿

傳回結果的順序一律會與上傳權杖相同 就會引發這個事件。

上傳最佳做法

下列最佳做法和資源有助於提升整體效率 上傳的影片:

  • 使用我們支援的其中一個用戶端程式庫
  • 遵循重試和錯誤處理最佳做法。 請記住以下要點:
    • 如果配額用盡,就可能出現 429 個錯誤 或是因太快撥打太多電話而受到限制請確認 您必須等到上一個batchCreate 執行完畢。
    • 429 個錯誤至少需要 30s 延遲時間才能重試。使用 指數輪詢 自動處理策略
    • 伺服器發生錯誤時,發生 500 錯誤。上傳時 這很可能是因為發出多次寫入呼叫 (例如 batchCreate)。查看 ,且不要同時呼叫 batchCreate
  • 使用支援續傳的流程 可讓您在網路服務中斷時更穩健地上傳 減少頻寬用量。 從用戶端行動裝置上傳時,這點非常重要 在上傳大型檔案時特別留意

至於上傳程序的各個步驟,也請考慮下列提示: 上傳位元組,然後建立媒體項目

上傳位元組

建立媒體項目

  • 請勿為單一使用者同時呼叫 batchCreate

    • 針對每個使用者,逐一呼叫 batchCreate (在 序列)。
    • 為多位使用者,一律為每位使用者發出 batchCreate 呼叫 字詞。只同時呼叫「不同的使用者」
  • 加入越多NewMediaItems越好 每次呼叫 batchCreate 以盡量減少通話總數 。您最多可以加入 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.

請繼續進行這個程序,直到所有上傳和媒體建立呼叫都完成為止。