Skip to content

Instantly share code, notes, and snippets.

@biesbjerg
Created November 16, 2016 21:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biesbjerg/124cdbc4af8493a5b26bdd429c6b49f5 to your computer and use it in GitHub Desktop.
Save biesbjerg/124cdbc4af8493a5b26bdd429c6b49f5 to your computer and use it in GitHub Desktop.
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