API Docs for:
Show:

File: ionic-audio-cordova-track.ts

import {IAudioProvider, ITrackConstraint, IAudioTrack} from './ionic-audio-interfaces'; 
import {Injectable, Inject, Optional} from 'angular2/core';

declare let Media: any;

/**
 * Cordova Media audio track
 * 
 * @export
 * @class CordovaAudioTrack
 * @constructor
 * @implements {IAudioTrack}
 */
@Injectable()
export class CordovaAudioTrack implements IAudioTrack {
  private audio: any;
  public isPlaying: boolean = false;
  public isFinished: boolean = false;
  private _progress: number;
  private _completed: number;
  private _duration: number;
  private _id: number;
  private _isLoading: boolean;
  private _hasLoaded: boolean;
  private _timer: any;
  
  constructor(public src: string) {
    if (window['cordova'] === undefined || window['Media'] === undefined) {
      console.log('Cordova Media is not available');
      return;
    };
    
    this.createAudio(); 
  }
  
  private createAudio() {
    this.audio = new Media(this.src, () => {
       console.log('Finished playback');
       this.stopTimer();
       this.isFinished = true;  
       this.destroy();  // TODO add parameter to control whether to release audio on stop or finished
    }, (err) => {
      console.log(`Audio error => track ${this.src}`, err);   
    }, (status) => {
      switch (status) {
        case Media.MEDIA_STARTING:
          console.log(`Loaded track ${this.src}`);
          this._hasLoaded = true;
          break;
        case Media.MEDIA_RUNNING:
          console.log(`Playing track ${this.src}`);
          this.isPlaying = true;
          this._isLoading = false;          
          break; 
        case Media.MEDIA_PAUSED:
          this.isPlaying = false;
          break
        case Media.MEDIA_STOPPED:
          this.isPlaying = false;
          break;
      }
    });  
  }
  
  private startTimer() {
    this._timer = setInterval(() => {  
      if (this._duration===undefined || this._duration < 0) {
        this._duration = Math.round(this.audio.getDuration()*100)/100;
      }  
      
      this.audio.getCurrentPosition((position) => {
            if (position > -1) {
              this._progress = Math.round(position*100)/100;
              this._completed = this._duration > 0 ? Math.round(this._progress / this._duration * 100)/100 : 0; 
            }
        }, (e) => {
            console.log("Error getting position", e);
        }
      );
    }, 1000);  
  }
  
  private stopTimer() {
    clearInterval(this._timer);
  }
  
  /** public members */

  /**
 * Gets the track id
 * 
 * @property id
 * @type {number}
 */
  public get id() : number {
    return this._id;
  }
  
  /**
 * Sets the track id
 * 
 * @property id
 */
  public set id(v : number) {
    this._id = v;
  }
  
  /**
 * Gets the track duration, or -1 if it cannot be determined
 * 
 * @property duration
 * @readonly
 * @type {number}
 */
  public get duration() : number {
    return this._duration;
  }
  
  /**
 * Gets current track time (progress)
 * 
 * @property progress
 * @readonly
 * @type {number}
 */
  public get progress() : number {
    return this._progress;
  } 
  
  /**
 * Gets current track progress as a percentage
 * 
 * @property completed
 * @readonly
 * @type {number}
 */
  public get completed() : number {
    return this._completed;
  }

/**
 * Gets any errors logged by HTML5 audio
 *
 * @property error 
 * @readonly
 * @type {MediaError}
 */
  public get error() : MediaError {
    return this.audio.error;
  }
  
  /**
 * Gets a boolean value indicating whether the current source can be played
 * 
 * @property canPlay
 * @readonly
 * @type {boolean}
 */
  public get canPlay() : boolean {
    return true;
  }
  
  /**
 * Gets a boolean value indicating whether the track is in loading state
 * 
 * @property isLoading
 * @readonly
 * @type {boolean}
 */
  public get isLoading() : boolean {
    return this._isLoading;
  }
  
  /**
 * Gets a boolean value indicating whether the track has finished loading
 *
 * @property hadLoaded 
 * @readonly
 * @type {boolean}
 */
  public get hasLoaded() : boolean {
    return this._hasLoaded;
  }
  
  /**
 * Plays current track
 * 
 * @method play
 */
  play() {
    if (!this.audio) {
      this.createAudio(); 
    }
    
    if (!this._hasLoaded) {
      console.log(`Loading track ${this.src}`);
      this._isLoading = true;
    }
    
    this.audio.play();
    this.startTimer();
  }
  
  /**
 * Pauses current track
 *
 * @method pause 
 */
  pause() {
    if (!this.isPlaying) return;
    console.log(`Pausing track ${this.src}`);
    this.audio.pause();
    this.stopTimer();  
  }
  
  /**
 * Stops current track and releases audio
 *
 * @method stop 
 */
  stop() {
    this.audio.stop();  // calls Media onSuccess callback
  }
  
  /**
 * Seeks to a new position within the track
 *
 * @method seekTo 
 * @param {number} time the new position (milliseconds) to seek to
 */
  seekTo(time: number) {
    // Cordova Media reports duration and progress as seconds, so we need to multiply by 1000
    this.audio.seekTo(time*1000);
  }
  
  /**
   * Releases audio resources
   * 
   * @method destroy
   */
  destroy() {
    this.audio.release();  
    console.log(`Released track ${this.src}`);
  }
}