Prześlij multimedia

Przesyłanie elementów multimedialnych składa się z dwóch etapów:

  1. Prześlij bajty plików multimedialnych na serwer Google za pomocą punktu końcowego przesyłania. Zwraca on token przesyłania, który identyfikuje przesłane bajty.
  2. Użyj wywołania BatchCreate z tokenem przesyłania, aby utworzyć element multimedialny na koncie użytkownika Zdjęć Google.

Poniżej opisujemy proces przesyłania pojedynczego elementu multimedialnego. Jeśli przesyłasz wiele elementów multimedialnych (jest to bardzo prawdopodobne w przypadku aplikacji produkcyjnych), zapoznaj się ze sprawdzonymi metodami przesyłania, aby poprawić wydajność przesyłania.

Zanim zaczniesz

Wymagane zakresy autoryzacji

Przesyłanie elementów multimedialnych do biblioteki lub albumu użytkownika wymaga zakresu photoslibrary.appendonly lub photoslibrary.

Elementy multimedialne można też tworzyć za pomocą zakresu photoslibrary.sharing. Aby utworzyć elementy z zakresem photoslibrary.sharing, musisz najpierw utworzyć album i oznaczyć go jako udostępniony za pomocą usługi shareAlbum. Następnie możesz utworzyć elementy multimedialne udostępnione użytkownikowi w albumie. Nie możesz tworzyć elementów bezpośrednio w bibliotece użytkownika ani w albumach, które nie zostały udostępnione przez aplikację.

Przy wyświetlaniu listy albumów właściwość isWriteable wskazuje, czy aplikacja ma dostęp do tworzenia multimediów w danym albumie.

Akceptowane typy i rozmiary plików

Możesz przesłać typy plików wymienione w tabeli poniżej.

Typ zawartości Akceptowane typy plików Maksymalny rozmiar pliku
Zdjęcia AVIF, BMP, GIF, HEIC, ICO, JPG, PNG, TIFF, WEBP i niektóre RAW. 200 MB
Filmy, 3GP, 3G2, ASF, AVI, DIVX, M2T, M2TS, M4V, MKV, MMV, MOD, MOV, MP4, MPG, MTS, TOD, WMV. 20 GB

Krok 1. Przesyłanie bajtów

Przesyłanie bajtów do Google za pomocą żądań przesyłania. Pomyślne żądanie przesłania danych zwraca token przesyłania w postaci nieprzetworzonego ciągu tekstowego. Użyj tych tokenów przesyłania, aby utworzyć elementy multimedialne za pomocą wywołania batchCreate.

REST

W nagłówku żądania POST uwzględnij te pola:

Pola nagłówka
Content-type Ustaw jako: application/octet-stream.
X-Goog-Upload-Content-Type Polecane, Ustaw typ MIME przesyłanych bajtów. Typowe typy MIME to image/jpeg, image/png i image/gif.
X-Goog-Upload-Protocol Ustaw jako: raw.

Oto nagłówek żądania 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

W treści żądania umieść plik binarny pliku:

media-binary-data

Jeśli żądanie POST zostanie zrealizowane, jako treść odpowiedzi zostanie zwrócony token przesyłania w postaci nieprzetworzonego ciągu tekstowego. Aby utworzyć elementy multimedialne, użyj tych ciągów tekstowych w wywołaniu 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
}

Sugerowany rozmiar pliku graficznego nie przekracza 50 MB. Pliki o wielkości ponad 50 MB mogą mieć problemy z wydajnością.

Interfejs Google Photos Library API obsługuje przesyłanie z możliwością wznawiania. Przesyłanie z możliwością wznawiania pozwala podzielić plik multimedialny na kilka sekcji i przesyłać po jednej sekcji naraz.

Krok 2. Tworzenie elementu multimedialnego

Po przesłaniu bajtów plików multimedialnych możesz je utworzyć jako elementy multimedialne w Zdjęciach Google, korzystając z tokenów przesyłania. Token przesyłania jest ważny przez 1 dzień po utworzeniu. Element multimedialny jest zawsze dodawany do biblioteki użytkownika. Elementy multimedialne można dodawać tylko do albumów utworzonych przez aplikację. Więcej informacji znajdziesz w artykule o zakresach autoryzacji.

