Node-Webkit File Player – A File player for your desktop

This post is part 5 of 7 in the series Node Webkit Apps
Tweet about this on TwitterShare on LinkedIn0Share on Google+3Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page

A few days ago, Ignacio Tartavull reached out to me mentioning that he had built a file viewer based on Node Webkit powered Dashboard application and associated the node webkit app as the default opener for.ipynb files. Which I thought was a pretty genius idea. You can check out the INotebook app here.

Inspired by that idea, I have written a file browser/player app with node webkit that can “play” basic files like txt, log, json, md, mp3, mp4, png and jpeg.

Also, mustapha has reached out to me requesting another tutorial on Node webkit. And Mitesh Agarwal reached out to me requesting a post on a node webkit file viewer. So here it goes.

The final product we are going to build will look like

You can find the completed code here.

So, let us get started.

Prerequisites

In this post, we will be building a nwk file player. This app will be built using node-webkit, Express.js and Angular.js.

If you are new to node-webkit refer

If you are new to Express.js refer

If you are new to Angular.js refer

We are also going to use a jQuery plugin named jstree. We will be leveraging this plugin in our app using an Angular directive. Also refer to the below post on how to build a file browser with this plugin

Setup project

We will be using a slush generator named slush-wean to scaffold a basic node webkit, Express.js and Angular.js app. And then we will build our application on top of it.

First, create a new folder named nwkFilePlayer. Open new terminal/prompt here. We will install gulp, slush and slush-wean modules globally. Run

npm install -g gulp slush slush-wean

Once this is done, we will scaffold a new wean app. Run

slush wean

and fill the project name as nwkFilePlayer. It will take a couple of mins to download all dependencies. Your final project structure would be like

To get an overview of the project structure, please refer the file browser app in the prerequisites above.

Now, to the run the app, we will execute

gulp run

For the first time, nwbuilder will run and download the required libs to run the nwk app for your OS. This may take upto 5 minutes. Once that is downloaded, nwbuild will launch the app. You will see a splash screen and then the boilerplate home page appears. Sweet scaffolder right!

Continue Development

Now that we have the boilerplate working, we will begin working on the app.

Our application logic is very simple. When the app loads, we will show all the folders right from the root on the left hand side of the app in a tree view. And when a user clicks on the resource, we play that file. Play here refers to viewing an image, displaying a md/log/json/txt file and playing media. A simple app that is more than a “media center”.

Open app.js and we will add 2 new routes.

Line 21 and line 22 point to the new routes which we are going to create. Next open routes/index.js and update it as below

Things to notice

Line 4 : Dispatches the main index.html

Line 8 : The logic for serving the tree. If the req.query.id == 1  this means that the tree is loading for the first time. So, we dispatch the root files and folders. If not, we dispatch the files and folders from the requested path.

Line 24 : If a resource is selected, we dispatch the resource. If the resource is text based, we dispatch it completely. If the resource is media, we stream it for live playback.

“Client Side”

To manage “client side” dependencies, we will use bower. Before shipping the app, it is highly recommend to remove the unwanted files and ship the ones which are only required. Back to terminal/prompt, run

bower init

This will create a bower.json file. Next, create a file at the root of the project named .bowerrc. This file will consist of the bower config. Update it as below

To keep the code organized, we will delete the existing public/lib folder. So, all our dependencies are inside the libs folder. To add the required dependencies, run

bower i --save angular angular-route bootstrap jstree-directive jstree

It will take a couple of minutes for all the dependencies to be downloaded.

Now, we will work on the User Interface. Open views/index.ejs and update it as below

Here we refer the downloaded libraries. We will update the existing public/partials/head.html to reflect the App name. Update it as below

Finally the main view of the app. The Tree and the players. Create a new file named home.html inside public/partials folder and update it is as below

Next, we will setup the Angular.js code. Open public/js/app.js and update it as below

We have added a HomeCtrl – The main controller for the app and a default route.  Next, we will create a Factory to interact with the Express.js server.

Create a new file named factory.js inside the public/js folder and update it as below.

Things to notice

Line 1 : Our resource factory. This factory is responsible for fetching the resource when we click on a file in the browser.

Line 15 : A Factory that is responsible for maintaining a single instance of the Audio tag. So, that only one file plays at once. We are not going to use any of the API methods written here except  play(fileName) and stop() .  But you can use this code to customize or rebuild a custom player with your own controls.

Line 56 : A factory for Video tag. Same purpose as above.

This way we can have more control on the Audio and Video elements.

Finally the controller. Create a new file named controller.js inside public/js folder. Update it as below

Things to notice

Line 5 : This function will get triggered when a user clicks on a tree node/leaf. We check if the clicked node/leaf is a leaf and then start processing it on line 24.

Line 27 : We determine the extension of the file and depending on it, we trigger the respective media players. If it is a text/image file we simply fetch the resource and display it.

