@martin-juul/nativescript-astreamer
Version:
NativeScript plugin to play audio from filesystem and network.
368 lines (367 loc) • 15 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var app = require("tns-core-modules/application");
var observable_1 = require("tns-core-modules/data/observable");
var utils_1 = require("tns-core-modules/utils/utils");
var common_1 = require("../common");
var options_1 = require("../options");
var NSAudioPlayer = (function () {
function NSAudioPlayer() {
var _this = this;
this._mAudioFocusGranted = false;
this._mOnAudioFocusChangeListener = new android.media.AudioManager.OnAudioFocusChangeListener({
onAudioFocusChange: function (focusChange) {
switch (focusChange) {
case android.media.AudioManager.AUDIOFOCUS_GAIN:
_this.log.info('AUDIOFOCUS_GAIN');
_this.log.info('this._lastPlayerVolume', _this._lastPlayerVolume);
if (_this._lastPlayerVolume && _this._lastPlayerVolume >= 10) {
_this.volume = 1.0;
}
else if (_this._lastPlayerVolume) {
_this.volume = parseFloat('0.' + _this._lastPlayerVolume.toString());
}
_this.resume();
break;
case android.media.AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
_this.log.info('AUDIOFOCUS_GAIN_TRANSIENT');
break;
case android.media.AudioManager.AUDIOFOCUS_LOSS:
_this.log.info('AUDIOFOCUS_LOSS');
_this.pause();
break;
case android.media.AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
_this.log.info('AUDIOFOCUS_LOSS_TRANSIENT');
_this.pause();
break;
case android.media.AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
_this.log.info('AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK');
_this._lastPlayerVolume = _this.volume;
_this.log.info('this._lastPlayerVolume', _this._lastPlayerVolume);
_this.volume = 0.2;
break;
}
}
});
this.log = new common_1.NS_AUDIO_LOGGER('android');
this._mAudioFocusGranted = this._requestAudioFocus();
this.log.info('_mAudioFocusGranted', this._mAudioFocusGranted);
}
Object.defineProperty(NSAudioPlayer.prototype, "events", {
get: function () {
if (!this._events) {
this._events = new observable_1.Observable();
}
return this._events;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NSAudioPlayer.prototype, "android", {
get: function () {
return this._player;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NSAudioPlayer.prototype, "debug", {
set: function (value) {
common_1.NS_AUDIO_UTIL.debug = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NSAudioPlayer.prototype, "volume", {
get: function () {
var ctx = this._getAndroidContext();
var mgr = ctx.getSystemService(android.content.Context.AUDIO_SERVICE);
return mgr.getStreamVolume(android.media.AudioManager.STREAM_MUSIC);
},
set: function (value) {
if (this._player && value >= 0) {
this._player.setVolume(value, value);
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(NSAudioPlayer.prototype, "duration", {
get: function () {
if (this._player) {
return this._player.getDuration();
}
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(NSAudioPlayer.prototype, "currentTime", {
get: function () {
return this._player ? this._player.getCurrentPosition() : 0;
},
enumerable: true,
configurable: true
});
NSAudioPlayer.prototype.initFromFile = function (options) {
options.autoPlay = false;
return this.playFromFile(options);
};
NSAudioPlayer.prototype.playFromFile = function (options) {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (options.autoPlay !== false) {
options.autoPlay = true;
}
var audioPath = common_1.resolveAudioFilePath(options.audioFile);
_this.log.info('audioPath', audioPath);
if (!_this._player) {
_this.log.info('android mediaPlayer is not initialized, creating new instance');
_this._player = new android.media.MediaPlayer();
}
_this._mAudioFocusGranted = _this._requestAudioFocus();
_this.log.info('_mAudioFocusGranted', _this._mAudioFocusGranted);
_this._player.setAudioStreamType(android.media.AudioManager.STREAM_MUSIC);
_this.log.info('resetting mediaPlayer...');
_this._player.reset();
_this.log.info('setting datasource', audioPath);
_this._player.setDataSource(audioPath);
if (utils_1.isFileOrResourcePath(audioPath)) {
_this.log.info('preparing mediaPlayer...');
_this._player.prepare();
}
else {
_this.log.info('preparing mediaPlayer async...');
_this._player.prepareAsync();
}
if (options.completeCallback) {
_this._player.setOnCompletionListener(new android.media.MediaPlayer.OnCompletionListener({
onCompletion: function (mp) {
if (options.loop === true) {
mp.seekTo(5);
mp.start();
}
options.completeCallback({ player: mp });
}
}));
}
if (options.errorCallback) {
_this._player.setOnErrorListener(new android.media.MediaPlayer.OnErrorListener({
onError: function (player, error, extra) {
_this._player.reset();
_this.log.error('errorCallback', error);
options.errorCallback({ player: player, error: error, extra: extra });
return true;
}
}));
}
if (options.infoCallback) {
_this._player.setOnInfoListener(new android.media.MediaPlayer.OnInfoListener({
onInfo: function (player, info, extra) {
_this.log.info('infoCallback', info);
options.infoCallback({ player: player, info: info, extra: extra });
return true;
}
}));
}
_this._player.setOnPreparedListener(new android.media.MediaPlayer.OnPreparedListener({
onPrepared: function (mp) {
_this.log.info({ mp: mp });
if (options.autoPlay) {
_this.log.info('options.autoPlay', options.autoPlay);
_this.play();
}
resolve();
}
}));
}
catch (e) {
_this.log.error('playFromFile error', e);
reject(e);
}
});
};
NSAudioPlayer.prototype.initFromUrl = function (options) {
options.autoPlay = false;
return this.playFromUrl(options);
};
NSAudioPlayer.prototype.playFromUrl = function (options) {
return this.playFromFile(options);
};
NSAudioPlayer.prototype.pause = function () {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (_this._player && _this._player.isPlaying()) {
_this.log.info('pausing player');
_this._player.pause();
_this._sendEvent(options_1.AudioPlayerEvent.PAUSED);
}
resolve(true);
}
catch (e) {
_this.log.error('pause error', e);
reject(e);
}
});
};
NSAudioPlayer.prototype.play = function () {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (_this._player && !_this._player.isPlaying()) {
_this._sendEvent(options_1.AudioPlayerEvent.STARTED);
app.android.foregroundActivity.setVolumeControlStream(android.media.AudioManager.STREAM_MUSIC);
app.android.registerBroadcastReceiver(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY, function (context, intent) {
_this.log.info('ACTION_AUDIO_BECOMING_NOISY onReceiveCallback');
_this.log.info('intent', intent);
_this.pause();
});
_this._player.start();
}
resolve(true);
}
catch (e) {
_this.log.error('Error trying to play audio.', e);
reject(e);
}
});
};
NSAudioPlayer.prototype.resume = function () {
if (this._player) {
this.log.info('resume');
this._player.start();
this._sendEvent(options_1.AudioPlayerEvent.PAUSED);
}
};
NSAudioPlayer.prototype.seekTo = function (time) {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (_this._player) {
time = time * 1000;
_this.log.info('seekTo seconds', time);
_this._player.seekTo(time);
_this._sendEvent(options_1.AudioPlayerEvent.SEEK);
}
resolve(true);
}
catch (e) {
_this.log.error('seekTo error', e);
reject(e);
}
});
};
NSAudioPlayer.prototype.changePlayerSpeed = function (speed) {
if (android.os.Build.VERSION.SDK_INT >= 23 && this.play) {
this.log.info('setting the mediaPlayer playback speed', speed);
if (this._player.isPlaying()) {
this._player.setPlaybackParams(this._player.getPlaybackParams()
.setSpeed(speed));
}
else {
this._player.setPlaybackParams(this._player.getPlaybackParams()
.setSpeed(speed));
this._player.pause();
}
}
else {
throw new Error('Android device API is not 23+. Cannot set the playbackRate on lower Android APIs.');
}
};
NSAudioPlayer.prototype.dispose = function () {
if (!this._player) {
return;
}
try {
this.log.info('disposing of mediaPlayer instance', this._player);
this._player.stop();
this._player.reset();
this.log.info('unregisterBroadcastReceiver ACTION_AUDIO_BECOMING_NOISY...');
app.android.unregisterBroadcastReceiver(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY);
this.log.info('abandoning audio focus...');
this._abandonAudioFocus();
return;
}
catch (e) {
this.log.error('dispose error', e);
throw e;
}
};
NSAudioPlayer.prototype.isAudioPlaying = function () {
if (this._player) {
return this._player.isPlaying();
}
else {
return false;
}
};
NSAudioPlayer.prototype.getAudioTrackDuration = function () {
var _this = this;
return new Promise(function (resolve, reject) {
try {
var duration = _this._player ? _this._player.getDuration() : 0;
_this.log.info('audio track duration', duration);
resolve(duration.toString());
}
catch (e) {
_this.log.error('getAudioTrackDuration error', e);
reject(e);
}
});
};
NSAudioPlayer.prototype._sendEvent = function (eventName, data) {
if (this.events) {
this.events.notify({
eventName: eventName,
object: this,
data: data
});
}
};
NSAudioPlayer.prototype._requestAudioFocus = function () {
var result = false;
if (!this._mAudioFocusGranted) {
var ctx = this._getAndroidContext();
var am = ctx.getSystemService(android.content.Context.AUDIO_SERVICE);
var focusResult = am.requestAudioFocus(this._mOnAudioFocusChangeListener, android.media.AudioManager.STREAM_MUSIC, android.media.AudioManager.AUDIOFOCUS_GAIN);
if (focusResult === android.media.AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
result = true;
}
else {
this.log.error('Failed to get audio focus.');
result = false;
}
}
return result;
};
NSAudioPlayer.prototype._abandonAudioFocus = function () {
var ctx = this._getAndroidContext();
var am = ctx.getSystemService(android.content.Context.AUDIO_SERVICE);
var result = am.abandonAudioFocus(this._mOnAudioFocusChangeListener);
if (result === android.media.AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
this._mAudioFocusGranted = false;
}
else {
this.log.error('Failed to abandon audio focus.');
}
this._mOnAudioFocusChangeListener = null;
};
NSAudioPlayer.prototype._getAndroidContext = function () {
var _this = this;
var ctx = app.android.context;
if (!ctx) {
ctx = app.getNativeApplication()
.getApplicationContext();
}
if (ctx === null) {
setTimeout(function () {
_this._getAndroidContext();
}, 200);
return;
}
return ctx;
};
return NSAudioPlayer;
}());
exports.NSAudioPlayer = NSAudioPlayer;