Aby utworzyć nowe elementy multimedialne, wywołaj metodę mediaItems.batchCreate, podając listę właściwości newMediaItems. Każdy element newMediaItem zawiera token przesyłania określony w elemencie simpleMediaItem oraz opcjonalny opis wyświetlany użytkownikowi.

Pole opisu może zawierać maksymalnie 1000 znaków i powinno zawierać wyłącznie znaczący tekst stworzony przez użytkowników. Na przykład „Wycieczka do parku” lub „Świąteczna kolacja”. Nie podawaj metadanych, takich jak nazwy plików, tagów automatycznych ani innego generowanego automatycznie tekstu.

Aby uzyskać najlepszą skuteczność, zmniejsz liczbę wymaganych wywołań mediaItems.batchCreate, uwzględniając wiele elementów multimedialnych w jednym wywołaniu. Przed wykonaniem kolejnego wywołania dla tego samego użytkownika zawsze czekaj na zakończenie poprzedniego żądania.

W bibliotece użytkownika możesz utworzyć jeden element multimedialny lub wiele elementów multimedialnych, określając opisy i odpowiadające im tokeny przesyłania:

REST

Oto nagłówek żądania POST:

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

Treść żądania powinna zawierać listę 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
}


Możesz dodawać elementy multimedialne do biblioteki i albumu, określając album id. Więcej informacji znajdziesz w artykule Tworzenie albumów.

Każdy album może zawierać do 20 000 elementów multimedialnych. Żądania utworzenia w albumie elementów multimedialnych, które spowodowałyby przekroczenie tego limitu, będą nieudane.

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
}

Możesz też określić albumId i albumPosition, aby wstawić elementy multimedialne w konkretnym miejscu w albumie.

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
}

Więcej informacji na temat pozycjonowania w albumach znajdziesz w artykule Dodawanie wzbogacenia.

Odpowiedź na utworzenie elementu

Wywołanie mediaItems.batchCreate zwraca wynik dla każdego elementu multimedialnego, który próbujesz utworzyć. Lista newMediaItemResults wskazuje stan i zawiera element uploadToken żądania. Wartość inna niż zero oznacza błąd.

REST

Jeśli wszystkie elementy multimedialne zostały utworzone, żądanie zwraca stan HTTP 200 OK. Jeśli nie można utworzyć niektórych elementów multimedialnych, żądanie zwraca stan HTTP 207 MULTI-STATUS, co oznacza częściowy sukces.

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

Jeśli element zostanie dodany, zwrócony zostanie mediaItem zawierający właściwości mediaItemId, productUrl i mediaMetadata. Więcej informacji znajdziesz w artykule Dostęp do elementów multimedialnych.

Jeśli element multimedialny to film, musi zostać najpierw przetworzony. mediaItem zawiera w elemencie mediaMetadata element status, który opisuje stan przetwarzania pliku wideo. Nowo przesłany plik najpierw zwraca stan PROCESSING, a potem READY. Więcej informacji znajdziesz w artykule Uzyskiwanie dostępu do elementów multimedialnych.

Jeśli podczas rozmowy wystąpi błąd, postępuj zgodnie ze sprawdzonymi metodami i spróbuj jeszcze raz. Warto śledzić operacje dodawania zdjęć. Dzięki temu podczas następnej prośby będzie można wstawić obraz w albumie w odpowiednim miejscu. Więcej informacji znajdziesz w artykule Tworzenie albumów.

Wyniki są zawsze zwracane w takiej kolejności, w jakiej zostały przesłane tokeny przesyłania.

Sprawdzone metody przesyłania