As of now, we are supporting only a mp3/mp4 and log, txt, json and md file types. You can add your own file types and dispatch an appropriate response from routes/index.js when the file is requested.

Using the video & audio tags inside Node Webkit

This is one of the most important steps. By default node webkit ships with only open source libraries. But if you want to play mp3 or mp4 files you need to modify the node webkit binaries.

Due to licensing issues, the pre-built binary doesn’t ship with the necessary codecs for patented media formats. If you require support for these formats, see the instructions below.

Consult a lawyer if you do not understand the licensing constraints and require patented media formats in your application.

So once we update the binaries with the new ffmpegsumo file for your OS, your project will automatically become a GPL licensed.

Below is how we enable Mp3 and Mp4 support for our app.

Windows

  1. Locate the Chrome\Application folder (e.g. C:\Program Files\Google)
  2. Copy ffmpegsumo.dll to your node-webkit distribution directory

OSX

  1. Head to your Applications folder and right-click on Google Chrome. Select Show Package Contents and navigate to Versions > Most recent # > Framework > Libraries.
  2. Copy ffmpegsumo.so to  /nwkFilePlayer/node_modules/node-webkit-builder/cache/0.10.5/osx/node-webkit.app/Contents/Frameworks/node-webkit Framework.framework/Libraries

You can find more info on how to set up for your OS here.

Note : Every time you download a new instance of node-webkit, be sure to update this.

Finally to cleanup the UI, we will apply styles. Delete public/css/bootstrap.css. Open public/css/app.css and update it as

Create another folder named imgs inside the public folder and download the images from hereThis will be the icons for the tree.

That is it. Now save all the files and execute

gulp run

And you should see your file browser/player!

If you want to distribute the app, you can use the gulp build task for the required Operating System.

Hope this post gave you a decent idea on how to work with file system, node modules and HTML5 media elements.


Thanks for reading! Do comment.
@arvindr21

Series Navigation<< node-webkit and Firebase – Simple and Social AuthenticationNode Webkit, Firebase and Ionic Framework – A one to one chat client >>
Tweet about this on TwitterShare on LinkedIn0Share on Google+3Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page
  • Ethan Arrowood

    Arvind, I know it’s been awhile since you made this but hopefully you can help me out. I’m on a windows machine, but I am trying to make my app single file executable for OSX. I got it to work as an .exe (single file executable). Can you give me some pointers as to how to make it single file executable for OSX? Currently I got up to the step where I download gulp. I enter the gulp nw command and it returns an error saying it doesn’t recognize the command ‘gulp’.
    Thanks in advanced

  • Paramanantham

    Hi Arvind,

    Is it possible to create .exe file which will install the node webkit app in some location (C:/program files) and create a shortcut for the application?

    Like real desktop apps?

    Since currently due to file size (almost 90mb), the exe file is taking some 20 sec to load. User wont see any notification while loading in node webkit… How to solve this problem?

  • Paramanantham

    Hey Arvind,

    I am developing a offline desktop application for ufaber.com. It contains encrypted (using node js crypto algorithms) video files. The assets are nearly 7GB…. Now, I am facing difficulty to package it.

    Is there any poosible way to package node webkit app excluding some large data folder outside of build and accessable from the application. Is it possible?

    Thanks in advance. Right now my executable file is too heavy like 7GB because of the data…

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hey Paramanantham,

      AFAIK, there is nothing out-of-box to manage data. The question I have here is do you want to reduce the size of download or do you want to reduce the size of the app on-disk?

      If it is the size of download, I would recommend implementing a download manager, that downloads assets after the user has downloaded the app.

      If it is the size on disk, I recommend streaming the video instead of downloading the assets,

      Thanks.

  • Rohan
  • unagieel

    Doesn’t work on Windows: Error: EPERM, operation not permitted ‘c:System Volume Information’

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Can you tell me when you are getting this error?

      • unagieel

        When I launch it, it will display the progress wheel, and then that error will display.

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          Is this after scaffolding a new slush-wean app?

  • Trevor

    Thanks for these tutorials. I have been enjoying building my desktop app with node-webkit and your slush generator. However, when I run the app with ‘gulp-run’, I am unable to see any output from my server console.log statements. How can I see this? Thanks.

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Trevor, Thanks. If my understanding is correct you want to see the console logs from the javascript code. For that, you need to check in the dev tools console of node webkit app.

  • gabrin

    Hi! Are can I open webdav connection?

  • Manisha

    Could you make simple node-ebkit file and folder browser using JavaScript or jquery (same structure)

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Hello Manisha, Yes, you can do that. Instead of the angular directive, you can use the jQuery version of the jstree and bind it to the server code and it should work fine. And also you can use the node selected event http://www.jstree.com/api/#/?q=.jstree%20Event&f=select_node.jstree and get the requested resource on selecting a node on the tree. Thanks!

  • Ignacio Tartavull

    Hey! thanks for that mention!

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks!

  • Mustapha

    thank you for this tutorial ! :)

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks.