미디어 업로드

미디어 항목 업로드는 두 단계로 이루어집니다.

  1. 업로드 엔드포인트를 사용하여 미디어 파일의 바이트를 Google 서버에 업로드합니다. 업로드된 바이트를 식별하는 업로드 토큰을 반환합니다.
  2. 업로드 토큰과 함께 batchCreate 호출을 사용하여 다음을 수행합니다. 사용자의 Google 포토 계정에서 미디어 항목을 만들 수 없습니다.

이 단계에서는 단일 미디어 항목을 업로드하는 프로세스를 간략하게 설명합니다. 만약 여러 미디어 항목 업로드 (모든 프로덕션 애플리케이션에서 가능성이 매우 높음) 업로드 권장사항을 검토하여 효율적으로 업로드할 수 있습니다.

시작하기 전에

필수 승인 범위

미디어 항목을 사용자의 라이브러리 또는 앨범에 업로드하려면 photoslibrary.appendonly 또는 photoslibrary 범위.

photoslibrary.sharing 범위를 사용하여 미디어 항목을 만들 수도 있습니다. 받는사람 photoslibrary.sharing 범위로 항목을 만들려면 먼저 shareAlbum을(를) 사용하여 해당 앨범을 공유한 것으로 표시합니다. 그런 다음 미디어 항목을 만들 수 있습니다. 앨범과 공유할 수 있습니다. 에서 바로 항목을 만들 수 없습니다. 앨범 또는 앱에서 공유하지 않은 앨범이 삭제됩니다.

앨범을 나열할 때 isWriteable 속성은 앨범을 나열할 것인지 애플리케이션에 특정 앨범에 대한 미디어를 만들 수 있는 액세스 권한이 있어야 합니다.

허용되는 파일 형식 및 크기

아래 표에 나열된 파일 형식을 업로드할 수 있습니다.

미디어 유형 허용되는 파일 형식 최대 파일 크기
사진 AVIF, BMP, GIF, HEIC, ICO, JPG, PNG, TIFF, WEBP, 일부 RAW 파일 200MB
동영상 3GP, 3G2, ASF, AVI, DIVX, M2T, M2TS, M4V, MKV, MMV, MOD, MOV, MP4, MPG, MTS, TOD, WMV. 20GB

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

자바

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

권장되는 이미지 파일 크기는 50MB 미만입니다. 50MB를 초과하는 파일은 성능 문제가 발생하기 쉽습니다.

Google 포토 라이브러리 API는 재개 가능한 업로드가 포함됩니다. 재개 가능한 업로드를 사용하면 미디어 파일을 여러 섹션으로 분할하여 하나의 동영상을 섹션을 하나씩 살펴보겠습니다.

2단계: 미디어 항목 만들기

미디어 파일의 바이트를 업로드한 후 미디어로 만들 수 있습니다. 항목을 업로드할 수 있습니다. 업로드 토큰이 유효함 생성 후 1일 동안 유지됩니다. 미디어 항목은 항상 사용자의 있습니다. 미디어 항목은 앨범에 추가됨 만들 수 있습니다. 자세한 내용은 승인 범위를 참조하세요.

새 미디어 항목을 만들려면 mediaItems.batchCreate 드림 목록을 지정하여 newMediaItemsnewMediaItem에는 업로드가 포함되어 있습니다. 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"
      }
    }
   , ...
  ]
}

자바

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

자바

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

자바

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

자바

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 mediaMetadata 내에 처리를 설명하는 status를 포함합니다. 동영상 파일의 상태입니다. 새로 업로드된 파일이 PROCESSING 상태를 반환합니다. 먼저 READY가 되기 전에 사용합니다. 자세한 내용은 미디어 항목에 액세스

통화 중에 오류가 발생하면 권장사항을 따르고 요청을 다시 시도하세요. 이미지가 삽입될 수 있도록 성공적으로 추가되었는지 추적하는 것이 좋습니다. 다음 요청 중에 올바른 위치에 있는 앨범으로 옮깁니다. 자세한 내용은 자세한 내용은 앨범 만들기

결과는 항상 업로드 토큰과 동일한 순서로 반환됩니다. 있습니다.

업로드 권장사항

다음 권장사항 및 리소스는 전반적인 효율성을 개선하는 데 도움이 됩니다. 업로드:

  • 지원되는 클라이언트 라이브러리 중 하나를 사용합니다.
  • 재시도 및 오류 처리 권장사항을 따릅니다. 다음 사항을 염두에 두세요. <ph type="x-smartling-placeholder">
      </ph>
    • 할당량이 소진되면 429 오류가 발생할 수 있습니다. 또는 너무 빨리 전화를 너무 많이 걸어 속도 제한이 있는 경우일 수 있습니다. 이전 코드가 호출될 때까지 동일한 사용자에 대해 batchCreate를 요청이 완료되었습니다.
    • 오류가 429개 발생했다면 다시 시도하기 전에 30s 이상 지연해야 합니다. 사용 지수 백오프 전략입니다.
    • 500 오류는 서버에 오류가 발생하면 발생합니다. 업로드할 때 여러 번 쓰기 호출 (예: batchCreate)를 동시에 사용할 수 있습니다. 다음 항목의 세부정보를 확인하세요. batchCreate를 동시에 호출하면 안 됩니다.
  • 재개 가능한 업로드 절차를 사용하여 네트워크가 중단되는 경우 더욱 안정적으로 업로드할 수 있도록 하여 부분적으로 완료된 업로드를 재개할 수 있습니다. 클라이언트 휴대기기에서 업로드할 때 중요합니다. 크게 다를 수 있습니다

또한 업로드 과정의 각 단계에서 다음 도움말을 참고하세요. 바이트 업로드미디어 항목 만들기를 참조하세요.

바이트 업로드 중

  • 업로드 토큰을 가져오기 위한 바이트 업로드는 동시에 수행할 수 있습니다.
  • X-Goog-Upload-Content-Type 헤더에 항상 올바른 MIME 유형을 설정합니다. 합니다.

미디어 항목 만들기

  • 단일 사용자에 대해 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.

모든 업로드와 미디어 제작 호출이 완료될 때까지 이 프로세스를 계속합니다.