Te sprawdzone metody i zasoby pomagają poprawić ogólną wydajność przesyłania:

  • Użyj jednej z obsługiwanych bibliotek klienta.
  • Postępuj zgodnie ze sprawdzonymi metodami dotyczącymi ponawiania próby i postępowania z błędami, pamiętając o tych kwestiach:
    • Błędy 429 mogą wystąpić, gdy wyczerpany limit został przekroczony lub masz ograniczoną częstotliwość wykonywania zbyt wielu połączeń. Pamiętaj, aby nie wywoływać funkcji batchCreate w przypadku tego samego użytkownika do momentu zrealizowania poprzedniego żądania.
    • Ponowienie próby wprowadzenia błędów (429) wymaga co najmniej 30s opóźnienia. Ponawianie żądań używaj strategii wykładniczego ponowienia.
    • Błędy 500 występują, gdy serwer napotka błąd. Podczas przesyłania najprawdopodobniej przyczyną jest kilku wywołań zapisu (np. batchCreate) dla tego samego użytkownika w tym samym czasie. Sprawdź szczegóły żądania i nie wykonuj równolegle wywołań funkcji batchCreate.
  • Użyj procesu wznawiania przesyłania, aby zwiększyć bezpieczeństwo przesyłania w przypadku przerw w działaniu sieci, ograniczając wykorzystanie przepustowości przez umożliwianie wznawiania częściowo zakończonych operacji. Jest to ważne w przypadku przesyłania z urządzeń mobilnych klienckich oraz podczas przesyłania dużych plików.

Na każdym etapie procesu przesyłania weź pod uwagę te wskazówki: przesyłanie bajtów, a następnie tworzenie elementów multimedialnych.

Przesyłam bajty

  • Przesyłanie bajtów (aby pobrać tokeny przesyłania) może być wykonywane równolegle.
  • W przypadku każdego wywołania przesyłania zawsze ustawiaj prawidłowy typ MIME w nagłówku X-Goog-Upload-Content-Type.

Tworzenie elementów multimedialnych

  • Nie wykonuj wywołań równolegle z funkcją batchCreate w przypadku pojedynczego użytkownika.

    • W przypadku każdego użytkownika wywołuj połączenia batchCreate jedno po drugim (po kolei).
    • W przypadku wielu użytkowników zawsze wykonuj wywołania batchCreate dla każdego użytkownika po kolei. Wykonuj równolegle wywołania tylko dla różnych użytkowników.
  • Aby zminimalizować łączną liczbę wywołań, uwzględnij jak najwięcej w każdym wywołaniu funkcji batchCreate.NewMediaItems Możesz dodać maksymalnie 50 elementów.

  • Ustaw zrozumiały tekst opisu utworzony przez użytkowników. W polu opisu nie umieszczaj metadanych takich jak nazwy plików, tagi automatyczne ani żadnego innego tekstu generowanego automatycznie.

Przykładowy przewodnik

W tym przykładzie pokazujemy, jak przesyłać elementy multimedialne wielu użytkownikom za pomocą pseudokodu. W tym celu omówimy oba etapy procesu przesyłania (przesyłanie nieprzetworzonych bajtów i tworzenie elementów multimedialnych) oraz sprawdzone metody efektywnej i odpornej integracji przesyłania.

Krok 1. Prześlij nieprzetworzone bajty

Najpierw utwórz kolejkę do przesłania nieprzetworzonych bajtów elementów multimedialnych od wszystkich użytkowników. Śledź zwrócone uploadToken na użytkownika. Pamiętaj o tych kluczowych kwestiach:

  • Liczba jednoczesnych wątków przesyłania zależy od środowiska operacyjnego.
  • W razie potrzeby zmień kolejność w kolejce przesyłania. Możesz na przykład ustawić priorytety przesyłania danych na podstawie liczby elementów do przesłania na użytkownika, ogólnych postępów użytkownika lub innych wymagań.

Pseudokod

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

Krok 2. Utwórz elementy multimedialne

W kroku 1 możesz równolegle przesłać wiele bajtów od wielu użytkowników, ale w kroku 2 możesz wykonać tylko 1 wywołanie dla każdego użytkownika naraz.

Pseudokod

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

Kontynuuj ten proces, aż wszystkie procesy przesyłania i tworzenia multimediów zostaną ukończone.