I am using the following code to upload photos and videos to Google Photos using Powershell. The code works perfectly for pictures, but will fail when uploading a video (which is accepted in Google Photos when this is uploaded through a browser).
When attempting to upload a video, raw bytes upload will succeed, but mediaItems.batchCreate
will fail with status.code 3
and status.message "Failed: There was an error while trying to create this media item."
Could this be due to a wrong mime type in the header?
Function GP-UploadMedia (){
<#
.SYNOPSIS
Uploads a Google Photos media (picture/video)
.Description
Parameters:
- album id
- media path
Returns:
- picture id
#>
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[string]$album_id,
[Parameter(Mandatory=$true)]
[string]$media_path
)
# refresh tokens if required
G-RefreshTokens
# 1st step: upload raw bytes
$requestUri = "https://photoslibrary.googleapis.com/v1/uploads"
$mime_type = [System.Web.MimeMapping]::GetMimeMapping($media_path);
$Headers = @{
Authorization = "Bearer $($Global:Tokens.access_token)";
ContentType = "application/octet-stream";
"X-Goog-Upload-Content-Type" = $mime_type;
"X-Goog-Upload-Protocol" = "raw";
}
$body = $media_path;
try {
$upload_token = Invoke-RestMethod -Headers $Headers -InFile $body -Uri $requestUri -Method POST
}
catch {
# Something went wrong. Investigate!
dieOnError ([System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream()));
}
# refresh tokens if required
G-RefreshTokens
# 2nd step: pair raw bytes to Google Photo media (picture/video)
$requestUri = "https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate"
$Headers = @{
Authorization = "Bearer $($Global:Tokens.access_token)";
}
$body = [PSCustomObject]@{
albumId = $album_id;
newMediaItems = @(
[PSCustomObject]@{
description = "";
simpleMediaItem = [PSCustomObject]@{
fileName = (Split-Path $media_path -leaf);
uploadToken = $upload_token;
}
}
)
}
$myJson = $body|ConvertTo-Json -Depth 4
try {
$Response = Invoke-RestMethod -Headers $Headers -Body ($myJson) -Uri $requestUri -Method POST -ContentType "application/json; charset=utf-8";
}
catch {
# Something went wrong. Investigate!
dieOnError ([System.IO.StreamReader]::new($_.Exception.Response.GetResponseStream()));
}
return $Response.newMediaItemResults.MediaItem.id;
}