Carica contenuti multimediali

Il caricamento di elementi multimediali è una procedura a due fasi:

  1. Carica i byte dei file multimediali su un server Google utilizzando l'endpoint di caricamento. Questo restituisce un token di caricamento che identifica i byte caricati.
  2. Utilizza una chiamata batchCreate con il token di caricamento per creare un elemento multimediale nell'account Google Foto dell'utente.

Questi passaggi descrivono la procedura di caricamento di un singolo elemento multimediale. Se carichi più elementi multimediali (molto probabilmente per qualsiasi applicazione di produzione), consulta le best practice per i caricamenti per migliorare l'efficienza del caricamento.

Prima di iniziare

Ambiti di autorizzazione obbligatori

Il caricamento di elementi multimediali nella raccolta o nell'album di un utente richiede l'ambito photoslibrary.appendonly o photoslibrary.

Puoi creare elementi multimediali anche utilizzando l'ambito photoslibrary.sharing. Per creare elementi con l'ambito photoslibrary.sharing, devi prima creare un album e contrassegnarlo come condiviso utilizzando shareAlbum. Puoi quindi creare elementi multimediali che vengono condivisi con l'utente nell'album. Non puoi creare elementi direttamente nella raccolta dell'utente o in album non condivisi dalla tua app.

Quando elenchi gli album, la proprietà isWriteable indica se la tua applicazione ha accesso alla creazione di contenuti multimediali in un determinato album.

Dimensioni e tipi di file accettati

Puoi caricare i tipi di file elencati nella tabella seguente.

Tipo multimediale Tipi di file accettati Dimensione massima del file
Foto AVIF, BMP, GIF, HEIC, ICO, JPG, PNG, TIFF, WEBP, alcuni file RAW. 200 MB
Video 3GP, 3G2, ASF, AVI, DIVX, M2T, M2TS, M4V, MKV, MMV, MOD, MOV, MP4, MPG, MTS, TOD, WMV. 20 GB

Passaggio 1: caricamento dei byte

Carica i byte su Google utilizzando le richieste di caricamento. Una richiesta di caricamento riuscito restituisce un token di caricamento sotto forma di stringa di testo non elaborata. Utilizza questi token di caricamento per creare elementi multimediali con la chiamata batchCreate.

REST

Includi i seguenti campi nell'intestazione della richiesta POST:

Campi intestazione
Content-type Da impostare su application/octet-stream.
X-Goog-Upload-Content-Type Consigliati Imposta il tipo MIME dei byte da caricare. I tipi MIME comuni includono image/jpeg, image/png e image/gif.
X-Goog-Upload-Protocol Da impostare su raw.

Ecco l'intestazione di una richiesta 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

Nel corpo della richiesta, includi il programma binario del file:

media-binary-data

Se questa richiesta POST ha esito positivo, come corpo della risposta viene restituito un token di caricamento sotto forma di stringa di testo non elaborata. Per creare elementi multimediali, utilizza queste stringhe di testo nella chiamata 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
}

Le dimensioni consigliate per le immagini sono inferiori a 50 MB. I file di dimensioni superiori a 50 MB sono soggetti a problemi di prestazioni.

L'API Google Foto Library supporta caricamenti ripristinabili. Un caricamento ripristinabile ti consente di suddividere un file multimediale in più sezioni e caricare una sezione alla volta.

Passaggio 2: crea un elemento multimediale

Dopo aver caricato i byte dei file multimediali, puoi crearli come elementi multimediali in Google Foto utilizzando i token di caricamento. Un token di caricamento è valido per un giorno dalla creazione. Un elemento multimediale viene sempre aggiunto alla libreria dell'utente. Gli elementi multimediali possono essere aggiunti solo ad album creati dalla tua app. Per ulteriori informazioni, consulta la sezione Ambiti di autorizzazione.

Per creare nuovi elementi multimediali, chiama mediaItems.batchCreate specificando un elenco di newMediaItems. Ogni newMediaItem contiene un token di caricamento specificato all'interno di un simpleMediaItem e una descrizione facoltativa che viene mostrata all'utente.

Il campo della descrizione è limitato a 1000 caratteri e deve includere solo testo significativo creato dagli utenti. Ad esempio, "La nostra gita al parco" o "Cena natalizia". Non includere metadati quali nomi file, tag programmatici o altro testo generato automaticamente.

Per un rendimento ottimale, riduci il numero di chiamate a mediaItems.batchCreate da effettuare includendo più elementi multimediali in una sola chiamata. Attendi sempre il completamento della richiesta precedente prima di effettuare una chiamata successiva per lo stesso utente.

Puoi creare un singolo elemento multimediale o più elementi multimediali nella libreria di un utente specificando le descrizioni e i token di caricamento corrispondenti:

REST

Ecco l'intestazione della richiesta POST:

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

Il corpo della richiesta deve specificare un elenco di 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
}


Puoi aggiungere elementi multimediali alla raccolta e a un album specificando l'album id. Per maggiori informazioni, consulta la sezione Creare album.

Ogni album può contenere fino a 20.000 elementi multimediali. Le richieste di creazione di elementi multimediali in un album che superano questo limite non andranno a buon fine.

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
}

Puoi anche specificare albumId e albumPosition per inserire elementi multimediali in una posizione specifica dell'album.

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
}

Per maggiori dettagli sul posizionamento negli album, consulta Aggiungere arricchimenti.

Risposta alla creazione di un elemento

