Tải lên phương tiện

Tải các mục nội dung nghe nhìn lên là quá trình gồm hai bước:

  1. Tải các byte của tệp nội dung nghe nhìn lên một Máy chủ Google bằng cách sử dụng điểm cuối tải lên. Thao tác này sẽ trả về một mã thông báo tải lên giúp xác định các byte đã tải lên.
  2. Sử dụng lệnh gọi dumpCreate với mã thông báo tải lên để tạo một mục nội dung nghe nhìn trong tài khoản Google Photos của người dùng.

Các bước này phác thảo quy trình tải một mục nội dung đa phương tiện lên. Nếu bạn đang tải nhiều mục nội dung đa phương tiện lên (rất có thể cho mọi ứng dụng phát hành chính thức), hãy xem lại các phương pháp hay nhất để tải lên để cải thiện hiệu quả tải lên.

Trước khi bắt đầu

Phạm vi uỷ quyền bắt buộc

Việc tải các mục nội dung đa phương tiện lên thư viện hoặc album của người dùng cần phải có phạm vi photoslibrary.appendonly hoặc photoslibrary.

Bạn cũng có thể tạo các mục nội dung đa phương tiện bằng phạm vi photoslibrary.sharing. Để tạo các mục có phạm vi photoslibrary.sharing, trước tiên, bạn phải tạo một album và đánh dấu album đó là đã chia sẻ bằng shareAlbum. Sau đó, bạn có thể tạo các mục nội dung nghe nhìn để chia sẻ với người dùng trong album. Bạn không thể tạo các mục trực tiếp trong thư viện của người dùng hoặc trong những album mà ứng dụng của bạn chưa chia sẻ.

Khi liệt kê album, thuộc tính isWriteable cho biết liệu ứng dụng của bạn có quyền truy cập để tạo nội dung nghe nhìn trong một album cụ thể hay không.

Kích thước và loại tệp được chấp nhận

Bạn có thể tải lên các loại tệp được liệt kê trong bảng bên dưới.

Loại nội dung nghe nhìn Các loại tệp được chấp nhận Kích thước tệp tối đa
Photos AVIF, BMP, GIF, HEIC, ICO, JPG, PNG, TIFF, WEBP, một số tệp RAW. 200 MB
Video 3GP, 3G2, ASF, AVI, DIVX, M2T, M2TS, M4V, MKV, MMV, MOD, MOV, MP4, MPG, MTS, TOD, WMV. 20 GB

Bước 1: Tải các byte lên

Tải byte lên Google bằng cách sử dụng yêu cầu tải lên. Yêu cầu tải lên thành công sẽ trả về mã thông báo tải lên ở dạng chuỗi văn bản thô. Hãy sử dụng các mã thông báo tải lên này để tạo các mục nội dung đa phương tiện bằng lệnh gọi batchCreate.

Kiến trúc chuyển trạng thái đại diện (REST)

Đưa các trường sau vào tiêu đề của yêu cầu POST:

Trường tiêu đề
Content-type Đặt thành application/octet-stream.
X-Goog-Upload-Content-Type Nên dùng. Đặt thành loại MIME của byte mà bạn đang tải lên. Các loại MIME phổ biến bao gồm image/jpeg, image/pngimage/gif.
X-Goog-Upload-Protocol Đặt thành raw.

Dưới đây là tiêu đề của yêu cầu 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

Trong nội dung yêu cầu, hãy thêm tệp nhị phân của tệp:

media-binary-data

Nếu yêu cầu POST này thành công, mã thông báo tải lên ở dạng chuỗi văn bản thô sẽ được trả về dưới dạng nội dung phản hồi. Để tạo các mục nội dung đa phương tiện, hãy sử dụng những chuỗi văn bản này trong lệnh gọi 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
}

1.199

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
}

Kích thước tệp đề xuất cho hình ảnh là dưới 50 MB. Những tệp trên 50 MB dễ gặp vấn đề về hiệu suất.

API thư viện Google Photos hỗ trợ quá trình tải lên tiếp nối. Quá trình tải lên tiếp nối cho phép bạn chia tệp đa phương tiện thành nhiều phần và tải từng phần một.

Bước 2: Tạo mục nội dung nghe nhìn

Sau khi tải các byte của tệp nội dung nghe nhìn lên, bạn có thể tạo các tệp đó dưới dạng mục nội dung nghe nhìn trong Google Photos bằng mã thông báo tải lên. Mã thông báo tải lên sẽ có hiệu lực trong một ngày sau khi tạo. Mục nội dung đa phương tiện luôn được thêm vào thư viện của người dùng. Bạn chỉ có thể thêm các mục nội dung đa phương tiện vào album do ứng dụng của bạn tạo. Để biết thêm thông tin, hãy xem bài viết Phạm vi uỷ quyền.

