Get MP4 file from Google Drive as blob for YouTube Data upload

1,604 views
Skip to first unread message

Alan Wells

unread,
Apr 18, 2021, 10:53:04 PM4/18/21
to Google Apps Script Community
Does anyone have any idea how I'd get an MP4 file from my Google Drive as a blob for the YouTube API in order to upload a video?

The code below uses the Drive API to get a download URL, and the code gets to the point where it will attempt the video upload to YouTube, but the last error I got is that HTML is not a valid content type.

I don't know if the export needs to convert the file to a specific file type, and I have no idea how that might work.

Or maybe there is a better way to get the MP4 as a blob than using the download url.
I tried using the built in DriveApp Service to get the MP4 file, but had no success.
I also thought about maybe needing a Web App that would upload the file from the users hard drive, and somehow convert it to a blob and then send it back to the server.

function uploadToYouTube() {
  var blob,downloadUrl,mp4_fileId,part,requestResource,response;
  var options = {},snippet = {};

  /*
    You will need to create a GCP standard project and associate it with this Apps Script project-
    In the new code editor click the settings cog wheel and scroll down to:
    Google Cloud Platform (GCP) Project -
    You may get an error:
    In order to change your project, you will need to configure the OAuth consent screen. Configure your OAuth Consent details.
    
    And if you do not have a Google Workspace account then you wont be able to set up the GCP project as "INTERNAL"
    You will need to enable the Google Drive API and the YouTube API in the associated GCP project -
  */

  /*
    This code needs the file ID of the MP4 file in your Google Drive - 
    To get the file ID of an MP4 video file in Google Drive, right click the MP4 in your Google Drive
    and choose, "Get link"
    The link will look like this:
    In the URL is the file ID

    Then you will need to get the webContentLink of the file with the Drive API
    The webContentLink is needed to get the MP4 files as a blob
  */

  options = {
    "method" : "get",
    "headers" : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
    "muteHttpExceptions":true
  }
  
  mp4_fileId = 'PUT THE MP4 FILE ID HERE';
  response = UrlFetchApp.fetch('https://www.googleapis.com/drive/v3/files/' + mp4_fileId + '?fields=webContentLink',options);
  //The download url should look like the following:
  //Logger.log('response.getResponseCode(): ' + response.getResponseCode()) 

  if (response.getResponseCode() !== 200) {

    return;
  }
  
  rspnsContent = JSON.parse(response.getContentText());
  downloadUrl = rspnsContent.webContentLink;
  Logger.log('downloadUrl: ' + downloadUrl) 


  options = {
    "method" : "get",
    "headers" : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
    "muteHttpExceptions":true
  }

  response = UrlFetchApp.fetch(downloadUrl,options);//YouTub accepts: "video/*", "application/octet-stream"
  Logger.log('response.getResponseCode(): ' + response.getResponseCode()) 

  if (response.getResponseCode() !== 200) {

    return;
  }

  Logger.log('response.getContentText(): ' + response.getContentText())

  blob = response.getBlob();

  
  return;
  /*
    With a big video the script might time out before the video was uploaded -

  */

  /*
  {"snippet":{
    "playlistId":"YOUR_PLAYLIST_ID",
    "position":0,
    "resourceId":{
      "kind":"youtube#video",
      "videoId":"abcdefg"
      }
    }
  }
  */

  /*
  {
  "snippet": {
    "title": "Summer vacation in California",
    "description": "Had fun surfing in Santa Cruz",
    "tags": ["surfing", "Santa Cruz"],
    "categoryId": "22"
  },
  "status": {
    "privacyStatus": "private"
  }
  }
  */
  
  requestResource = {};

  snippet.title = "AAA_Put_Title_Here";
  snippet.description = "Description of video goes here";
  snippet.categoryId = "22";

  options.snippet = snippet;
  options.status = {
      "privacyStatus": "private"
    }

  part = "snippet,status";//This correlates to the options

  //YouTube.Videos.insert(resource: Youtube_v3.Youtube.V3.Schema.Video, part: string[], mediaData: Blob, optionalArgs: Object)
  var response = YouTube.Videos.insert(requestResource, part, blob, options);

  if (!response || !response.kind) {//There was an error
    console.log("Error!")
  }
  
  //Logger.log('response: ' + response);

}

Tanaike

unread,
Apr 19, 2021, 1:46:08 AM4/19/21
to Google Apps Script Community
Although I'm not sure about the file size of MP4 file, in your situation, it seems that your script retrieves the blob from "webContentLink". In this case, how about using Drive service and/or the method of get in Drive API with "alt=media"? By this, the file can be directly downloaded from the Google Drive without the virus scan. But in this case, the maximum file size is 50 MB. Please be careful this.

Pattern 1
const blob = DriveApp.getFileById(fileId).getBlob();

Pattern 2
const blob = UrlFetchApp.fetch(url, {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}}).getBlob();

If you want to upload the file over 50 MB, please use the partial download and the resumable upload. If I misunderstood your situation, I apologize.


Alan Wells

unread,
Apr 19, 2021, 12:03:47 PM4/19/21
to Google Apps Script Community
Surprised Face Mine.png
const blob = UrlFetchApp.fetch(url, {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}}).getBlob();

It Works!
I uploaded a MP4 to YouTube!
Awesome.
Thanks for the suggestion.

Tanaike

unread,
Apr 19, 2021, 9:16:02 PM4/19/21
to Google Apps Script Community
Thank you for replying. I'm glad your issue was resolved. Thank you, too.
Reply all
Reply to author
Forward
0 new messages