Created
November 16, 2016 21:21
-
-
Save biesbjerg/124cdbc4af8493a5b26bdd429c6b49f5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Observable } from 'rxjs/Observable'; | |
import { Subject } from 'rxjs/Subject'; | |
import { AbstractAudioEngine } from './abstract-audio-engine'; | |
export class CordovaMediaAudioEngine extends AbstractAudioEngine { | |
private _play: Subject<boolean> = new Subject(); | |
private _pause: Subject<boolean> = new Subject(); | |
private _ended: Subject<boolean> = new Subject(); | |
private _time: Subject<{ currentTime: number, duration: number }> = new Subject(); | |
private _error: Subject<{ code: number, message: string}> = new Subject(); | |
public play$: Observable<boolean> = this._play.asObservable(); | |
public pause$: Observable<boolean> = this._pause.asObservable(); | |
public ended$: Observable<boolean> = this._ended.asObservable(); | |
public time$: Observable<{ currentTime: number, duration: number }> = this._time.asObservable(); | |
public error$: Observable<{ code: number, message: string}> = this._error.asObservable(); | |
protected _media: Media; | |
protected _playing: boolean = false; | |
protected _currentTime: number = 0; | |
protected _duration: number = 0; | |
protected _initialize(): void { | |
this._media = new Media( | |
this.src, | |
null, | |
error => this._errorHandler(error), | |
status => this._statusHandler(status) | |
); | |
} | |
public play(): void { | |
if (!this._media) { | |
return; | |
} | |
this._media.play(); | |
} | |
public pause(): void { | |
if (!this._media) { | |
return; | |
} | |
this._media.pause(); | |
} | |
public stop(): void { | |
if (!this._media) { | |
return; | |
} | |
this._media.pause(); | |
this._media.seekTo(0); | |
} | |
public seekTo(seconds: number): void { | |
this._media.seekTo(seconds * 1000); | |
} | |
public destroy(): void { | |
if (!this._media) { | |
return; | |
} | |
this._media.pause(); | |
this._media.release(); | |
} | |
protected _statusHandler(status: number): void { | |
if (status === Media.MEDIA_RUNNING) { | |
this._playing = true; | |
this._play.next(this._playing); | |
this._pollTime(); | |
return; | |
} | |
const ended = (status === Media.MEDIA_STOPPED && this._playing); | |
this._playing = false; | |
this._pause.next(this._playing); | |
if (ended) { | |
this._ended.next(this._playing); | |
} | |
} | |
protected _pollTime(): void { | |
if (!this._media) { | |
return; | |
} | |
if (this._duration <= 0) { | |
const duration = this._media.getDuration(); | |
if (duration > 0) { | |
this._duration = duration; | |
} | |
} | |
if (!this._playing) { | |
return; | |
} | |
this._media.getCurrentPosition(currentTime => { | |
if (currentTime > 0) { | |
this._currentTime = Math.min(currentTime, this._duration); | |
} | |
this._time.next({ | |
currentTime: this._currentTime, | |
duration: this._duration | |
}); | |
if (this._playing) { | |
setTimeout(() => this._pollTime(), 250); | |
} | |
}); | |
} | |
protected _errorHandler(code: any): void { | |
const message = this._getErrorMessage(code); | |
this._error.next({ | |
code, message | |
}); | |
} | |
protected _getErrorMessage(error: any): string { | |
switch (error) { | |
case 1: 'Fetching process aborted by user'; | |
case 2: return 'Error occurred when downloading'; | |
case 3: return 'Error occurred when decoding'; | |
case 4: return 'Audio/video not supported'; | |
default: return 'Unknown Error'; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment