อัปโหลดสื่อ

การอัปโหลดรายการสื่อมี 2 ขั้นตอน ดังนี้

  1. อัปโหลดไบต์ของไฟล์สื่อไปยังเซิร์ฟเวอร์ของ Google โดยใช้ปลายทางการอัปโหลด ซึ่งจะแสดงโทเค็นการอัปโหลดซึ่งระบุไบต์ที่อัปโหลด
  2. ใช้การเรียกใช้batchCreate กับโทเค็นการอัปโหลดเพื่อสร้างรายการสื่อในบัญชี Google Photos ของผู้ใช้

ขั้นตอนเหล่านี้ระบุขั้นตอนการอัปโหลดสื่อรายการเดียว หากคุณอัปโหลดรายการสื่อหลายรายการ (มีแนวโน้มสูงสำหรับแอปพลิเคชันเวอร์ชันที่ใช้งานจริง) โปรดอ่านแนวทางปฏิบัติแนะนำสำหรับการอัปโหลดเพื่อปรับปรุงประสิทธิภาพการอัปโหลด

ก่อนเริ่มต้น

ขอบเขตการให้สิทธิ์ที่จำเป็น

การอัปโหลดรายการสื่อไปยังคลังหรืออัลบั้มของผู้ใช้ต้องใช้ขอบเขต photoslibrary.appendonly หรือ photoslibrary

คุณสามารถสร้างรายการสื่อโดยใช้ขอบเขต photoslibrary.sharing ได้ด้วย หากต้องการสร้างรายการที่มีขอบเขต photoslibrary.sharing ก่อนอื่นคุณต้องสร้างอัลบั้มและทำเครื่องหมายว่าแชร์โดยใช้ shareAlbum คุณสามารถสร้างรายการสื่อ ที่แชร์กับผู้ใช้ในอัลบั้มได้ คุณไม่สามารถสร้างรายการใน ไลบรารีของผู้ใช้โดยตรง หรือในอัลบั้มที่แอปไม่ได้แชร์

เมื่อแสดงรายการอัลบั้ม พร็อพเพอร์ตี้ isWriteable จะระบุว่าแอปพลิเคชันของคุณมีสิทธิ์เข้าถึงเพื่อสร้างสื่อในอัลบั้มใดอัลบั้มหนึ่งหรือไม่

ประเภทและขนาดของไฟล์ที่ยอมรับ

คุณอัปโหลดประเภทไฟล์ที่แสดงในตารางด้านล่างได้

ประเภทสื่อ ประเภทไฟล์ที่ยอมรับ ขนาดไฟล์สูงสุด
Photos 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/jpeg, image/png และ image/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 Photos โดยใช้โทเค็นการอัปโหลดได้ โทเค็นการอัปโหลดจะใช้งานได้ 1 วันหลังจากสร้าง รายการสื่อจะเพิ่มลงใน ไลบรารีของผู้ใช้เสมอ รายการสื่อสามารถ เพิ่มในอัลบั้ม ที่แอปของคุณสร้างขึ้นเท่านั้น ดูข้อมูลเพิ่มเติมได้ที่ขอบเขตการให้สิทธิ์

หากต้องการสร้างรายการสื่อใหม่ ให้เรียกใช้ 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
}

นอกจากนี้คุณยังระบุ albumId และ albumPosition เพื่อแทรกรายการสื่อในตำแหน่งที่เจาะจงในอัลบั้มได้ด้วย

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 สำหรับคำขอ รหัสสถานะที่ไม่เป็น 0 จะระบุข้อผิดพลาด

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 ที่มี mediaItemId, productUrl และ mediaMetadata ดูข้อมูลเพิ่มเติมได้ที่เข้าถึงรายการสื่อ

หากรายการสื่อเป็นวิดีโอ จะต้องประมวลผลรายการก่อน mediaItem มี status ภายใน mediaMetadata ที่อธิบายสถานะการประมวลผลของไฟล์วิดีโอ ไฟล์ที่อัปโหลดใหม่จะแสดงสถานะ PROCESSING ก่อน สถานะจะเป็น READY โปรดดูรายละเอียดที่เข้าถึงรายการสื่อ

หากพบข้อผิดพลาดในระหว่างการโทร ให้ทำตามแนวทางปฏิบัติที่ดีที่สุด และลองส่งคำขออีกครั้ง คุณอาจต้องการติดตามการเพิ่มที่ดำเนินการสำเร็จ เพื่อให้แทรกรูปภาพลงในอัลบั้มในตำแหน่งที่ถูกต้องได้ขณะส่งคำขอถัดไป ดูข้อมูลเพิ่มเติมได้ที่สร้างอัลบั้ม

ผลลัพธ์จะส่งกลับในลำดับเดียวกันกับที่มีการส่งโทเค็นการอัปโหลดเสมอ

แนวทางปฏิบัติแนะนำสำหรับการอัปโหลด