Để tạo các mục nội dung nghe nhìn mới, hãy gọi mediaItems.batchCreate bằng cách chỉ định danh sách newMediaItems. Mỗi newMediaItem chứa một mã tải lên được chỉ định bên trong simpleMediaItem và một nội dung mô tả không bắt buộc hiển thị cho người dùng.

Trường nội dung mô tả chỉ được dài tối đa 1.000 ký tự và chỉ được bao gồm văn bản có ý nghĩa do người dùng tạo. Ví dụ: "Chuyến đi đến công viên của chúng tôi" hoặc "Bữa tối ngày lễ". Đừng thêm siêu dữ liệu như tên tệp, thẻ có lập trình hoặc văn bản được tạo tự động khác.

Để có hiệu suất tốt nhất, hãy giảm số lượng lệnh gọi đến mediaItems.batchCreate mà bạn phải thực hiện bằng cách đưa nhiều mục nội dung nghe nhìn vào một lệnh gọi. Luôn đợi cho đến khi yêu cầu trước đó hoàn tất trước khi thực hiện lệnh gọi tiếp theo cho cùng một người dùng.

Bạn có thể tạo một mục nội dung đa phương tiện hoặc nhiều mục nội dung đa phương tiện trong thư viện của người dùng bằng cách chỉ định nội dung mô tả và mã thông báo tải lên tương ứng:

Kiến trúc chuyển trạng thái đại diện (REST)

Dưới đây là tiêu đề của yêu cầu POST:

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

Nội dung yêu cầu phải chỉ định danh sách 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
}

1.199

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
}


Bạn có thể thêm các mục nội dung nghe nhìn vào thư viện và một album bằng cách chỉ định album id. Để biết thêm thông tin, hãy xem phần Tạo album.

Mỗi album có thể chứa tối đa 20.000 mục nội dung nghe nhìn. Yêu cầu tạo mục nội dung nghe nhìn trong một album vượt quá giới hạn này sẽ không thành công.

Kiến trúc chuyển trạng thái đại diện (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
}

1.199

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

Bạn cũng có thể chỉ định albumIdalbumPosition để chèn các mục nội dung nghe nhìn tại một vị trí cụ thể trong album.

Kiến trúc chuyển trạng thái đại diện (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
}

1.199

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

Để biết thêm thông tin chi tiết về việc đặt vị trí trong album, hãy xem phần Thêm tính năng bổ sung.

Phản hồi khi tạo mục

Lệnh gọi mediaItems.batchCreate trả về kết quả cho từng mục nội dung đa phương tiện mà bạn đã cố gắng tạo. Danh sách newMediaItemResults cho biết trạng thái và bao gồm uploadToken cho yêu cầu. Mã trạng thái khác 0 cho biết có lỗi.

Kiến trúc chuyển trạng thái đại diện (REST)

Nếu tất cả các mục nội dung đa phương tiện đã được tạo thành công, yêu cầu sẽ trả về trạng thái HTTP 200 OK. Nếu không thể tạo một số mục nội dung đa phương tiện, yêu cầu sẽ trả về trạng thái HTTP 207 MULTI-STATUS để cho biết thành công một phần.

{
  "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();
    // ...
  }
}

1.199

// 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();
        // ...
    }
}

Nếu đã thêm thành công một mục, mediaItem sẽ được trả về chứa mediaItemId, productUrlmediaMetadata. Để biết thêm thông tin, hãy xem phần Truy cập vào các mục nội dung đa phương tiện.

Nếu mục nội dung đa phương tiện là video, trước tiên, mục đó phải được xử lý. mediaItem chứa status bên trong mediaMetadata mô tả trạng thái xử lý của tệp video. Tệp mới tải lên sẽ trả về trạng thái PROCESSING trước, trước khi tệp được READY để sử dụng. Để biết thông tin chi tiết, hãy xem phần Truy cập vào các mục nội dung nghe nhìn.

Nếu bạn gặp lỗi trong khi gọi, hãy làm theo Các phương pháp hay nhất rồi thử yêu cầu lại. Bạn nên theo dõi những lần thêm thành công, nhờ đó, bạn có thể chèn hình ảnh vào album ở đúng vị trí trong yêu cầu tiếp theo. Để biết thêm thông tin, hãy xem phần Tạo album.

Kết quả luôn được trả về theo cùng thứ tự mã thông báo tải lên được gửi.

Các phương pháp hay nhất để tải video lên

