Ionic-audio

An audio player for Ionic 1.x based on the Cordova Media Plugin

View the Project on GitHub arielfaur/ionic-audio


If you've found this project useful please consider donating to support further development. Thank you!

News

28-Apr-2016

Ionic-audio for Ionic 2 / Angular 2 released!

Get it here

This module creates an audio player UI for Ionic. It creates an interface to the cordova-media plugin including a service that controls Media playback and directives to define the look and feel of the player.

Features

Demo

You need a real device to test audio playback but these demos can be used to tweak the UI. You can also run the example projects locally with ionic serve if you prefer.

Usage

Install dependencies

Cordova media plugin

ionic plugin add cordova-plugin-media

Install this module using bower

bower install ionic-audio

There's a sample Ionic project in the folder example-audio. The project contains not platforms, so you must add one and make a build if you want to test it on your device. Keep in mind that the module depends on a Cordova plugin so the module won't run locally with ionic serve. However, you can still run the project locally to tune the UI before deploying to the device.

Include JS file

<script src="dist/ion-audio.js"></script>

Inject the dependency in your app's module

angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'ionic-audio'])

Define your player UI using directives as in the follow example

<ion-view view-title="Music">
  <ion-content>
      <ion-audio-track track="track">
          <div class="list list-inset">
              <div class="item item-thumbnail-left">
                  <img src="{{track.art}}">
                  <h2>{{track.title}}</h2>
                  <p>{{track.artist}}</p>
                  <ion-audio-controls>
                        <a class="button button-icon icon" ion-audio-play></a>
                        <ion-spinner icon="ios"></ion-spinner>
                    </ion-audio-controls>
              </div>
              <div class="item">
                <ion-audio-progress-bar track="track" display-time></ion-audio-progress-bar>
              </div>
          </div>
      </ion-audio-track>
  </ion-content>
</ion-view>

Directives

ion-audio-track

Creates an audio track from a JSON object passed as parameter using the track attribute. The player UI is defined inside the body of ion-audio-track. Supports multiple instances per view, each one being completely independent.

<ion-audio-track track="myTrack">
...
</ion-audio-track>

Then in your controller:

$scope.myTrack = {
    url: 'https://www.example.com/my_song.mp3',
    artist: 'Somebody',
    title: 'Song name',
    art: 'img/album_art.jpg'
}

NEW in version 1.3.0:

You can now dynamically assign a track to the ion-audio-track directive. There is also a new scope property toggle-playback that can be used to control playback if needed. The module will simply listen to changes in the toggle-playback property and toggle playback regardless of the property value.

<button class="button button-assertive" ng-click="playTrack(0)">Play first track</button>
<ion-audio-track track="dynamicTrack" toggle-playback="togglePlayback">
      <div class="card">
          <div class="item">
              <h2>{{dynamicTrack.title}}</h2>

              <p>{{dynamicTrack.artist}}</p>
              <ion-audio-controls>
                  <a class="button button-icon icon" ion-audio-play></a>
                  <ion-spinner icon="ios" style="position: relative; top: 8px; left: 4px"></ion-spinner>
              </ion-audio-controls>
          </div>
          <div class="item item-divider">
              <ion-audio-progress-bar track="dynamicTrack" display-time></ion-audio-progress-bar>
          </div>
      </div>
</ion-audio-track>

.controller('MusicCtrl', ['$scope', 'MediaManager', function($scope, MediaManager) {
    
    $scope.dynamicTrack = {};   // we use this scope variable to dynamically assign a track

    $scope.tracks = [
        {
            url: 'http://myserver.com/audio/Track1.mp3',  // audio file from the cloud
            artist: 'The Police',
            title: 'Roxane'
        },
        {
            url: '/android_asset/www/audio/Track2.mp3', // audio file stored in device's app folder
            artist: 'Genesis',
            title: 'Tonight. Tonight. Tonight'
        }
    ];

    $scope.stopPlayback = function() {
        MediaManager.stop();  // will stop any audio currently playing
    };

    $scope.playTrack = function(index) {
        $scope.dynamicTrack = $scope.tracks[index];   // assign one track

        $scope.togglePlayback = !$scope.togglePlayback; // start playback when track changes    
    };
}]);

ion-audio-controls

Container for ion-audio-play and ion-spinner directives. The spinner is automatically hidden/shown when needed.

ion-audio-play

Displays play/pause/loading status. Simply apply this attribute to an a or button element. It updates the UI accordingly and shows a spinner while the track is loading. Additionally, the attributes text-play and text-pause may be used to include a label for each status.

<a class="button button-icon icon" ion-audio-play></a>

<button class="button icon-left" ion-audio-play text-play="Play" text-pause="Pause"></button>

ion-audio-progress-bar

Shows a progress bar using Ionic's range control. It also displays the track duration and progress update if the display-time attribute is present. The current track instance needs to be passed to the track property.

<ion-audio-progress-bar track="myTrack" display-time></ion-audio-progress-bar>

Sample use case: tracks listed with an embedded progress bar.

Use as a global progress bar

If a ion-audio-progress-bar is placed outside the scope of ion-audio-track, it will automatically behave as a standalone bar keeping in sync with the track list. Add a display-info attribute to show the current playing track. In this case there is no need to pass a track property because the progress bar is outside the scope.

<ion-audio-progress-bar display-time display-info></ion-audio-progress-bar>

Sample use case: tracks listed with a global progress bar.

API

MediaManager

Inject MediaManager in your controller if you need access to the currently playing track. For example, in order to stop playback before transitioning to another state or performing any other action:


.controller('MusicCtrl', ['$scope', 'MediaManager', function($scope, MediaManager) {

    // bind stop button in view
    $scope.stopPlayback = function() {
        MediaManager.stop();
    };

    // stop any track before leaving current view
    $scope.$on('$ionicView.beforeLeave', function() {
        MediaManager.stop();
    });

}]);

<ion-view view-title="Music">
    <ion-content>
        <button class="button button-assertive" ng-click="stopPlayback()">Stop all</button>
        <ion-audio-track track="track">
              <div class="list list-inset">
                  <div class="item item-thumbnail-left">
                      <img src="{{track.art}}">
                      <h2>{{track.title}}</h2>
                      <p>{{track.artist}}</p>
                      <ion-audio-controls>
                            <a class="button button-icon icon" ion-audio-play></a>
                            <ion-spinner icon="ios"></ion-spinner>
                        </ion-audio-controls>
                  </div>
                  <div class="item">
                    <ion-audio-progress-bar display-time></ion-audio-progress-bar>
                  </div>
              </div>
          </ion-audio-track>
    </ion-content>
</ion-view>

TODO