anghami-audio-manager
Version:
Web audio manager
802 lines (770 loc) • 47.6 kB
HTML
<!DOCTYPE html>
<html>
<head>
<title>SimpleAudioPlayer</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<script src="https://cdn.jsdelivr.net/bluebird/3.5.0/bluebird.js"></script>
<script type="text/javascript">!function(a, b) {
var c = this, d = c.document, e = "audio", f = "video", g = function() {
function a() {
this.regex = {
platform: {
playstation: new RegExp("^Mozilla/[0-9].[0-9]\\s.(PlayStation [3-5]).*\\sSCEE/[1-9].[0-9]\\sNuanti/[1-9].[0-9]"),
mobile: new RegExp("Mobile|Android|Tab|Tablet|GT|SM-(T|P)|Silk-Accelerated", "i"),
tablet: new RegExp("Tab|Tablet|iPad|SM-(T|P)|GT|Silk-Accelerated", "i"),
desktop: new RegExp("(?:(?!Mobile|Android|Tab|Tablet|GT|SM-(T|P)|Silk-Accelerated).)", "i")
},
os: {
android: new RegExp("Linux.*Android"),
ios: new RegExp("like\\sMac\\sOS\\sX"),
mac: new RegExp("Intel\\sMac\\sOS\\sX"),
windows: new RegExp("Windows\\sNT")
},
browser: {
chrome: new RegExp("Chrome"),
firefox: new RegExp("Firefox")
}
}, this.canInit = !1, c.navigator && c.navigator.userAgent && c.RegExp && "function" == typeof c.RegExp ? this.canInit = !0 : this.throwErr();
}
return a.prototype.detectDevice = function() {
return {
platform: this.detect("platform"),
os: this.detect("os"),
browser: this.detect("browser")
};
}, a.prototype.detect = function(a) {
if (this.canInit) {
var b = this.regex[a], d = void 0;
for (d in b) if (b[d].test(c.navigator.userAgent)) return d;
} else this.throwErr();
}, a.prototype.throwErr = function() {
if (c.Error && "function" == typeof c.Error) throw new Error("This browser doesn't supprot platform detection.");
}, a;
}(), h = function() {
function a() {
this.setup();
}
return a.prototype.setup = function() {
var a = this;
this.audioElementEvents = {
abort: function(b) {
a.checkError(b);
},
stalled: function(b) {
a.checkError(b);
},
suspend: function(b) {
a.checkError(b);
},
error: function(b) {
if (a.checkError(b), a.options.video && a.isUsingHLSPolyfill) {
var c = b.currentTarget.error;
c.code === c.MEDIA_ERR_DECODE && a.hlsVideoTagErrorHandler();
}
},
emptied: function(b) {
a.audioTrackPlaying = void 0;
},
waiting: function(b) {
a.checkError(b), a.hasBuffer() && a.onBufferChange(b), a.dispatchEvent("wait", {
status: a.audioTrackPlaying
});
},
loadedmetadata: function(b) {
a.metadata = !0;
},
loadstart: function(b) {
a.dispatchEvent("wait", {
status: a.audioTrackPlaying
}), a.audioTrackPlaying = void 0, a.hasBuffer() && a.onBufferChange(b);
},
durationchange: function(b) {
a.isValid() && a.onDurationChange(b), a.lastPosition && (a.setPosition(a.lastPosition),
a.lastPosition = void 0), a.duration = b.target.duration;
},
timeupdate: function(b) {
a.playState = !0, a.isValid() && (a.onDurationChange(b), a.audioTrackPlaying = !0),
a.hasBuffer() && a.onBufferChange(b), a.isReloading && (a.isReloading = a.error = !1),
100 === a.bufferProgress && a.clearWaiters();
},
canplay: function(b) {
a.dispatchEvent("readyToPlay", {
track: a.currentMediaItem,
src: a.currentSrc,
progress: a.progress
}), a.audioTrackPlaying = !0, a.play();
},
playing: function(b) {
a.audioTrackPlaying = !0, a.isValid() && a.dispatchEvent("play", {
status: a.audioTrackPlaying
}), a.hasBuffer() && a.onBufferChange(b);
},
pause: function(b) {
a.audioTrackPlaying = !1, a.isValid() && a.dispatchEvent("pause", {
status: a.audioTrackPlaying
});
},
ended: function(b) {
a.isValid() && a.dispatchEvent("end", {
progress: a.progress
});
},
progress: function(b) {
a.hasBuffer() && a.onBufferChange(b);
},
ratechange: function(b) {
a.isValid() && a.dispatchEvent("rateChange");
},
volumechange: function(b) {
a.isValid() && a.dispatchEvent("volumeChange");
},
seeking: function(b) {
a.pause();
},
seeked: function(b) {
a.play();
}
}, this.options = {
html5: !1,
reloadOnInit: 1e4,
reloadOnError: 5e3,
volume: 1
}, this.emptyWaveFileBase64 = "data:audio/wave;base64,UklGRjIAAABXQVZFZm10IBIAAAABAAEAQB8AAEAfAAABAAgAAABmYWN0BAAAAAAAAABkYXRhAAAAAA==",
this.mimeRegx = new RegExp(/\.m4a|mp4|mpeg4|aac|flv|mov|m4v|f4v|.m4b|mp4v|3gp|3g2|mp4|m3u8/),
this.eventMap = {}, this.list = this.playNextList = this.shuffleList = [], this.currentMediaItem = {},
this.online = !0, this.bufferProgress = this.progress = this.lastBufferProgress = this.position = this.remainingTime = this.currentIndex = this.shuffleIndex = this.duration = 0,
this.audioElement = this.errorTimeout = this.lastPosition = this.error = this.metadata = this.isRepeating = this.isShuffling = this.isPaused = this.isReloading = this.interval = this.onlinecbreload = this.playState = this.playPromise = this.forceDurationChangeForAudioAd = void 0,
this.device = new g().detectDevice(), this.windows = "windows" === this.device.os,
this.playstation = "playstation" === this.device.platform, this.loadEmpty = function() {
return function() {
return a.load(!1).play(), a;
};
}(), this.windows || this.playstation || (c.addEventListener("offline", this.offlinecb, !1),
c.addEventListener("online", this.onlinecb, !1));
}, a.prototype.appendHLSEvents = function() {
var a = this;
this.hls.on(c.Hls.Events.MANIFEST_PARSED, function() {
a.play();
}), this.hls.on(c.Hls.Events.ERROR, function(b, d) {
if (d.fatal) switch (d.type) {
case c.Hls.ErrorTypes.NETWORK_ERROR:
a.hls.startLoad();
break;
case c.Hls.ErrorTypes.MEDIA_ERROR:
a.hlsjsErrorHandler();
break;
default:
a.destoryHLS();
}
});
}, a.prototype.init = function(a) {
return this.setOptions(a).createMedia().addEventListeners(this.audioElement, this.audioElementEvents),
this.isUsingHLSPolyfill || this.setSrc(this.emptyWaveFileBase64).setAttribute("src", this.currentSrc).setAttribute("preload", "none"),
this;
}, a.prototype.isOnline = function() {
var a = new XMLHttpRequest();
a.open("HEAD", "//" + c.location.hostname + "/?rand=" + c.Math.floor(65536 * (1 + c.Math.random())), !1);
try {
return a.send(), a.status >= 200 && (a.status < 300 || 304 === a.status);
} catch (a) {
return !1;
}
}, a.prototype.waitUntilOnline = function() {
var a = this;
return this.windows || this.playstation ? this.interval = this.interval ? this.interval : c.setInterval(function() {
a.online = a.isOnline(), a.online && a.reload(0);
}, 2e3) : this.onlinecbreload = !0, this;
}, a.prototype.onlinecb = function() {
this.online = !0, this.onlinecbreload && this.reload(0);
}, a.prototype.offlinecb = function() {
this.online = !1;
}, a.prototype.onBufferChange = function(a) {
try {
var b = a.target.duration, d = a.target.buffered, e = a.target.currentTime, f = 0, g = d.length;
if (this.lastBufferProgress = this.bufferProgress, b > 0 && g > 0) {
for (;f < g; f++) if (d.start(g - 1 - f) < e) {
this.bufferProgress = c.Math.round(d.end(g - 1 - f) / b * 100);
break;
}
} else this.bufferProgress = void 0;
this.isBufferValid() && this.dispatchEvent("bufferChange", {
bufferProgress: this.bufferProgress
});
} catch (a) {}
}, a.prototype.onDurationChange = function(a) {
var b = a.target.duration ? 1e3 * a.target.duration : 0, c = a.target.currentTime ? 1e3 * a.target.currentTime : 0, d = c / b * 100;
this.setTimeValues(d, b - c, c);
}, a.prototype.setTimeValues = function(a, b, c) {
this.progress = a, this.remainingTime = b, this.position = c, this.position > 0 && this.dispatchEvent("durationChange", {
progress: this.progress,
remainingTime: this.remainingTime,
position: this.position,
duration: this.audioElement.duration
});
}, a.prototype.setPosition = function(a) {
try {
this.audioElement.currentTime = Number(a) / 1e3;
} catch (a) {}
return this;
}, a.prototype.reload = function(a, b) {
var d = this;
this.position > 1e3 && (this.lastPosition = this.position), this.errorTimeout = this.errorTimeout ? this.errorTimeout : c.setTimeout(function() {
d.online && !d.audioTrackPlaying && d.error ? d.audioElement.readyState >= 2 && 2 === d.audioElement.networkState ? (d.isReloading = !0,
d.clearWaiters().play(!0)) : d.load(d.currentSrc, !0) : (d.error = !1, d.isReloading = !1,
d.clearWaiters());
}, a);
}, a.prototype.setVolume = function(a) {
return this.audioElement.volume = a, this.dispatchEvent("volumeChange", {
volume: this.audioElement.volume
}), this;
}, a.prototype.getVolume = function() {
return this.audioElement.volume;
}, a.prototype.loadAudio = function() {
return this.options.video && this.isUsingHLSPolyfill ? (this.createNewHlsContext(),
this.hls.loadSource(this.currentSrc)) : this.audioElement.load(), this;
}, a.prototype.load = function(a, b) {
return this.dispatchEvent("wait", {
status: this.audioTrackPlaying
}).flush(!0), b && this.loadAudio(), this.setSrc(a || this.emptyWaveFileBase64),
this.isUsingHLSPolyfill || this.setAttribute("src", this.currentSrc), this.loadAudio(),
this;
}, a.prototype.play = function() {
var a = this;
if (this.isPaused = !1, this.playstation || this.isReloading || this.options.video) this.audioElement.play(); else {
this.audioElement.currentTime > 0 && !this.audioElement.paused && !this.audioElement.ended && this.audioElement.readyState >= 2 || (this.playPromise = this.audioElement.play(),
this.playPromise && this.playPromise.then(function(b) {
a.audioElement.play();
}).catch(function(a) {}));
}
return this;
}, a.prototype.pause = function() {
var a = this;
return this.audioTrackPlaying && (this.playstation || this.options.video ? this.audioElement.pause() : this.playPromise && this.playPromise.then(function(b) {
a.isPaused = !0, a.audioElement.pause();
}).catch(function(b) {
a.isPaused = !1;
})), this;
}, a.prototype.stop = function(a) {
return this.pause().flush(!0).dispatchEvent("durationChange", {
progress: 0,
remainingTime: 0,
position: 0
}), this.lastPosition = void 0, a && a(), this;
}, a.prototype.next = function(a, b) {
return this[a] = this[a] === this.list.length - 1 ? 0 : ++this[a], this.currentMediaItem = this.list[this[a]],
b && b({
track: this.currentMediaItem
}), this;
}, a.prototype.previous = function(a, b) {
return this[a] = this[a] <= 0 ? this.list.length - 1 : --this[a], this.currentMediaItem = this.list[this[a]],
b && b({
track: this.currentMediaItem
}), this;
}, a.prototype.repeat = function(a) {
return !this.isRepeating && this.toggle("repeat"), this.currentMediaItem = this.list[this.currentIndex],
a && a({
track: this.currentMediaItem
}), this.dispatchEvent("repeatStatusChange", {
repeat: this.isRepeating,
track: this.currentMediaItem
}), this;
}, a.prototype.createShuffleList = function(a) {
for (var b, c, d = a.length; 0 !== d; ) c = Math.floor(Math.random() * d), d -= 1,
b = a[d], a[d] = a[c], a[c] = b;
return a;
}, a.prototype.shuffle = function(a) {
return !this.isShuffling && this.toggle("shuffle"), this.shuffleList = 0 === this.shuffleIndex ? this.createShuffleList(this.list) : this.shuffleList,
a && (this.currentMediaItem = this.shuffleList[this.shuffleIndex], a({
track: this.currentMediaItem,
list: this.shuffleList
})), this.dispatchEvent("shuffleStatusChange", {
shuffle: this.isShuffling,
track: this.currentMediaItem
}), this;
}, a.prototype.addToPlaylist = function(a, b, c) {
var d;
return "string" == typeof arguments[1] ? a.constructor === Array ? this[b] = d = a.length > 0 ? a : this[b] : (this[b].push(a),
d = this[b]) : a.constructor === Array ? this.list = this.shuffleList = d = a.length > 0 ? a : this.list : (this.list.push(a),
this.shuffleList = d = this.list), c && c({
list: d
}), this.dispatchEvent("playlistChange", {
playlist: this.list,
shuffleList: this.shuffleList
}), this;
}, a.prototype.clearPlaylist = function() {
return this.list = this.shuffleList = [], this;
}, a.prototype.setNextPlayingListItem = function(a) {
return a.constructor === Array ? this.playNextList = this.playNextList.concat(a) : this.playNextList.push(a),
this;
}, a.prototype.getNextPlayingListItem = function() {
return this.playNextList[this.playNextList.length - 1];
}, a.prototype.removeNextPlayingListItem = function() {
return this.playNextList.splice(this.playNextList.length - 1, 1), this;
}, a.prototype.hasNextPlayingListItem = function() {
return this.playNextList.length > 0;
}, a.prototype.applyNextAction = function(a) {
var b = this;
if (this.hasNextPlayingListItem()) {
var c = function(c) {
b.removeNextPlayingListItem(), b.currentMediaItem = c, a({
track: b.currentMediaItem
});
}, d = this.getNextPlayingListItem();
this.isShuffling ? this.shuffleList.forEach(function(a) {
a.id == d.id && c(a);
}) : c(d);
} else this.isRepeating ? this.repeat(a) : this.isShuffling ? this.shuffle().next("shuffleIndex", a) : this.next("currentIndex", a);
return this;
}, a.prototype.applyPreviousAction = function(a) {
return this.isRepeating && this.toggle("repeat", !1), this.isShuffling ? this.shuffle().previous("shuffleIndex", a) : this.previous("currentIndex", a),
this;
}, a.prototype.toggle = function(a, b) {
var c = "shuffle" === a ? "isShuffling" : "repeat" === a ? "isRepeating" : "", d = "shuffle" === a ? "isRepeating" : "repeat" === a ? "isShuffling" : "";
return this[c] = void 0 !== b ? b : !this[c], void 0 === b && (this[d] = !1), "shuffle" === c && (this.shuffleIndex = 0),
this;
}, a.prototype.flush = function(a) {
return a && (this.isReloading = !0, this.clearWaiters()), this.options.video && this.isUsingHLSPolyfill && this.hls && this.destoryHLS(),
this.bufferProgress = this.lastBufferProgress = this.progress = this.position = this.remainingTime = this.duration = 0,
this.error = this.metadata = this.playState = void 0, this.currentMediaItem = {},
this.isUsingHLSPolyfill || this.setAttribute("src", this.emptyWaveFileBase64), this.setPosition(0),
this;
}, a.prototype.clearWaiters = function() {
return c.clearTimeout(this.errorTimeout), this.errorTimeout = void 0, this.windows || this.playstation ? (c.clearInterval(this.interval),
this.interval = void 0) : this.onlinecbreload = !1, this;
}, a.prototype.setOptions = function(a) {
if (a) {
var b = void 0;
for (b in a) this.options[b] = a[b];
}
return this;
}, a.prototype.createMedia = function() {
return this.options.html5 ? this.audioElement = new Audio() : (this.audioElement = this.createElement(),
this.options.video && (this.audioElement.style.width = "100%", this.audioElement.style.height = "100%",
this.audioElement.style.display = "block", this.audioElement.style.position = "absolute",
this.audioElement.style.top = "0", this.audioElement.style.left = "0", this.audioElement.style.right = "0",
this.audioElement.style.bottom = "0"), this.audioElement.type = this.options.video ? "application/vnd.apple.mpegurl" : 'audio/mp4; codecs="mp4a.40.2"'),
this;
}, a.prototype.createNewHlsContext = function() {
this.hls = new c.Hls({
autoStartLoad: !0,
startPosition: -1,
capLevelToPlayerSize: !0,
debug: !1,
defaultAudioCodec: void 0,
initialLiveManifestSize: 1,
maxBufferLength: 30,
maxMaxBufferLength: 600,
maxBufferSize: 6e7,
maxBufferHole: .5,
lowBufferWatchdogPeriod: .5,
highBufferWatchdogPeriod: 3,
nudgeOffset: .1,
nudgeMaxRetry: 5,
maxFragLookUpTolerance: .2,
liveSyncDurationCount: 3,
liveMaxLatencyDurationCount: 10,
enableWorker: !0,
enableSoftwareAES: !0,
manifestLoadingTimeOut: 15e3,
manifestLoadingMaxRetry: 4,
manifestLoadingRetryDelay: 500,
manifestLoadingMaxRetryTimeout: 64e3,
startLevel: void 0,
levelLoadingTimeOut: 1e4,
levelLoadingMaxRetry: 4,
levelLoadingRetryDelay: 500,
levelLoadingMaxRetryTimeout: 64e3,
fragLoadingTimeOut: 2e4,
fragLoadingMaxRetry: 6,
fragLoadingRetryDelay: 500,
fragLoadingMaxRetryTimeout: 64e3,
startFragPrefetch: !1,
appendErrorMaxRetry: 3,
enableWebVTT: !0,
enableCEA708Captions: !0,
stretchShortVideoTrack: !0,
maxAudioFramesDrift: 1,
forceKeyFrameOnDiscontinuity: !0,
abrEwmaFastLive: 5,
abrEwmaSlowLive: 9,
abrEwmaFastVoD: 4,
abrEwmaSlowVoD: 15,
abrEwmaDefaultEstimate: 5e5,
abrBandWidthFactor: .95,
abrBandWidthUpFactor: .7,
minAutoBitrate: 0
}), this.hls.attachMedia(this.audioElement), this.appendHLSEvents();
}, a.prototype.createElement = function() {
var a;
try {
if (this.options.video) {
var b = d.getElementById(f);
a = b.appendChild(d.createElement(f)), b = null, this.device.browser && (this.isUsingHLSPolyfill = !0);
} else a = d.body.appendChild(d.createElement(e));
} catch (a) {} finally {
return a;
}
}, a.prototype.addEventListeners = function(a, b) {
var c;
if (a) {
for (c in b) a.addEventListener(c, b[c], !1);
this.options.video && this.isUsingHLSPolyfill && (this.hlsjsErrorHandler = this.hlsPolyfillVideoTagErrorHandlerFactory(),
this.hlsVideoTagErrorHandler = this.hlsPolyfillVideoTagErrorHandlerFactory());
}
return this;
}, a.prototype.isValid = function() {
return !!this.forceDurationChangeForAudioAd || null !== this.currentSrc.match(this.mimeRegx);
}, a.prototype.isBufferValid = function() {
return this.bufferProgress > 0 && this.bufferProgress !== this.lastBufferProgress;
}, a.prototype.hasBuffer = function() {
return !this.playstation && 100 !== this.bufferProgress;
}, a.prototype.setSrc = function(a) {
return this.currentSrc = a, this;
}, a.prototype.setAttribute = function(a, b) {
try {
this.audioElement[a] = b;
} catch (a) {}
return this;
}, a.prototype.on = function(a, b) {
this.eventMap[a] || (this.eventMap[a] = []), this.eventMap[a].push(b);
}, a.prototype.off = function(a, b) {
this.eventMap[a] = b;
}, a.prototype.dispatchEvent = function(a, b) {
var c = this.eventMap[a];
return c ? (c.forEach(function(a) {
"function" == typeof a && a(b);
}), this) : this;
}, a.prototype.destroy = function() {
var a;
for (a in this.audioElementEvents) this.audioElement.removeEventListener(a, this.audioElementEvents[a], !1);
for (a in this.eventMap) delete this.eventMap[a];
return delete this.eventMap, this.eventMap = {}, this.options.html5 || this.audioElement.parentNode.removeChild(this.audioElement),
this.options.video && this.isUsingHLSPolyfill && (this.destoryHLS(), this.options = {},
this.isUsingHLSPolyfill = void 0, delete this.hlsjsErrorHandler, delete this.hlsVideoTagErrorHandler,
delete this.hls), this.audioElement = void 0, this;
}, a.prototype.destoryHLS = function() {
this.hls.destroy(), this.hls.detachMedia();
}, a.prototype.hlsPolyfillVideoTagErrorHandlerFactory = function() {
var a = this, b = null, c = null;
return function() {
var d = Date.now();
!b || d - b > 2e3 ? (b = d, a.hls.recoverMediaError()) : !c || d - c > 2e3 ? (c = d,
a.hls.swapAudioCodec(), a.hls.recoverMediaError()) : a.destoryHLS();
};
}, a.prototype.checkError = function(a) {
this.audioTrackPlaying = void 0, this.isValid() && (this.catchErrorVulnerability(a),
this.dispatchEvent("wait", {
status: this.audioTrackPlaying
}));
}, a.prototype.catchErrorVulnerability = function(a) {
var b = this;
if (100 !== this.bufferProgress) {
var c = a.target.readyState, d = a.target.networkState, e = c >= 2 && this.metadata, f = 2 === d, g = a.target.error, h = g && g.code ? g.code : void 0, i = function(a) {
b.error = !0, b.waitUntilOnline();
}, j = function(a) {
b.error = !0, b.reload(a);
};
if (this.online = this.windows || this.playstation ? this.isOnline() : this.online,
this.online) {
if (g && 4 === h) return void this.dispatchEvent("error", {
progress: this.progress
});
g && h > 1 || this.bufferProgress > 0 && !f && !e || this.playstation && this.playState ? j(this.options.reloadOnError) : (0 === this.bufferProgress || this.playstation && !this.playState) && (f && !e ? j(this.options.reloadOnInit + 1e4) : (!f && !e || e && !f) && j(this.options.reloadOnInit));
} else i(1e3);
}
}, a;
}(), i = new h();
"object" == typeof module && module && "object" == typeof module.exports ? module.exports = i : "function" == typeof define && define.amd ? define(function() {
return {
constructor: i,
instance: i
};
}) : c.Galactic = i, b.true = a;
}({}, function() {
return this;
}());
//# sourceMappingURL=AudioManager.min.js.map
</script>
<!-- <script src="/AudioManager.js"></script> -->
<style type="text/css">
* {
box-sizing: border-box;
}
html, body {
height: 100%;
width: 100%;
}
body {
background-color: #e2e2e2;
margin: 0;
}
audio, .playerController {
position: absolute;
}
audio {
right: 0;
width: 95%;
bottom: 25%;
left: 0;
margin: auto
}
.button {
border: 0;
background-color: #92278f;
color: white;
font-size: 1.1em;
padding: 2%;
margin: 2%
}
.previous, .next {
width: 10%;
}
.shuffle, .play, .repeat {
width: 20%;
}
.playerController, .controllers {
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex;
width: 100%;
}
.playerController {
bottom: 3%;
}
.playerController {
flex-direction: column;
}
.timing {
color: black;
}
.progress, .timing {
margin: 0 2%;
width: 96%;
}
.timing .position {
float: left;
}
.timing .remaining {
float: right;
}
.controllers {
flex-direction: row;
}
fieldset {
height: 300px;
width: 90%;
overflow: scroll;
position: relative;
}
fieldset div {
display: inline-block;
/* text-align: end; */
position: absolute;
left: 0;
right: 0;
margin: auto;
}
</style>
</head>
<body>
<fieldset id="console-log-div"></fieldset>
<script src="https://rawgit.com/bahmutov/console-log-div/master/console-log-div.js"></script>
<div class='playerController'>
<div class='controllers'>
<button class='button previous' onclick="previous(event)"><<</button>
<button class='button play' onclick="play()">Play</button>
<button class='button shuffle' onclick="shuffle(event)">Shuffle</button>
<button class='button repeat' onclick="repeat(event)">Repeat</button>
<button class='button next' onclick="next(event)">>></button>
</div>
<progress class='progress' value="0" max="100"></progress>
<div class='timing'>
<span class='position'>00:00</span>
<span class='remaining'>00:00</span>
</div>
</div>
<script type="text/javascript">
var createCookie = function (name, value, days) {
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
} else var expires = "";
document.cookie = name + "=" + value + expires + "; path=/;domain=.anghami.com";
document.cookie = name + "=" + value + expires + "; path=/;domain=.angha.me";
};
createCookie('sss', 'ns6799343_f0fd10ec6776a35593e6c18a019aecb8', 90);
createCookie('fingerprint', '646f1722d51c73446fd3ed2b0f1b8d8c', 90);
var rc4 = function (key, str) {
var s = [], j = 0, x, res = '';
for (var i = 0; i < 256; i++) {
s[i] = i;
}
for (i = 0; i < 256; i++) {
j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
x = s[i];
s[i] = s[j];
s[j] = x;
}
i = 0;
j = 0;
for (var y = 0; y < str.length; y++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
x = s[i];
s[i] = s[j];
s[j] = x;
res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
}
return res;
};
var songs = [
{"id":"1501607","title":"Behind The Wall Of Sleep","album":"Black Sabbath","albumID":"164841","artist":"Black Sabbath","artistID":"1592","track":"3","year":"2009","duration":"215.75","coverArt":"210521","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"210521","bitrate":64,"size":"1761556","releasedate":"2009-07-14","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"200","details":"200 plays","swapnames":1,"likes":"0"
},
{"id":"1501611","title":"Warning","album":"Black Sabbath","albumID":"164841","artist":"Black Sabbath","artistID":"1592","track":"7","year":"2009","duration":"630.23","coverArt":"210521","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"210521","bitrate":64,"size":"5134953","releasedate":"2009-07-14","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"199","details":"199 plays","swapnames":1,"likes":"0"},
{"id":"4165712","title":"Embryo - Demo","album":"Master Of Reality (Deluxe Edition)","albumID":"434636","artist":"Black Sabbath","artistID":"1592","track":"3","year":"2013","duration":"28.00","coverArt":"2639307","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"2639307","bitrate":64,"size":"237169","releasedate":"2013-07-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"194","details":"194 plays","swapnames":1,"likes":"0"},{"id":"1463136","title":"Gypsy","album":"Technical Ecstasy","albumID":"160482","artist":"Black Sabbath","artistID":"1592","track":"4","year":"","duration":"308.31","coverArt":"203608","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"203608","bitrate":64,"size":"2514832","releasedate":"1976-01-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"194","details":"194 plays","swapnames":1,"likes":"0"},{"id":"1463187","title":"The Thrill Of It All","album":"Sabotage","albumID":"159993","artist":"Black Sabbath","artistID":"1592","track":"5","year":"2009","duration":"355.86","coverArt":"203612","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"203612","bitrate":64,"size":"2901893","releasedate":"2009-09-21","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"193","details":"193 plays","swapnames":1,"likes":"0"},{"id":"1477161","title":"The Shining","album":"The Eternal Idol","albumID":"167632","artist":"Black Sabbath","artistID":"1592","track":"1","year":"2010","duration":"358.23","coverArt":"208324","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"208324","bitrate":64,"size":"2921167","releasedate":"2010-01-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"191","details":"191 plays","swapnames":1,"likes":"0"},{"id":"6956794","title":"Cel i infern","album":"Kcor d rock","albumID":"712821","artist":"Black Sabbath & LUPE VILLAR & XII.AMC","artistID":"548245","track":"12","year":"2008","duration":"283.00","coverArt":"1064433","ArtistArt":1001064433,"allowoffline":1,"genre":"Rock","AlbumArt":"1064433","bitrate":64,"size":"2314732","releasedate":"2008-03-31","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"190","details":"190 plays","swapnames":1,"likes":"0"},{"id":"1045242","title":"After All (The Dead) (2011 - Remaster)","album":"Dehumanizer","albumID":"88049","artist":"Black Sabbath","artistID":"1592","track":"2","year":"2011","duration":"339.80","coverArt":"151757","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"151757","bitrate":64,"size":"2771103","releasedate":"2011-02-04","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"190","details":"190 plays","swapnames":1,"likes":"0"},{"id":"1463276","title":"Spiral Architect","album":"Sabbath Bloody Sabbath","albumID":"159991","artist":"Black Sabbath","artistID":"1592","track":"8","year":"2011","duration":"329.67","coverArt":"203619","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"203619","bitrate":64,"size":"2688708","releasedate":"2011-01-31","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"189","details":"189 plays","swapnames":1,"likes":"0"},{"id":"1472213","title":"Voodoo","album":"Mob Rules","albumID":"166576","artist":"Black Sabbath","artistID":"1592","track":"2","year":"2010","duration":"272.60","coverArt":"207653","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"207653","bitrate":64,"size":"2224183","releasedate":"2010-01-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"189","details":"189 plays","swapnames":1,"likes":"0"},{"id":"1360900","title":"Zero The Hero","album":"Born Again","albumID":"148257","artist":"Black Sabbath","artistID":"1592","track":"5","year":"2011","duration":"455.71","coverArt":"189411","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"189411","bitrate":64,"size":"3714527","releasedate":"2011-01-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"189","details":"189 plays","swapnames":1,"likes":"0"},{"id":"4165714","title":"Orchid - Demo","album":"Master Of Reality (Deluxe Edition)","albumID":"434636","artist":"Black Sabbath","artistID":"1592","track":"5","year":"2013","duration":"91.00","coverArt":"2639307","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"2639307","bitrate":64,"size":"748179","releasedate":"2013-07-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"188","details":"188 plays","swapnames":1,"likes":"0"},{"id":"1469434","title":"Rat Salad - Instrumental","album":"Paranoid","albumID":"159585","artist":"Black Sabbath","artistID":"1592","track":"7","year":"2010","duration":"149.53","coverArt":"204242","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"204242","bitrate":64,"size":"1222548","releasedate":"2010-02-22","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"188","details":"188 plays","swapnames":1,"likes":"0"},{"id":"4165713","title":"Children Of The Grave - Demo","album":"Master Of Reality (Deluxe Edition)","albumID":"434636","artist":"Black Sabbath","artistID":"1592","track":"4","year":"2013","duration":"316.00","coverArt":"2639307","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"2639307","bitrate":64,"size":"2582874","releasedate":"2013-07-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"188","details":"188 plays","swapnames":1,"likes":"0"},{"id":"4165717","title":"Into The Void - Demo","album":"Master Of Reality (Deluxe Edition)","albumID":"434636","artist":"Black Sabbath","artistID":"1592","track":"8","year":"2013","duration":"371.00","coverArt":"2639307","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"2639307","bitrate":64,"size":"3027753","releasedate":"2013-07-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"186","details":"186 plays","swapnames":1,"likes":"0"},{"id":"1501615","title":"Planet Caravan","album":"Paranoid","albumID":"166903","artist":"Black Sabbath","artistID":"1592","track":"3","year":"2009","duration":"270.74","coverArt":"210522","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"210522","bitrate":64,"size":"2209058","releasedate":"2009-07-14","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"184","details":"184 plays","swapnames":1,"likes":"0"},{"id":"1045249","title":"I (2011 - Remaster)","album":"Dehumanizer","albumID":"88049","artist":"Black Sabbath","artistID":"1592","track":"9","year":"2011","duration":"311.14","coverArt":"151757","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"151757","bitrate":64,"size":"2537908","releasedate":"2011-02-04","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"181","details":"181 plays","swapnames":1,"likes":"0"},{"id":"12469011","title":"Hand of Doom","album":"Paranoid","albumID":"1293378","artist":"Black Sabbath","artistID":"1592","track":"6","year":"","duration":"429.00","coverArt":"1655884","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"1655884","bitrate":64,"size":"3490988","releasedate":"1970-01-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"179","details":"179 plays","swapnames":1,"likes":"0"},{"id":"1472251","title":"Die Young - Live","album":"Heaven & Hell","albumID":"165781","artist":"Black Sabbath","artistID":"1592","track":"15","year":"2010","duration":"277.15","coverArt":"207654","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"207654","bitrate":64,"size":"2261224","releasedate":"2010-01-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"177","details":"177 plays","swapnames":1,"likes":"0"},{"id":"1353329","title":"In Memory","album":"Seventh Star","albumID":"151341","artist":"Black Sabbath","artistID":"1592","track":"9","year":"2010","duration":"156.17","coverArt":"188552","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"188552","bitrate":64,"size":"1276610","releasedate":"2010-11-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"176","details":"176 plays","swapnames":1,"likes":"0"}];
var swa;
var progressElement = document.getElementsByClassName('progress')[0];
var position = document.getElementsByClassName('position')[0];
var remaining = document.getElementsByClassName('remaining')[0];
var shuffleBtn = document.getElementsByClassName('shuffle')[0];
var repeatBtn = document.getElementsByClassName('repeat')[0];
var humanTime = function (input) {
function pad(d) {
return (d < 10) ? '0' + d.toString() : d.toString();
}
var min = (input / 1000 / 60) << 0;
var sec = Math.round((input / 1000) % 60);
if (sec == 60) {
min += 1;
sec = 0;
}
return pad(min) + ':' + pad(sec);
};
var fetch = function(song) {
return new Promise(function(resolve, reject) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if (this.responseText[0] !== '+') {
var decoded = window.atob(this.responseText);
var key = '34%i7ateMyImcreept24fjf#ang.646f1722d51c73446fd3ed2b0f1b8d8c';
var rc4Value = rc4(key, decoded);
var trackUrl = JSON.parse(rc4Value).location;
console.log(trackUrl);
resolve(trackUrl);
} else {
reject(false);
}
}
};
xhttp.open("GET", "https://api.anghami.com/gateway.php?angh_type=GETdownload&encrypt=true&fileid=" + song.id + "&fingerprint=646f1722d51c73446fd3ed2b0f1b8d8c&lang=en&language=en&method=GET&nocache=true&noloader=true&type=GETdownload", true);
xhttp.send();
});
};
var fetchplay = function (song) {
var track = song ? song : swa.list[0];
var loadedEmpty = swa.loadEmpty(); //for mobile only
fetch(track).then(function (url) {
console.log(url);
setTimeout(function() {
swa.load(url);
}, 0);
// .fadeOut(3000, function () {
// console.log('fading out');
// })
// .fadeIn(3000, function () {
// console.log('fading in');
// });
//.play();
//'https://anghamiaudio.akamaized.net/mp43/UMG_00602557991529_T1_audtrk.m4a?anghakamitoken=st=1505391418~exp=1505391898~acl=*~hmac=a35fc74de20924e5971721789cec6cc7966a95d83358da4543a6ad85105cc187'
});
};
// //this.setNextPlayingListItem([{"id":"1501615","title":"Planet Caravan","album":"Paranoid","albumID":"166903","artist":"Black Sabbath","artistID":"1592","track":"3","year":"2009","duration":"270.74","coverArt":"210522","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"210522","bitrate":64,"size":"2209058","releasedate":"2009-07-14","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"184","details":"184 plays","swapnames":1,"likes":"0"}, {"id":"1477161","title":"The Shining","album":"The Eternal Idol","albumID":"167632","artist":"Black Sabbath","artistID":"1592","track":"1","year":"2010","duration":"358.23","coverArt":"208324","ArtistArt":1002639307,"allowoffline":1,"genre":"Heavy Metal","AlbumArt":"208324","bitrate":64,"size":"2921167","releasedate":"2010-01-01","explicit":"0","extras":"eyJyZXF1ZXN0dHlwZWlkIjo3NCwicmVxdWVzdHR5cGUiOiJHRVRhcnRpc3Rwcm9maWxlIiwicmVxdWVzdG9uZGVtYW5kIjoxLCJzZWN0aW9uIjoidG9wc29uZ3MifQ==","plays":"191","details":"191 plays","swapnames":1,"likes":"0"}]);
function nextAction(e) {
swa.applyNextAction(function (data) {
console.log(data.track);
console.log(swa.currentIndex);
fetchplay(data.track);
});
}
function previousAction(e) {
swa.applyPreviousAction(function (data) {
console.log(data.track);
console.log(swa.currentIndex);
fetchplay(data.track);
});
}
var init = function () {
swa = Galactic.init(
{
html5: false,
reloadOnInit: 10000,
reloadOnError: 5000
});
swa.audioElement.controls = true;
swa.list = songs;
swa.on('end', nextAction);
swa.on('durationChange', function (data) {
console.log(data);
progressElement.value = data.progress;
position.innerHTML = humanTime(data.position);
remaining.innerHTML = humanTime(data.remainingTime);
});
swa.on('play', function () {
console.log('swa on play.........');
});
swa.on('whilePlaying', function () {
console.log('swa on whilePlaying.........');
});
swa.on('pause', function () {
console.log('swa on pause.........');
});
swa.on('bufferChange', function (data) {
console.log('swa on bufferChange: ', data.bufferProgress + ' %');
});
swa.on('load', function () {
console.log('swa on waiting.........');
});
swa.on('error', function () {
console.log('ERRRRRRrrrrrrrrrrrrrrrrrrrrrrrr.........');
});
};
var changeButtonsValues = function () {
shuffleBtn = document.getElementsByClassName('shuffle')[0];
repeatBtn = document.getElementsByClassName('repeat')[0];
repeatBtn.innerHTML = swa.isRepeating ? 'Repeating...' : 'Repeat';
shuffleBtn.innerHTML = swa.isShuffling ? 'Shuffling...' : 'Shuffle';
};
var play = function () {
fetchplay();
};
var shuffle = function (e) {
swa.toggle('shuffle');
changeButtonsValues();
console.log(swa);
};
var repeat = function (e) {
swa.toggle('repeat');
changeButtonsValues();
console.log(swa);
};
var next = function () {
swa.isRepeating && swa.toggle('repeat', false);
nextAction();
!swa.isRepeating && (repeatBtn.innerHTML = 'Repeat');
};
var previous = function () {
//handled by default in the player class since the default actions always moves forward so that's wwhy it's handled there
//swa.isRepeating && swa.toggle('repeat', false);
previousAction();
!swa.isRepeating && (repeatBtn.innerHTML = 'Repeat');
};
init();
</script>
</body>
</html>