Ionic Framework, Cordova and File API – A Media Player App

Tweet about this on TwitterShare on LinkedIn0Share on Google+12Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page

Yves Bamani requested a post to build a media player app using Ionic Framework and Cordova. The mediaPlayer app will show a player interface and a couple of buttons. The user can browse through the filesystem and pick a file to play. The initial request was to play both Audio and Video files inline. But I was only able to get the Audio files to play inline where as the Video will be launched in the device default video player.

Here is a quick demo of the app

Screenshot_2015-03-30-10-53-15 Screenshot_2015-03-30-10-53-24 Screenshot_2015-03-30-10-53-54

Yves also requested for the app to be built using ngCordova. But there are a couple of features in $cordovaMedia like getDuration(media)  and  getCurrentPosition(), which are not working yet. And the $cordovaFile does not have a method to recursively get all the folders in a directory, so I am going to use Cordova API as is and build this app.

You can find the completed here.

So, let us get started.

Prerequisites

You need to have the knowledge of the following to get a better understanding of the code below.

Application Design

The application is pretty simple. When the user launches the app, we show a file browser, where the user can browse through his/her device. Then they can select an audio or video file to play.

We will be using a side menu template, where the player is a instance of  $ionicModal. This modal lives in the background. As mentioned earlier, we will be using the Media API from cordova to manage the audio files and a Video player Cordova plugin by Dawson Loudon named VideoPlayer inspired by Simon MacDonald’s VideoPlayer. All this plugin does is create a new Video Intent and launch it.

I am still looking for a consistent solution on how to implement inline videos. If you do know one, please drop a comment.

I have tested this app on an Android and not on iOS.

Develop the App

Create a new folder named mediaPlayerApp. Open a new terminal/prompt here. We will scaffold the side menu template and then clean it up as per our needs. Run,

ionic start mediaPlayerApp sidemenu

Once the scaffolding is completed, you can CD into the mediaPlayerApp folder and run

ionic serve

and you should see the side menu app in your browser.

The first thing we are going to do is update index.html. Open www/index.html in your favorite editor and update it as below

We have referred the audio service JS code that consist of the logic to deal with the Media API and the controllers file which consist of the controller logic.

Next, open www/templates/menu.html. We will update this file with fewer menu items

We have removed all the old menu items and added 2 new. One to show the player, and one to browse the device.

Now, we will clean up and rename the required files inside www/templates folder

  • Rename login.html to player.html
  • Delete playlist.html
  • Delete playlists.html
  • Delete search.html

Open www/templates/player.html and update it as below

This template will be shown when we init the Ionic Modal. This Modal will always be in the background while the app is running.

This template is the base for showing the audio player. Line 18 consists of the logic to show the seek bar. Line 22 shows the play button, when we have paused the video using the button on line 25. We can also stop the media play back completely using the Stop button.

As you can see from the directives on these buttons, they are subjected to visibility based on the state of the audio file.

Next, open www/templates/browse.html and update it as below

This is a very simple template drive by the files[]  from scope. When the user launches the browse page, we will query the file system and show the root files. Once the user clicks on a particular folder, we query the file system API passing in the current folder as the root and fetch its children.

And when a user selects a file, we check if it is of the type audio or video and then play it. Else we will show a message that we cannot play the selected file.

This completes all our templates. We will now work with the Audio Service. Open www/js folder and create a new file named audio.service.js and update it as below.

Things to notice

Line 1 : We have created a new module named starter.services and added the  AudioSvc to that.

Line 8 : Defines the play audio method, which plays the given src using the Cordova’s Media API.

Line 18 : We create a setInterval for every seconds to execute  getCurrentPosition() and trigger the callback. This way we update the seek bar with the total time and time left.

Line 46 : The logic for resume audio

Line 52 : The logic for pause audio

Line 58 : The logic for stop audio

We will be injecting this service as a dependency in our controller, where we will manage the above API based on the user interactions.

Next, we will update www/js/app.js as below

Things to notice

Line 1 : We create a module named starter and inject ionicstarter.controllers and starter.services as dependencies.

Line 4 : Inside the  $ionicPlatform.ready() we config the keyboard and status bar.

Line 12, 20, 26 : We are building an API to work with the  $ionicLoading  API.

Line 32 : We config the router

Finally, the controllers. Open www/js/controller/js and update it as below

Things to notice

Line 13 : When the app launches, the BrowseCtrl is invoked. Here, we initialize the player as a modal from the template.

Line 19, 23 : We have created 2 methods on  $rootScope that can show and hide the player. This will be used across the app. Take a look at line 5.

Line 27 : The File System traversing starts from here. We wait for the device to be ready.

Line 30 : We call  requestFileSystem() on the window and get the contents of the root directory.

Line 35 : We read all the entries present in the root folder and  call  processEntries() to build an Array of files system items.

Line 156 : Here we get all the entries and a reference Array. We iterate through each item and build an object, which consists of essential information while rendering. This same method will be invoked when ever we are reading entries from the file system and building a UI.

Line 38 : We assign the file info array to  $scope.files. This updates the browse.html template to reflect the files in the root.

Line 49 : Will get invoked when any file or folder name is clicked.

Line 51 : If the selected item is a folder, we check if the item is a navigation item. Navigation items are used to move to folder one level up, which we create for the user to navigate. Based on this condition, we call  processFile() with a URL

Line 115 : Here, we resolve the current URL, and then get the children (files/folders) inside that path and then update  $scope.files.

Line 125 : If the folder is not the root folder and it has children, we append a new  .. One level up item to the top of the list, using which the user can navigate to the parent folder. You can see the same in the demo video. This way, we can recursively show the file system to the user.

Line 57 : If the clicked item is a file, we check it is an Audio file or Video file. If it is a Video file, we will invoke the  VideoPlayer.play() passing in the media URL. We install the Video player plugin next.

Line 63 : If it is an audio file, we will work with the  AudioSvc  service and manage the player.

The file looks pretty complicated but the logic is pretty simple.

Install Cordova Plugins

To run the app, we need 3 plugins.

  1. com.ionic.keyboard
  2. org.apache.cordova.file
  3. org.apache.cordova.media
  4. com.dawsonloudon.videoplayer

To install the plugins run

cordova plugin add com.ionic.keyboard

cordova plugin add org.apache.cordova.file

cordova plugin add org.apache.cordova.media

cordova plugin add https://github.com/dawsonloudon/VideoPlayer.git

Run the App

We need to run the app on a device to test it. First, we will add a platform. Run,

ionic platform add android

And then to the run  the app on a device execute

ionic run

And you should be able to check out the below

 

Hope this post gave you an idea on how to work with File System, Audio and Video APIs.


Thanks for reading! Do comment.
@arvindr21

Tweet about this on TwitterShare on LinkedIn0Share on Google+12Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page
  • adedeji92

    Hi, Nice article , c an we have a way to add music controller(Like next, previous and
    play/pause) in the notification bar. any help? Attached image is an
    example
    https://uploads.disquscdn.com/images/3c7e63b8f43fa29d70b0e455dabc1215f9327d5c88c92b8c2c5e762eac1f047c.png

    • Felipe de Castro

      I want to know about it too

  • Carinha que mora logo ali

    no working more, this plugins is outdated.

  • elyptik

    Hello !
    First thank you for your tutorial it’s still working at the moment !
    I have a question, can we add more than one music in the player ?
    I will explain, I want that user put a lot of music and chose which one play. I tried something but it doesn’t work. Can u give me some tips please Thx !!!

    @arvindr21

  • hanie

    hi.i downloaded your code project in Git. I run program in my phone (Samsung S 2+) but the browse page remains blank . i added to config.xml but until it hasn’t work.thank you for help me

    • hanie

      great:)thanks a lot for your article :)
      It work correctly on android 5 but in my android 4.1 it doesn’t work so i think cordova not work on less version .am i right ?

  • Sao Thien Hat

    Hi Arvind,

    Thank you for your tutorial :). I wonder that is it possible to display image during playing an audio on full screen mode ? I try put image for bgImage with image in project such as: bgImage: “img/myImage.jpg” but it seem not work. Only bgColor working.
    Do I need have any special configuration to do that ?

  • santosh

    hi i can play audo files in it but not video files please help

  • Vinicius Coimbra

    Hi Arvind,

    I don’t know what i’m doing wrong. I cloned your project in github, installed all dependencies for the project, put the “” in config.xml to works in my Moto G2, but always when i try to play some music in my device, it doesn’t work. My player never load and there is no callback to see log or errors :/

  • Abraham

    Hi! thanks for your blog and this post, very useful.
    But i have a problem which is going me crazy.
    I’ve made a project with your code but “getDuration()” call return me -1 every time, so the progress bar doesn’t work.
    My environment is:
    cordova version: 5.4.1
    cordova platform android version: 5.1.0
    cordova plugin media version: 2.1.0

    anyone have any idea about what is happening? where is the problem?
    thanks in advance!

  • Arvind Chakraborty

    Hey great tutorial but the browse page remains blank on my phone :( ..any clue ? phone model : Asus Zenfone 2 ZE551ML

    • jetmiller

      I have the same problem…
      samsung s2, android 5.1.1

  • Rajesh

    video files is not playing…….whops we can not play this file..
    why?
    And mine question is also: how we can access mobiles video players for opening a video file which is hosted in my website..
    please help

  • Sakthivel A

    Thanks for the tutorial.

    Error: $window.LocalFileSystem is undefined

    Am facing this error while am trying using intel xdk

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Try adding the Cordova media plugin : cordova plugin add org.apache.cordova.media

      • santosh

        try this “cordova plugin add cordova-plugin-media”

  • Matías Aiskovich

    Thank you very much for the tutorial, is great.

    I am trying to implement that the songs will change automatically after finishing, going to the next one in the folder, do you know how i can achieve that?

    Thanks

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Glad you liked it.

      Yes, you can achieve that quite easily. The callback you pass to

      in controllers.js, will return 2 values from audio.service.js (line 21). The position & duration. And if the position is same as duration after the song has started, that means it has reached the end. Now you can pull the next file from your list or the filesystem and execute playAudio

      • Matías Aiskovich

        Thanks! Its working now

        • shashwatee

          I am trying to auto-play the next song automatically from the folder. Can you please share the code which you have added.
          Its urgent….

      • shashwatee

        I am trying to auto-play the next song automatically from the folder. Can you please share the code which you have added.How exactly can i pull up the next song??

        Its urgent….

  • Prabhjas Singh Bajwa

    Really Thanks for providing such a good tutorial. But i am having my project online streaming radio using com.keosu.cordova.stream plugin in my android app. I want to record online radio and want to show loading spinner. So, Please help me where to write what code.

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks. What have you tried so far?

      • Prabhjas Singh Bajwa

        Till now i have implemented online streaming radio using above plugin which i mentioned. But now my need is to record that online streaming radio. So i just need some functions which i can put in my controllers javascript file and able to record that audio.

  • Nuruddin Ba

    What’s the solution for this error I’ve seen in many of the comments I did not find any Answer
    “Media is not define ”
    when i get instance from Media
    media = new Media (src)

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      It means that the Media plugin is not loaded.

  • Raghu A

    I have been having difficulties to implement the FileBorwser in Ionic. I tried deploying in my Mobile but it does not list any directories. I have downloaded your code from Git and same case. What could be the issue. I am having KitKat 4.4 in my Mobile.

    • Raghu A

      Got it had to add following in the config.xml

      While adding the file plugin it gave an indicator but it also mentioned “If this is a new application no changes are required.”.. Strange..

      Thanks for a great post.

  • rafael perdomo

    hello,you’re very good at explaining and doing
    things.
    I am having a problem with the browser, I do everything from video and
    tutorial and have no problem but when the application does not show me
    any folder but as I say you will not give me any errors, what can it be?

    download the application, add all(platform plugin) and is the same

    thanks for your tutorial and I hope your early response

  • SlyOne

    Hi:
    I am looking at this and was wondering how I could record voice from device and then
    display those voice recordings. Thanks when will your be released, will this be covered?

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      You can use the Capture API for that : http://ngcordova.com/docs/plugins/capture/ . My book is already released and no I did not cover this in that book.

      Try implementing the capture API. If you face issues, let me know. I can help.

  • Zach Alvar

    Hi Arvind, great tutorial. Tested it on my HTC One M7 and works well. But i came across another blog where the guy was able to generate a .json from the songs and display the info about the song but its quite outdated, not sure if you are able to do this? Here is the post by the way: http://blog.jetboystudio.com/articles/angular-music-player/. Thanks!

  • http://udgwebdev.com/ Caio Ribeiro Pereira

    Nice post! Ionic is a good choice framework for hybrids app development.
    Today I’m using Meteoric package into my app (http://99folks.com), it’s a Ionic without Angular, instead it uses Meteor helpers and it’s a great option for developers who don’t like Angular and prefer something simple like Meteor framework which is also integrated with cordova by default.

  • ryan

    Hi Arvind, great tutorial. It tested on nexus 7 2012 and working well. But could you explain why it is slowe response than other file access app? Is it becase of ionic framework or cordova plugin? I tested with logcat. it has no error. But performance is a bit slow. How can it be improved? Thank for your tutorial. Just asking for buttery smoothness.

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks Ryan! Which areas are you seeing performance issues? The accessing file API part or the playing API or the switching between pages?

      • ryan

        Hi Arvind, It is accessing file API part, dude. If take time to list directory, and can’t go back to first level file list from second level file list. But can go back to root from first level file list. Anyway, it is great tutorial. Just want to know anyway to improve.

        And could you make a tutorial about android back button tutorials, which work as native app. $inoicPlatform.registerbackbuttonaction which working – Return to previous view, Close side menu, Dismiss modal, Close action sheet, Dismiss popup, Dismiss loading overlay – all functions properly. Thank advanced for whether new tutorials or any suggestions.

        • http://thejackalofjavascript.com/ Arvind Ravulavaru

          As of now I do not have a good solution for the slowness. I will let you know if I find any.

          Sure, I will think about that. Thanks!

  • Abdul Rahim

    I couldn’t access SD card. Only showing phone storage list. I am used the same code. What is the problem ? please

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Which device (phone make & model) are you using?

      • Mirko Scavazzin

        Same issue here, using Android in Sony Xperia M2.

  • Jonathan Obino

    just discovered your blog, never losing an incoming article in the future 😀

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks!

  • Darth

    Thanks for this! A couple things…

    1) I was getting an error, so I had to run “cordova plugin add com.ionic.keyboard”

    2) When I try to run it on my android device, I get a “Webpage not available” browser error, I believe because of the src value that is set in the platforms config.xml file which contains the following line:

    Any suggestions?

    • http://thejackalofjavascript.com/ Arvind Ravulavaru

      Thanks Darth! Fixed #1 in the post above. For #2, yes it depends on the content tag inside config.xml. You can read more here : https://cordova.apache.org/docs/en/4.0.0/config_ref_index.md.html

      If you have not modified the start up page in the Cordova/Ionic scaffolded app, the content tag shown below

      should work fine.

      Not sure how you have scaffolded the app, but you may need to update the config,xml’s content tag as above. Let me know if works.

      Thanks.