Загрузка медиа-элементов представляет собой двухэтапный процесс:
- Загрузите байты своих медиафайлов на сервер 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
.
ОТДЫХ
Включите следующие поля в заголовок 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 }
Рекомендуемый размер файла изображений — менее 50 МБ. Файлы размером более 50 МБ подвержены проблемам с производительностью.
API библиотеки Google Фото поддерживает возобновляемую загрузку . Возобновляемая загрузка позволяет разделить медиафайл на несколько разделов и загружать по одному разделу за раз.
Шаг 2. Создание медиа-элемента
После загрузки байтов ваших медиафайлов вы можете создать их как медиаэлементы в Google Фото, используя токены загрузки. Токен загрузки действителен в течение одного дня после создания. Медиа-элемент всегда добавляется в библиотеку пользователя. Медиа-элементы можно добавлять только в альбомы, созданные вашим приложением. Дополнительные сведения см. в разделе Области авторизации .
Чтобы создать новые элементы мультимедиа, вызовите mediaItems.batchCreate
, указав список newMediaItems
. Каждый newMediaItem
содержит токен загрузки, указанный внутри simpleMediaItem
, и необязательное описание, которое отображается пользователю.
Поле описания ограничено 1000 символами и должно включать только значимый текст, созданный пользователями. Например, « Наша поездка в парк » или « Праздничный ужин ». Не включайте метаданные, такие как имена файлов, программные теги или другой автоматически сгенерированный текст.
Для достижения максимальной производительности сократите количество вызовов mediaItems.batchCreate
, включив несколько элементов мультимедиа в один вызов. Всегда дожидайтесь завершения предыдущего запроса, прежде чем совершать последующий вызов тому же пользователю.
Вы можете создать один или несколько медиа-элементов в библиотеке пользователя, указав описания и соответствующие токены загрузки:
ОТДЫХ
Вот заголовок 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 медиа-элементов. Запросы на создание медиа-элементов в альбоме, превышающие этот предел, не будут выполнены.
ОТДЫХ
{ "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 }
Вы также можете указать albumId
и albumPosition
, чтобы вставлять элементы мультимедиа в определенное место в альбоме.
ОТДЫХ
{ "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
для запроса. Ненулевой код состояния указывает на ошибку.
ОТДЫХ
Если все медиа-элементы были успешно созданы, запрос возвращает статус 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
содержит 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. Создайте медиа-элементы
На шаге 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.
Продолжайте этот процесс, пока не будут завершены все загрузки и вызовы создания мультимедиа.