top of page

Video Automation Project

Took some time at the end of 2022 to explore the possibilities of video automation and the creation of data-driven videos within After Effects. With a limited knowledge of codes and scripts but guided by the idea of making a daily automated video forecast for my hometown, Bergamo, now I can say that I'm very proud of the result.

Everyday, at 6.30 pm, a new video is uploaded on @MeteoBergamo profile on Twitter. No human interaction needed.

I've used VisualCrossing for the weather data, Apps Script for the JSON daily creation, NexaRender for the actual video export and Zapier for the upload on Twitter (wanted to do this by myself, initially, writing a script with Apps Script but I ran out of time! Next time, maybe :)

25.05.2023 Update: We're actually on hiatus with this project because of Twitter's new policy for the API. Going to see if I can find a way around it.

Creative Coding, Design & Animation: onice - josé escobar meneses

function importData()


var ss = SpreadsheetApp.getActive();

var url = '"YOURKEY"&lang=it&contentType=csv';

var text = UrlFetchApp.fetch(url).getContentText();

var csvData = Utilities.parseCsv(text);

var sheet = ss.getSheetByName('NAME');

for (var i = 0; i < csvData.length; i++) {

sheet.getRange(i+1, 1, 1, csvData[i].length).setValues(new Array(csvData[i]));



The daily function that updates the Google Sheets file with the forecast is up here.

On the right, the function that creates the JSON file containing all the useful data for the AE project.

I'm sure they're basic functions, but having them working is still a great result for me.

function exportSheetAsJSON()


var sheet = SpreadsheetApp.openById('ID');

var rows = sheet.getDataRange();

var numRows = rows.getNumRows();

var numCols = rows.getNumColumns();

var values = rows.getValues();

var output = "";

output += "{\""+sheet.getName()+"\" : {\n";

var header = values[0];

for (var i = 1; i < numRows; i++)


if (i > 1) output += " , \n";

var row = values[i];

output += "\""+row[0]+"\" : {";

for (var a = 1;a<numCols;a++)


if (a > 1) output += " , ";

output += "\""+header[a]+"\" : \""+row[a]+"\"";


output += "}";



output += "\n}}";



var folder = DriveApp.getFoldersByName("NAME").next();

var file = folder.getFilesByName("NAME");

if (file.hasNext()){;


folder.createFile("NAME", output, MimeType.PLAIN_TEXT);



2. SERENO (0-00-02-04).png
8. NEBBIA (0-00-01-22).png
6. NEVE (0-00-02-04).png
4. NUVOLOSO (0-00-02-04).png
7. VENTOSO (0-00-01-15).png
5. PIOVOSO (0-00-02-04).png
3. PARZ. NUVOLOSO (0-00-02-04).png

Seven main animations but endless combinations. Thanks to the data structure taken from VisualCrossing, I was able to subdivide the outcomes in these 7 macro-areas. These are characterized by three different palettes and a lot of tiny details that change in each composition. The daily description is taken from VisualCrossing as well.

Schermata 2023-03-17 alle 15.14.28.png

Even the intro changes everyday, randomly, and there are 10 of them (same for the outros). The outcome is based on the first decimal number of the temperature value from the JSON file. Take a look up here to see the expressions used.

On the right, the "Source Text" expression used to automatically update the date in the intro.

month = new Array();

month[0] = "Gennaio";

month[1] = "Febbraio";

month[2] = "Marzo";

month[3] = "Aprile";

month[4] = "Maggio";

month[5] = "Giugno";

month[6] = "Luglio";

month[7] = "Agosto";

month[8] = "Settembre";

month[9] = "Ottobre";

month[10] = "Novembre";

month[11] = "Dicembre";

D = new Date(Date(0));

D = new Date(D.getTime()+1*24*60*60*1000);

"Domani" + "\r" + D.getDate() + " " + month[(D.getMonth())] + "\r" + "a Bergamo"

Schermata 2023-03-17 alle 15.19.45.png

On the left, the expressions used to change the colors of the gradient of the arrow used in the temperature animation. 

This is based on the temp min and temp max values.


Click on the image to take a closer look!

bottom of page