We’re about to build simple Youtube Terminal Downloader for downloading videos and music from Youtube, Soundcloud, Vimeo and other mainstream services.

Before we begin, you can try out a live demo of the app here. Github repo here.

In order to this tutorial you’ve to have Meteor running on your machine. We’ve already installed it in the part 1. Jump straight to 6 in 6 Challenge Week 1 — Yik Yak Web Clone to see an installation process. Install Meteor and create your app.

It also shows how to execute terminal commands and returns result back to client.

Creating Interface

Open up html file and type the following:

<head>

<title>Terminal</title>

</head> <body>

{{> terminal}}

</body> <template name="terminal">

<div class="box">

<form id="command-input">

<input type="text" id="command" class="command" autofocus="autofocus">

</form>

</div>

</template>

Client side

Now we need to create event that sends data to server and returns executed output back to client.

if (Meteor.isClient) {

Template.terminal.events({

'submit #command-input': function (event, template) {

event.preventDefault();

var input = template.find('#command');

var cmd = input.value;

console.log('command', cmd);

Meteor.call('command', cmd, function(error, result) {

if(result.stdout)

console.log('Output: '+ result.stdout);

else

console.log('Error: '+ result.stderr);

});

input.value = '';

input.focus();

}

});

}

Server side

On server we need to use asynchronous method, to return the output from terminal back to client after terminal executes our exec command.

First we need to add meteor package in terminal that allows us to use Npm packages.

meteor add meteorhacks:npm

Second we need to install on our computer youtube-dl, a small command-line program to download videos from YouTube.com and a few more sites.

Click here to find installation instructions.

We load exec and future npm packages. We use this.unclock() because some methods take longer time to execute. Command method starts download in terminal and returns progress result back to client.

if (Meteor.isServer) {

// load exec

var exec = Meteor.npmRequire('child_process').exec;

// load future from fibers

var Future = Meteor.npmRequire('fibers/future');



Meteor.methods({

'command' : function(line) {

console.log(“In command method”, line);

// this method call won’t return immediately, it will wait for the

// asynchronous code to finish, so we call unblock to allow this client

this.unblock();

var future = new Future(); exec("youtube-dl " + line, function(error, stdout, stderr) {

console.log(‘Command Method’, error, stdout, stderr);



future.return({stdout: stdout, stderr: stderr});

});

return future.wait();

}

});

}

Styling

There is also included some additional styling for this app to look better here.