Các phương pháp hay nhất và tài nguyên sau đây giúp bạn cải thiện hiệu quả tổng thể bằng cách tải lên:

  • Dùng một trong những thư viện ứng dụng mà chúng tôi hỗ trợ.
  • Làm theo các phương pháp hay nhất về thử lại và xử lý lỗi, đồng thời lưu ý những điểm sau:
    • Lỗi 429 có thể xảy ra khi hạn mức của bạn đã bị phóng đại hoặc bạn bị giới hạn tốc độ do thực hiện quá nhiều lệnh gọi quá nhanh. Hãy đảm bảo bạn không gọi batchCreate cho cùng một người dùng cho đến khi yêu cầu trước đó đã hoàn tất.
    • 429 lỗi yêu cầu độ trễ tối thiểu là 30s trước khi thử lại. Sử dụng chiến lược thời gian đợi luỹ thừa khi thử lại các yêu cầu.
    • 500 lỗi xảy ra khi máy chủ gặp lỗi. Khi bạn tải lên, điều này rất có thể là do thực hiện nhiều lệnh gọi ghi (chẳng hạn như batchCreate) cho cùng một người dùng cùng lúc. Kiểm tra thông tin chi tiết về yêu cầu của bạn và không thực hiện song song các lệnh gọi đến batchCreate.
  • Sử dụng quy trình tải lên tiếp nối để giúp quá trình tải lên hoạt động mạnh mẽ hơn trong trường hợp bị gián đoạn mạng, giảm mức sử dụng băng thông bằng cách cho phép bạn tiếp tục tải lên theo cách tương tự. Điều này rất quan trọng khi tải lên từ thiết bị di động của ứng dụng hoặc khi tải các tệp có kích thước lớn lên.

Ngoài ra, hãy xem xét các mẹo sau cho mỗi bước của quy trình tải lên: tải byte lên rồi tạo mục nội dung nghe nhìn.

Đang tải byte lên

  • Có thể thực hiện song song quá trình tải các byte lên (để truy xuất mã thông báo đã tải lên).
  • Luôn đặt đúng loại MIME trong tiêu đề X-Goog-Upload-Content-Type cho mỗi lệnh gọi tải lên.

Tạo mục nội dung nghe nhìn

  • Không thực hiện lệnh gọi song song với batchCreate cho một người dùng.

    • Đối với mỗi người dùng, hãy lần lượt thực hiện các lệnh gọi đến batchCreate (trong chuỗi).
    • Đối với nhiều người dùng, hãy luôn thực hiện lệnh gọi batchCreate cho từng người dùng. Chỉ thực hiện song song cuộc gọi cho những người dùng khác nhau.
  • Đưa nhiều NewMediaItems nhất có thể vào mỗi lệnh gọi đến batchCreate để giảm thiểu tổng số lệnh gọi bạn phải thực hiện. Bạn có thể thêm tối đa 50 mục.

  • Đặt một văn bản mô tả có ý nghĩa do người dùng của bạn tạo. Đừng đưa siêu dữ liệu như tên tệp, thẻ có lập trình hoặc văn bản được tạo tự động khác vào trường nội dung mô tả.

Hướng dẫn từng bước mẫu

Ví dụ này sử dụng mã giả để hướng dẫn quá trình tải các mục nội dung đa phương tiện lên cho nhiều người dùng. Mục tiêu là phác thảo cả hai bước của quy trình tải lên (tải byte thô lêntạo các mục nội dung đa phương tiện), đồng thời nêu chi tiết các phương pháp hay nhất để tích hợp quá trình tải lên hiệu quả và bền bỉ.

Bước 1: Tải lên byte thô

Trước tiên, hãy tạo một hàng đợi để tải các byte thô lên cho các mục nội dung đa phương tiện từ tất cả người dùng của bạn. Theo dõi từng uploadToken được trả về trên mỗi người dùng. Hãy nhớ những điểm chính sau:

  • Số lượng luồng tải lên đồng thời phụ thuộc vào môi trường hoạt động của bạn.
  • Hãy cân nhắc việc sắp xếp lại danh sách chờ tải lên nếu cần. Ví dụ: bạn có thể ưu tiên các tệp tải lên dựa trên số lượt tải lên còn lại trên mỗi người dùng, tiến trình tổng thể của người dùng hoặc các yêu cầu khác.

Mã giả

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

Bước 2: Tạo mục nội dung nghe nhìn

Ở bước 1, bạn có thể tải song song nhiều byte từ nhiều người dùng lên, nhưng ở bước 2, bạn chỉ có thể thực hiện một lệnh gọi duy nhất cho mỗi người dùng tại một thời điểm.

Mã giả

// 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.

Tiếp tục quá trình này cho đến khi tất cả các lượt tải lên và lệnh gọi tạo nội dung nghe nhìn đã hoàn tất.