src/HTML5Sound.hx
import haxe.Timer;
import js.html.SourceElement;
import js.html.AudioElement;
@:keep class HTML5Sound extends BaseSound implements IWaudSound {
public var source:SourceElement;
var _snd:AudioElement;
var _tmr:Timer;
var _pauseTime:Float;
public function new(url:String, ?options:WaudSoundOptions = null, ?src:SourceElement) {
super(url, options);
_snd = Waud.dom.createAudioElement();
if (src == null) _addSource(url);
else _snd.appendChild(src);
if (_options.preload) load();
if (_b64.match(url)) url = "";
}
public function load(?callback:IWaudSound -> Void):IWaudSound {
if (!_isLoaded) {
_snd.autoplay = _options.autoplay;
_snd.loop = _options.loop;
_snd.volume = _options.volume;
_snd.playbackRate = rate;
if (callback != null) _options.onload = callback;
if (_options.preload) _snd.preload = "auto";
else _snd.preload = "metadata"; //none
if (_options.onload != null) {
_isLoaded = true;
_snd.onloadeddata = function() {
_options.onload(this);
}
}
_snd.onplaying = function() {
_isLoaded = true;
_isPlaying = true;
}
_snd.onended = function() {
_isPlaying = false;
if (_options.onend != null) _options.onend(this);
}
if (_options.onerror != null) {
_snd.onerror = function() {
_options.onerror(this);
}
}
_snd.load();
}
return this;
}
public function getDuration():Float {
if (!_isLoaded) return 0;
_duration = _snd.duration;
return _duration;
}
function _addSource(url:String):SourceElement {
source = Waud.dom.createSourceElement();
source.src = url;
if (Waud.audioManager.types.get(_getExt(url)) != null) source.type = Waud.audioManager.types.get(_getExt(url));
_snd.appendChild(source);
return source;
}
function _getExt(filename:String):String {
return filename.split(".").pop();
}
public function setVolume(val:Float, ?spriteName:String) {
if (val >= 0 && val <= 1) _options.volume = val;
if (!_isLoaded) return;
_snd.volume = _options.volume;
}
public function getVolume(?spriteName:String):Float {
return _options.volume;
}
public function mute(val:Bool, ?spriteName:String) {
if (!_isLoaded) return;
_snd.muted = val;
if (WaudUtils.isiOS()) {
if (val && isPlaying()) {
_muted = true;
_snd.pause();
}
else if (_muted) {
_muted = false;
_snd.play();
}
}
}
public function toggleMute(?spriteName:String) {
mute(!_muted);
}
public function play(?sprite:String, ?soundProps:AudioSpriteSoundProperties):Int {
spriteName = sprite;
if (!_isLoaded || _snd == null) {
trace("sound not loaded");
return -1;
}
if (_isPlaying) {
if (_options.autostop) stop(spriteName);
else {
var nsnd = cast(_snd.cloneNode(true), AudioElement);
if (nsnd.readyState == 4) {
nsnd.currentTime = 0;
nsnd.play();
}
else {
nsnd.oncanplay = function() {
nsnd.currentTime = 0;
nsnd.play();
};
}
nsnd.onended = function() {
Waud.dom.removeChild(nsnd);
}
}
}
if (_muted) return -1;
if (isSpriteSound && soundProps != null) {
_snd.currentTime = _pauseTime == null ? soundProps.start : _pauseTime;
if (_tmr != null) _tmr.stop();
_tmr = Timer.delay(function() {
if (soundProps.loop != null && soundProps.loop) {
play(spriteName, soundProps);
}
else stop(spriteName);
},
Math.ceil(soundProps.duration * 1000));
}
if (_snd.readyState == 4) _snd.play();
else {
_snd.oncanplay = function() {
_snd.play();
};
}
_pauseTime = null;
return 0;
}
public function togglePlay(?spriteName:String) {
if (_isPlaying) pause();
else play();
}
public function isPlaying(?spriteName:String):Bool {
return _isPlaying;
}
public function loop(val:Bool) {
if (!_isLoaded || _snd == null) return;
_snd.loop = val;
}
public function autoStop(val:Bool) {
_options.autostop = val;
}
public function stop(?spriteName:String) {
if (!_isLoaded || _snd == null) return;
_snd.currentTime = 0;
_snd.pause();
_isPlaying = false;
if (_tmr != null) _tmr.stop();
}
public function pause(?spriteName:String) {
if (!_isLoaded || _snd == null) return;
_snd.pause();
_pauseTime = _snd.currentTime;
_isPlaying = false;
if (_tmr != null) _tmr.stop();
}
public function playbackRate(?val:Float, ?spriteName:String):Float {
if (val == null) return rate;
_snd.playbackRate = val;
return rate = val;
}
public function setTime(time:Float) {
if (!_isLoaded || _snd == null || time > _snd.duration) return;
_snd.currentTime = time;
}
public function getTime():Float {
if (_snd == null || !_isLoaded || !_isPlaying) return 0;
return _snd.currentTime;
}
public function onEnd(callback:IWaudSound -> Void, ?spriteName:String):IWaudSound {
_options.onend = callback;
return this;
}
public function onLoad(callback:IWaudSound -> Void):IWaudSound {
_options.onload = callback;
return this;
}
public function onError(callback:IWaudSound -> Void):IWaudSound {
_options.onerror = callback;
return this;
}
public function destroy() {
if (_snd != null) {
_snd.pause();
_snd.removeChild(source);
source = null;
_snd = null;
}
_isPlaying = false;
}
}