แนวทางปฏิบัติแนะนำและแหล่งข้อมูลต่อไปนี้จะช่วยปรับปรุงประสิทธิภาพโดยรวมด้วยการอัปโหลด

  • ใช้ไลบรารีของไคลเอ็นต์ที่รองรับ
  • ทำตามแนวทางปฏิบัติแนะนำในการลองอีกครั้งและการจัดการข้อผิดพลาด โดยคํานึงถึงประเด็นต่อไปนี้
    • ข้อผิดพลาด 429 รายการอาจเกิดขึ้นเมื่อโควต้าของคุณหมดลง หรือถูกจํากัดอัตราการโทรจากการโทรเร็วเกินไป โปรดอย่าเรียกใช้ batchCreate สำหรับผู้ใช้รายเดียวกันจนกว่าคำขอก่อนหน้านี้จะเสร็จสมบูรณ์
    • ข้อผิดพลาด 429 รายการต้องล่าช้าอย่างน้อย 30s ก่อนที่จะลองอีกครั้ง ใช้กลยุทธ์ Exponential Backoff เมื่อลองส่งคำขออีกครั้ง
    • 500 เกิดขึ้นเมื่อเซิร์ฟเวอร์พบข้อผิดพลาด ขณะอัปโหลด สาเหตุที่เป็นไปได้มากที่สุดคือเกิดจากการโทรเขียนหลายครั้ง (เช่น batchCreate) สำหรับผู้ใช้รายเดียวกันพร้อมกัน โปรดตรวจสอบรายละเอียดคำขอและอย่าโทรไปที่ batchCreate พร้อมกัน
  • ใช้ขั้นตอนการอัปโหลดที่ดำเนินการต่อได้เพื่อทำให้การอัปโหลดมีประสิทธิภาพมากขึ้นในกรณีที่เครือข่ายขัดข้อง และลดการใช้แบนด์วิดท์โดยช่วยให้คุณดำเนินการอัปโหลดที่เสร็จสมบูรณ์บางส่วนต่อได้ ซึ่งเป็นสิ่งสำคัญเมื่ออัปโหลดจากอุปกรณ์เคลื่อนที่ของไคลเอ็นต์ หรือเมื่ออัปโหลดไฟล์ขนาดใหญ่

พิจารณาเคล็ดลับต่อไปนี้สําหรับแต่ละขั้นตอนของกระบวนการอัปโหลด ได้แก่ การอัปโหลดไบต์และการสร้างรายการสื่อ

จำนวนไบต์ที่อัปโหลด

  • คุณสามารถอัปโหลดไบต์ (เพื่อเรียกโทเค็นการอัปโหลด) พร้อมกันได้
  • โปรดตั้งค่าประเภท MIME ที่ถูกต้องในส่วนหัว X-Goog-Upload-Content-Type สำหรับการเรียกการอัปโหลดแต่ละครั้งเสมอ

การสร้างรายการสื่อ

  • อย่าโทรออกพร้อมกับ batchCreate สำหรับผู้ใช้รายเดียว

    • สำหรับผู้ใช้แต่ละราย ให้โทรหา batchCreate ทีละคน (ตามลำดับ)
    • สำหรับผู้ใช้หลายราย ให้โทร batchCreate สำหรับผู้ใช้แต่ละรายพร้อมกันทุกครั้ง โทรหาผู้ใช้ที่ต่างกันพร้อมกันเท่านั้น
  • ระบุจำนวน NewMediaItems ให้มากที่สุดในการโทรแต่ละครั้งไปยัง batchCreate เพื่อลดจำนวนการโทรทั้งหมดที่คุณต้องโทรออก คุณสามารถใส่ได้สูงสุด 50 รายการ

  • กำหนดข้อความคำอธิบายที่มีความหมายซึ่งผู้ใช้สร้างขึ้น อย่ารวมข้อมูลเมตา เช่น ชื่อไฟล์ แท็กแบบเป็นโปรแกรม หรือข้อความที่สร้างขึ้นโดยอัตโนมัติอื่นๆ ไว้ในช่องคำอธิบาย

คำแนะนำแบบทีละขั้น

ตัวอย่างนี้ใช้ Pseudocode เพื่อช่วยในการอัปโหลดรายการสื่อสำหรับผู้ใช้หลายราย เป้าหมายคือการระบุขั้นตอนทั้ง 2 ขั้นตอนของกระบวนการอัปโหลด (การอัปโหลดไบต์ดิบและการสร้างรายการสื่อ) และอธิบายรายละเอียดแนวทางปฏิบัติแนะนำในการสร้างการผสานรวมการอัปโหลดที่มีประสิทธิภาพและยืดหยุ่น

ขั้นตอนที่ 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.

ทำขั้นตอนนี้ต่อไปจนกว่าการอัปโหลดและการเรียกใช้การสร้างสื่อทั้งหมดจะเสร็จสมบูรณ์