La chiamata mediaItems.batchCreate restituisce il risultato per ciascuno degli elementi multimediali che hai provato a creare. L'elenco newMediaItemResults indica lo stato e include il valore uploadToken per la richiesta. Un codice di stato diverso da zero indica un errore.

REST

Se tutti gli elementi multimediali sono stati creati correttamente, la richiesta restituisce lo stato HTTP 200 OK. Se non è possibile creare alcuni elementi multimediali, la richiesta restituisce lo stato HTTP 207 MULTI-STATUS per indicare l'esito positivo parziale.

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

Se un elemento viene aggiunto correttamente, viene restituito un mediaItem che contiene i relativi mediaItemId, productUrl e mediaMetadata. Per maggiori informazioni, consulta Accedere agli elementi multimediali.

Se l'elemento multimediale è un video, deve essere prima elaborato. L'elemento mediaItem contiene un status all'interno del suo mediaMetadata che descrive lo stato di elaborazione del file video. Un file appena caricato restituisce lo stato PROCESSING, prima che sia READY per l'utilizzo. Per maggiori dettagli, consulta Accedere agli elementi multimediali.

Se si verifica un errore durante la chiamata, segui le best practice e riprova. Ti consigliamo di tenere traccia delle aggiunte, in modo che l'immagine possa essere inserita nell'album nella posizione corretta alla successiva richiesta. Per ulteriori informazioni, consulta la sezione Creare album.

I risultati vengono sempre restituiti nello stesso ordine in cui sono stati inviati i token di caricamento.

Best practice per i caricamenti

Le best practice e le risorse riportate di seguito consentono di migliorare l'efficienza complessiva dei caricamenti:

  • Utilizzare una delle nostre librerie client supportate.
  • Segui le best practice per nuovi tentativi ed errori, tenendo presente quanto segue:
    • Gli errori 429 possono verificarsi quando la tua quota è stata esaurita o quando la frequenza è limitata per aver effettuato troppe chiamate troppo rapidamente. Assicurati di non chiamare batchCreate per lo stesso utente fino al completamento della richiesta precedente.
    • 429 errori richiedono un ritardo minimo di 30s prima di riprovare. Utilizza una strategia di backoff esponenziale quando si ripetono le richieste.
    • Si verificano 500 errori quando il server rileva un errore. Durante il caricamento, è molto probabile che questo sia dovuto all'esecuzione simultanea di più chiamate di scrittura (ad esempio batchCreate) per lo stesso utente. Controlla i dettagli della richiesta e non effettuare chiamate a batchCreate in parallelo.
  • Utilizza il flusso di caricamento ripristinabile per rendere i caricamenti più affidabili in caso di interruzioni di rete, riducendo l'utilizzo della larghezza di banda consentendoti di riprendere i caricamenti parzialmente completati. Questo è importante per il caricamento da dispositivi mobili client o quando si caricano file di grandi dimensioni.

Inoltre, tieni presente i seguenti suggerimenti per ogni passaggio del processo di caricamento: caricamento dei byte e creazione di elementi multimediali.

Caricamento dei byte

  • Il caricamento dei byte (per recuperare i token di caricamento) può essere eseguito in parallelo.
  • Imposta sempre il tipo MIME corretto nell'intestazione X-Goog-Upload-Content-Type per ogni chiamata di caricamento.

Creazione di elementi multimediali

  • Non effettuare chiamate in parallelo a batchCreate per un singolo utente.

    • Per ogni utente, effettua chiamate a batchCreate una dopo l'altra (in serie).
    • Per più utenti, effettua sempre chiamate batchCreate per ciascun utente una dopo l'altra. Effettua chiamate in parallelo solo per utenti diversi.
  • Includi il maggior numero possibile di NewMediaItems in ogni chiamata a batchCreate per ridurre al minimo il numero totale di chiamate da effettuare. Puoi includere al massimo 50 elementi.

  • Imposta un testo descrittivo significativo creato dagli utenti. Non includere metadati quali nomi di file, tag programmatici o altro testo generato automaticamente nel campo descrizione.

Procedura dettagliata di esempio

Questo esempio utilizza lo pseudocodice per descrivere il caricamento di elementi multimediali per più utenti. L'obiettivo è delineare entrambi i passaggi del processo di caricamento (caricamento di byte non elaborati e creazione di elementi multimediali) e dettagli sulle best practice per la creazione di un'integrazione di caricamento efficiente e resiliente.

Passaggio 1: carica i byte non elaborati

Innanzitutto crea una coda per caricare i byte non elaborati dei tuoi elementi multimediali di tutti gli utenti. Monitora ogni valore restituito per uploadToken per utente. Ricorda questi punti chiave:

  • Il numero di thread di caricamento simultaneo dipende dall'ambiente operativo.
  • Valuta la possibilità di riordinare la coda di caricamento in base alle tue esigenze. Ad esempio, puoi dare priorità ai caricamenti in base al numero di caricamenti rimanenti per utente, all'avanzamento complessivo di un utente o ad altri requisiti.

Pseudocodice

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

Passaggio 2: crea elementi multimediali

Nel passaggio 1 puoi caricare più byte in parallelo da più utenti, ma nel passaggio 2 puoi effettuare una sola chiamata per ciascun utente alla volta.

Pseudocodice

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

Continua questa procedura fino al completamento di tutti i caricamenti e le chiamate per la creazione di contenuti multimediali.