Reputation: 735
My goal is to calculate the total length - in seconds - of all videos within all sub directories of a Google Drive folder.
I have followed the Answer from here: Iterate Through Folders/Subfolders/Files in Google Drive to try and create a script that iterates through all directories within a folder and grabs the file count, plus file name and video duration if the file is a video.
I am currently using:
function testTraverse(){
var originFolder = DriveApp.getFoldersByName('All Media').next();
var totalCount = traverseFolder(originFolder,0);
Logger.log('total files = '+totalCount);
}
function getVideoDuration(folder,folderId, files) {
var q = "'" + folderId + "' in parents and trashed=false";
var fields = "files(mimeType,name,videoMediaMetadata)";
var url = "https://www.googleapis.com/drive/v3/files?q=" + encodeURIComponent(q) + "&fields=" + encodeURIComponent(fields) + "&access_token=" + ScriptApp.getOAuthToken();
var res = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
var obj = JSON.parse(res);
for (var i = 0; i < obj.files.length; i++) {
sum += obj.files[i].videoMediaMetadata.durationMillis / 1000;
}
Logger.log("Total duration: " + sum);
}
function traverseFolder(folder,total) {
var name = folder.getName();
var count = 0;
var files = folder.getFiles();
var folderId = folder.getId();
while (files.hasNext()) {
count++;
getVideoDuration(folderId, files);
}
var subs = folder.getFolders();
while (subs.hasNext()) {
total+=traverseFolder(subs.next(),count);
}
return total;
}
Running the above throws an error from the line: for (var i = 0; i < obj.files.length; i++)
:
Cannot read property 'length' of undefined
Which is confusing, because I am in a directory with multiple files.
And the function I am way out of my depth with is the getVideoDuration, which I used from the sample script from the answer here: How to get file (video) duration of google drive file programmatically?.
My desired result is to calculate the total length - in seconds - of all videos within all sub directories.
Is there a simpler way to do this?
Upvotes: 0
Views: 1420
Reputation: 201358
Cannot read property 'length' of undefined
is due to the following 2 reasons.
getVideoDuration(folderId, files)
in traverseFolder
, you send folderId, files
as the arguments. But at the function of getVideoDuration
, the script is getVideoDuration(folder,folderId, files)
. By this, the folder ID is not used. And also, files
is not used in getVideoDuration
.access_token
cannot be used now. So it is required to use the access token at the request header. I thought that I had modified my answers related to this. But I had forgot to modify to this answer. I apologize for this.sum
is not declared. By this, an error occurs.obj.files[i].videoMediaMetadata.durationMillis
.When above points are reflected to your script, it becomes as follows.
// Please run this function.
function testTraverse() {
var originFolder = DriveApp.getFoldersByName('All Media').next();
var res = traverseFolder(originFolder, {totalLength: 0, totalFiles: 0, filenames: []});
Logger.log(res)
}
function getVideoDuration(folderId, o) {
var q = "'" + folderId + "' in parents and trashed=false";
var fields = "files(mimeType,name,videoMediaMetadata)";
var url = "https://www.googleapis.com/drive/v3/files?q=" + encodeURIComponent(q) + "&fields=" + encodeURIComponent(fields);
var res = UrlFetchApp.fetch(url, {muteHttpExceptions: true, headers: {authorization: "Bearer " + ScriptApp.getOAuthToken()}});
var obj = JSON.parse(res);
for (var i = 0; i < obj.files.length; i++) {
var file = obj.files[i];
if (file.hasOwnProperty("videoMediaMetadata")) {
o.filenames.push(file.name);
o.totalFiles++;
o.totalLength += file.videoMediaMetadata.durationMillis / 1000;
}
}
}
function traverseFolder(folder, obj) {
var name = folder.getName();
var count = 0;
var files = folder.getFiles();
var folderId = folder.getId();
if (files.hasNext()) getVideoDuration(folderId, obj);
var subs = folder.getFolders();
while (subs.hasNext()) {
traverseFolder(subs.next(), obj);
}
return obj;
}
{totalLength: ##, totalFiles: ##, filenames: [###]}
. totalLength
, totalFiles
and filenames
are the total length of video length, the total number of video files and the filenames of video files, respectively.Upvotes: 2