העלה את המדיה

העלאת פריטי מדיה היא תהליך דו-שלבי:

  1. מעלים את הבייטים של קובצי המדיה לשרת Google באמצעות נקודת הקצה של העלאות. הפעולה הזו מחזירה אסימון העלאה שמזהה את הבייטים שהועלו.
  2. כדי ליצור פריט מדיה בחשבון Google Photos של המשתמש, משתמשים בקריאה ל-batchCreate עם אסימון ההעלאה.

בשלבים האלה מתואר תהליך ההעלאה של פריט מדיה יחיד. אם אתם מעלים כמה פריטי מדיה (סביר להניח שבכל אפליקציית ייצור), כדאי לעיין בשיטות המומלצות להעלאות כדי לשפר את יעילות ההעלאה.

לפני שמתחילים

היקפי ההרשאות הנדרשים

כדי להעלות פריטי מדיה לספרייה או לאלבום של משתמש, צריך את ההיקף photoslibrary.appendonly או את ההיקף photoslibrary.

אפשר גם ליצור פריטי מדיה באמצעות ההיקף photoslibrary.sharing. כדי ליצור פריטים עם ההיקף photoslibrary.sharing, קודם צריך ליצור אלבום ולסמן אותו כמשותף באמצעות shareAlbum. לאחר מכן תוכלו ליצור פריטי מדיה שישותפו עם המשתמשים באלבום. אי אפשר ליצור פריטים ישירות בספרייה של המשתמש או באלבומים שהאפליקציה לא שיתפה.

כשמפרסמים אלבומים, המאפיין isWriteable מציין אם לאפליקציה יש גישה ליצירת מדיה באלבום מסוים.

סוגים וגדלים קבילים של קבצים

אפשר להעלות את סוגי הקבצים שמפורטים בטבלה שלמטה.

סוג מדיה סוגי הקבצים האפשריים גודל קובץ מקסימלי
תמונות AVIF, BMP, GIF, HEIC, ICO, JPG, PNG, TIFF, WEBP, חלק מקובצי RAW. ‎200 GB
סרטונים 3GP, 3G2, ASF, AVI, DIVX, M2T, M2TS, M4V, MKV, MMV, MOD, MOV, MP4, MPG, MTS, TOD, WMV. ‎20 GB

שלב 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
}

גודל הקובץ המוצע לתמונות הוא פחות מ-50MB. קבצים שגדולים מ-50MB עלולים להיתקל בבעיות בביצועים.

ה-Google Photos Library API תומך בהעלאות שניתנות לחידוש. העלאה שניתן להמשיך מאפשרת לך לפצל קובץ מדיה למספר קטעים ולהעלות קטע אחד בכל פעם.

שלב 2: יצירת פריט מדיה

אחרי שתעלו את הבייטים של קובצי המדיה, תוכלו ליצור אותם כפריטי מדיה ב-Google Photos באמצעות אסימוני העלאה. אסימון העלאה תקף למשך יום אחד אחרי שנוצר. פריט מדיה תמיד מתווסף לספרייה של המשתמש. ניתן להוסיף פריטי מדיה רק לאלבומים שהאפליקציה יצרה. למידע נוסף, ראו היקפי הרשאות.

כדי ליצור פריטי מדיה חדשים, צריך לקרוא לפונקציה mediaItems.batchCreate על ידי ציון רשימה של newMediaItems. כל newMediaItem מכיל אסימון העלאה שמצוין בתוך 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"
      }
    }
   , ...
  ]
}

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 לפחות. מומלץ להשתמש באסטרטגיה של השהיה מעריכית לפני ניסיון חוזר (exponential backoff) כשמנסים שוב בקשות.
    • 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.

המשך בתהליך זה עד להשלמת כל ההעלאות והשיחות ליצירת מדיה.