Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposes the volume controls for WebAudioTrack and CordovaAudioTrack #101

Open
wants to merge 1 commit into
base: 2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 64 additions & 52 deletions dist/ionic-audio-cordova-track.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {IAudioTrack} from './ionic-audio-interfaces';
import {IAudioTrack} from './ionic-audio-interfaces';
import {Injectable} from '@angular/core';

declare let Media: any;

/**
* Cordova Media audio track
*
*
* @export
* @class CordovaAudioTrack
* @constructor
Expand All @@ -23,24 +23,24 @@ export class CordovaAudioTrack implements IAudioTrack {
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();

this.createAudio();
}

private createAudio() {
this.audio = new Media(this.src, () => {
console.log('Finished playback');
this.stopTimer();
this.isFinished = true;
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);
console.log(`Audio error => track ${this.src}`, err);
}, (status) => {
switch (status) {
case Media.MEDIA_STARTING:
Expand All @@ -50,86 +50,86 @@ export class CordovaAudioTrack implements IAudioTrack {
case Media.MEDIA_RUNNING:
console.log(`Playing track ${this.src}`);
this.isPlaying = true;
this._isLoading = false;
break;
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(() => {
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;
this._completed = this._duration > 0 ? Math.round(this._progress / this._duration * 100)/100 : 0;
}
}, (e) => {
console.log("Error getting position", e);
}
);
}, 1000);
}, 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}
Expand All @@ -141,105 +141,117 @@ export class CordovaAudioTrack implements IAudioTrack {
/**
* Gets any errors logged by HTML5 audio
*
* @property error
* @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
* @property hadLoaded
* @readonly
* @type {boolean}
*/
public get hasLoaded() : boolean {
return this._hasLoaded;
}

/**
* Plays current track
*
*
* @method play
*/
play() {
if (!this.audio) {
this.createAudio();
this.createAudio();
}

if (!this._hasLoaded) {
console.log(`Loading track ${this.src}`);
this._isLoading = true;
}

this.audio.play();
this.startTimer();
}

/**
* Pauses current track
*
* @method pause
* @method pause
*/
pause() {
if (!this.isPlaying) return;
console.log(`Pausing track ${this.src}`);
this.audio.pause();
this.stopTimer();
this.stopTimer();
}

/**
* Stops current track and releases audio
*
* @method stop
* @method stop
*/
stop() {
this.audio.stop(); // calls Media onSuccess callback
}

/**
* Seeks to a new position within the track
*
* @method seekTo
* @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);
}


/**
* Sets the volume of the current track. Valid values are (0, 1) inclusive.
*
* @method setVolume
* @param v {number} the new volume to set
*/
setVolume(v: number) {
// Valid values are (0,1) inclusive.
const volume = Math.min(Math.max(0, v), 1);
this.audio.setVolume(volume);
}

/**
* Releases audio resources
*
*
* @method destroy
*/
destroy() {
this.audio.release();
this.audio.release();
console.log(`Released track ${this.src}`);
}
}
}
19 changes: 10 additions & 9 deletions dist/ionic-audio-interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@

/**
* Defines the audio provider contract
*
*
* @export
* @interface IAudioProvider
*/
export interface IAudioProvider {
current: number;
tracks: IAudioTrack[];

create(track: ITrackConstraint): IAudioTrack;
add(track: IAudioTrack);
play(index: number);
pause(index?: number);
stop(index?: number);
}
}

/**
* Defines the properties for JSON objects representing tracks to be played
*
*
* @export
* @interface ITrackConstraint
*/
Expand All @@ -27,33 +27,34 @@ export interface ITrackConstraint {
src: string;
title?: string;
artist?: string;
art?: string;
art?: string;
preload?: string;
}

/**
* Defines the audio track contract
*
* Defines the audio track contract
*
* @export
* @interface IAudioTrack
* @extends {ITrackConstraint}
*/
export interface IAudioTrack extends ITrackConstraint {
src: string;
id: number;
isPlaying: boolean;
isPlaying: boolean;
isLoading: boolean;
isFinished: boolean;
duration: number;
progress: number;
completed: number;
canPlay: boolean;
error: MediaError;

play();
pause();
stop();
seekTo(time: number);
setVolume(volume: number);
destroy();
}

Expand Down
Loading