Загрузка мультимедийных объектов состоит из двух этапов:
- Загрузите байты медиафайлов на сервер Google, используя конечную точку загрузки. Вы получите токен загрузки, который идентифицирует загруженные байты.
- Используйте вызов batchCreate с токеном загрузки, чтобы создать мультимедийный объект в аккаунте Google Фото пользователя.
Ниже описано, как загрузить один мультимедийный объект. Если вы загружаете несколько мультимедийных объектов (что, скорее всего, и происходит в любом рабочем приложении), ознакомьтесь с рекомендациями по загрузке, чтобы повысить ее эффективность.
Подготовка
Необходимые области авторизации
Для загрузки мультимедийных объектов в библиотеку или альбом пользователя требуется область действия photoslibrary.appendonly или photoslibrary.
Мультимедийные объекты также можно создавать с помощью области действия photoslibrary.sharing. Чтобы создать объекты с областью действия photoslibrary.sharing, сначала нужно создать альбом и пометить его как общий с помощью shareAlbum. Затем вы можете создавать мультимедийные объекты, которые будут доступны пользователю в альбоме. Вы не можете создавать объекты непосредственно в библиотеке пользователя или в альбомах, которыми ваше приложение не поделилось.
При получении списка альбомов свойство isWriteable указывает, есть ли у вашего приложения разрешение на создание медиафайлов в определенном альбоме.
Допустимые типы и размеры файлов
Вы можете загружать типы файлов, перечисленные в таблице ниже.
| Тип контента | Допустимые типы файлов | Максимальный размер файла |
|---|---|---|
| Фото | AVIF, BMP, GIF, HEIC, ICO, JPG, PNG, TIFF, WEBP, некоторые файлы RAW. | 200 МБ |
| Видео | 3GP, 3G2, ASF, AVI, DIVX, M2T, M2TS, M4V, MKV, MMV, MOD, MOV, MP4, MPG, MTS, TOD, WMV. | 20 ГБ |
Шаг 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 МБ. Файлы размером более 50 МБ могут работать медленно.
Google Photos Library API поддерживает возобновляемую загрузку. Возобновляемая загрузка позволяет разделить медиафайл на несколько частей и загружать их по одной.
Шаг 2. Создание мультимедийного объекта
После загрузки байтов медиафайлов вы можете создать их как мультимедийные объекты в Google Фото, используя токены загрузки. Токен загрузки действителен в течение одного дня после создания. Мультимедийный объект всегда добавляется в библиотеку пользователя. Мультимедийные объекты можно добавлять только в альбомы, созданные вашим приложением. Подробнее об областях авторизации…
Чтобы создать новые мультимедийные объекты, вызовите mediaItems.batchCreate, указав список newMediaItems. Каждый элемент newMediaItem содержит токен загрузки, указанный в элементе simpleMediaItem, и необязательное описание, которое показывается пользователю.
Поле description может содержать не более 1000 символов и должно включать только осмысленный текст, созданный пользователями. Например, Наша поездка в парк или Праздничный ужин. Не добавляйте метаданные, например названия файлов, программные теги или другой автоматически сгенерированный текст.
Чтобы повысить производительность, сократите количество вызовов 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 запроса. Ненулевой код статуса указывает на ошибку.
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. Отправляя повторные запросы, используйте экспоненциальную выдержку. - Ошибки
500возникают, когда на сервере происходит сбой. При загрузке это, скорее всего, связано с одновременным выполнением нескольких вызовов записи (например,batchCreate) для одного и того же пользователя. Проверьте сведения в запросе и не отправляйте параллельные вызовы кbatchCreate.
- Ошибки
- Используйте возобновляемую загрузку, чтобы повысить надежность загрузки в случае сбоев в сети и снизить нагрузку на пропускную способность, возобновляя частично выполненные загрузки. Это важно при загрузке с мобильных устройств клиентов или при загрузке больших файлов.
Также ознакомьтесь с советами для каждого этапа загрузки: загрузки байтов и создания мультимедийных объектов.
Загрузка байтов
- Загрузку байтов (для получения токенов загрузки) можно выполнять параллельно.
- Всегда указывайте правильный MIME-тип в заголовке
X-Goog-Upload-Content-Typeдля каждого вызова загрузки.
Создание медиаобъектов
Не выполняйте параллельные вызовы
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. Создайте мультимедийные объекты
На первом шаге вы можете параллельно загружать несколько байтов от нескольких пользователей, но на втором шаге вы можете делать только один вызов для каждого пользователя за раз.
Псевдокод
// 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.Повторяйте этот процесс, пока не будут выполнены все загрузки и вызовы для создания медиафайлов.