diff --git a/About/README.md b/About/README.md
new file mode 100644
index 0000000..ab1360e
--- /dev/null
+++ b/About/README.md
@@ -0,0 +1,24 @@
+# About
+This is an example project, generated by AntOS Development Kit
+
+## Howto
+
+1. Open the project.apj file with AntOSDK (simply double Click on it)
+2. Modify the UI in *assets/scheme.html*
+3. Modify application code in *coffees/main.coffee*
+4. Modify CSS style in *css/main.css*
+5. Other files need to be copied: put in to assets
+
+## Set up build target
+
+Click **Menu> Build > Build Option** or simply hit **ALT-Y**
+
+In the build options dialog, add or remove files that need to be
+included into the build
+
+Click **Save**
+
+## Build application
+* To build: **Menu > Build > Build** or **ALT-C**
+* To build and run: **Menu > Build > Build and Run** or **CTRL-R**
+* To release: **Menu > Build > Build release** or **ALT-P**
\ No newline at end of file
diff --git a/About/assets/scheme.html b/About/assets/scheme.html
new file mode 100644
index 0000000..d057480
--- /dev/null
+++ b/About/assets/scheme.html
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/About/build/debug/README.md b/About/build/debug/README.md
new file mode 100644
index 0000000..ab1360e
--- /dev/null
+++ b/About/build/debug/README.md
@@ -0,0 +1,24 @@
+# About
+This is an example project, generated by AntOS Development Kit
+
+## Howto
+
+1. Open the project.apj file with AntOSDK (simply double Click on it)
+2. Modify the UI in *assets/scheme.html*
+3. Modify application code in *coffees/main.coffee*
+4. Modify CSS style in *css/main.css*
+5. Other files need to be copied: put in to assets
+
+## Set up build target
+
+Click **Menu> Build > Build Option** or simply hit **ALT-Y**
+
+In the build options dialog, add or remove files that need to be
+included into the build
+
+Click **Save**
+
+## Build application
+* To build: **Menu > Build > Build** or **ALT-C**
+* To build and run: **Menu > Build > Build and Run** or **CTRL-R**
+* To release: **Menu > Build > Build release** or **ALT-P**
\ No newline at end of file
diff --git a/About/build/debug/main.js b/About/build/debug/main.js
new file mode 100644
index 0000000..e5e530c
--- /dev/null
+++ b/About/build/debug/main.js
@@ -0,0 +1,28 @@
+(function() {
+ var About;
+
+ About = class About extends this.OS.GUI.BaseApplication {
+ constructor(args) {
+ super("About", args);
+ }
+
+ main() {
+ var me;
+ me = this;
+ this.container = this.find("container");
+ return "os://README.md".asFileHandler().read(function(txt) {
+ var converter;
+ converter = new showdown.Converter();
+ return ($(me.container)).html(converter.makeHtml(txt));
+ });
+ }
+
+ };
+
+ About.singleton = true;
+
+ About.dependencies = ["showdown.min"];
+
+ this.OS.register("About", About);
+
+}).call(this);
diff --git a/About/build/debug/package.json b/About/build/debug/package.json
new file mode 100644
index 0000000..ad725d0
--- /dev/null
+++ b/About/build/debug/package.json
@@ -0,0 +1,13 @@
+{
+ "app":"About",
+ "name":"About",
+ "description":"AntOS about",
+ "info":{
+ "author": "Xuan Sang LE",
+ "email": "xsang.le@gmail.com"
+ },
+ "version":"0.0.1-a",
+ "category":"Other",
+ "iconclass":"fa fa-question-circle",
+ "mimes":["none"]
+}
\ No newline at end of file
diff --git a/About/build/debug/scheme.html b/About/build/debug/scheme.html
new file mode 100644
index 0000000..d057480
--- /dev/null
+++ b/About/build/debug/scheme.html
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/About/coffees/main.coffee b/About/coffees/main.coffee
new file mode 100644
index 0000000..5813eff
--- /dev/null
+++ b/About/coffees/main.coffee
@@ -0,0 +1,14 @@
+class About extends this.OS.GUI.BaseApplication
+ constructor: ( args ) ->
+ super "About", args
+
+ main: () ->
+ me = @
+ @container = @find "container"
+ "os://README.md".asFileHandler().read (txt) ->
+ converter = new showdown.Converter()
+ ($ me.container).html converter.makeHtml txt
+
+About.singleton = true
+About.dependencies = [ "showdown.min" ]
+this.OS.register "About", About
\ No newline at end of file
diff --git a/About/package.json b/About/package.json
new file mode 100644
index 0000000..ad725d0
--- /dev/null
+++ b/About/package.json
@@ -0,0 +1,13 @@
+{
+ "app":"About",
+ "name":"About",
+ "description":"AntOS about",
+ "info":{
+ "author": "Xuan Sang LE",
+ "email": "xsang.le@gmail.com"
+ },
+ "version":"0.0.1-a",
+ "category":"Other",
+ "iconclass":"fa fa-question-circle",
+ "mimes":["none"]
+}
\ No newline at end of file
diff --git a/About/project.apj b/About/project.apj
new file mode 100644
index 0000000..75a722f
--- /dev/null
+++ b/About/project.apj
@@ -0,0 +1,8 @@
+{
+ "name": "About",
+ "root": "home://workspace/About",
+ "css": [],
+ "javascripts": [],
+ "coffees": ["coffees/main.coffee"],
+ "copies": ["assets/scheme.html", "package.json", "README.md"]
+}
\ No newline at end of file
diff --git a/MediaPlayer/README.md b/MediaPlayer/README.md
new file mode 100644
index 0000000..79b66d0
--- /dev/null
+++ b/MediaPlayer/README.md
@@ -0,0 +1,24 @@
+# MediaPlayer
+This is an example project, generated by AntOS Development Kit
+
+## Howto
+
+1. Open the project.apj file with AntOSDK (simply double Click on it)
+2. Modify the UI in *assets/scheme.html*
+3. Modify application code in *coffees/main.coffee*
+4. Modify CSS style in *css/main.css*
+5. Other files need to be copied: put in to assets
+
+## Set up build target
+
+Click **Menu> Build > Build Option** or simply hit **ALT-Y**
+
+In the build options dialog, add or remove files that need to be
+included into the build
+
+Click **Save**
+
+## Build application
+* To build: **Menu > Build > Build** or **ALT-C**
+* To build and run: **Menu > Build > Build and Run** or **CTRL-R**
+* To release: **Menu > Build > Build release** or **ALT-P**
\ No newline at end of file
diff --git a/MediaPlayer/assets/scheme.html b/MediaPlayer/assets/scheme.html
new file mode 100644
index 0000000..51bed82
--- /dev/null
+++ b/MediaPlayer/assets/scheme.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MediaPlayer/build/debug/README.md b/MediaPlayer/build/debug/README.md
new file mode 100644
index 0000000..79b66d0
--- /dev/null
+++ b/MediaPlayer/build/debug/README.md
@@ -0,0 +1,24 @@
+# MediaPlayer
+This is an example project, generated by AntOS Development Kit
+
+## Howto
+
+1. Open the project.apj file with AntOSDK (simply double Click on it)
+2. Modify the UI in *assets/scheme.html*
+3. Modify application code in *coffees/main.coffee*
+4. Modify CSS style in *css/main.css*
+5. Other files need to be copied: put in to assets
+
+## Set up build target
+
+Click **Menu> Build > Build Option** or simply hit **ALT-Y**
+
+In the build options dialog, add or remove files that need to be
+included into the build
+
+Click **Save**
+
+## Build application
+* To build: **Menu > Build > Build** or **ALT-C**
+* To build and run: **Menu > Build > Build and Run** or **CTRL-R**
+* To release: **Menu > Build > Build release** or **ALT-P**
\ No newline at end of file
diff --git a/MediaPlayer/build/debug/main.css b/MediaPlayer/build/debug/main.css
new file mode 100644
index 0000000..04dee5e
--- /dev/null
+++ b/MediaPlayer/build/debug/main.css
@@ -0,0 +1,108 @@
+
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-button button{
+ border: 0;
+ font-size: 25px;
+ padding-top:9px;
+ background-color: transparent;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-pause"]{
+ padding-top:5px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-pause"] span::before{
+ content: "\f144";
+ font-size: 40px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-pause"] .swon::before{
+ content: "\f28b";
+}
+afx-app-window[data-id="MediaPlayer"] afx-label[data-id="play-time"] {
+ text-align: left;
+}
+afx-app-window[data-id="MediaPlayer"] afx-label[data-id="total-time"] {
+ text-align: right;
+}
+afx-app-window[data-id="MediaPlayer"] afx-label[data-id="song-name"] {
+ text-align: center;
+ display: inline;
+ overflow: hidden;
+}
+afx-app-window[data-id="MediaPlayer"] afx-slider .dragpoint {
+ width:12px;
+ height: 12px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-slider[data-id="vol-control"] .progress {
+ background-color: #a6a6a6;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-vol"] {
+ margin-top:10px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-vol"] span::before{
+ content: "\f026";
+ font-size: 19px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-vol"] .swon::before{
+ content: "\f028";
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-random"] span::before{
+ content: "\f074";
+ font-size: 16px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-random"] .swon::before{
+ content: "\f074";
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-random"] {
+ margin-top:10px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-list-view[data-id="playlist"] {
+ border:1px solid #a6a6a6;
+}
+afx-app-window[data-id="MediaPlayer"] afx-button.ctlbtn button:active{
+ background-color: transparent;
+ color:#2786F3;
+}
+afx-app-window[data-id="MediaPlayer"] .animation {
+ position: relative;
+}
+
+afx-app-window[data-id="MediaPlayer"] .animation span{
+ width:5px;
+ height: 5px;
+ bottom:18px;
+ position:absolute;
+ -webkit-animation: bodong 0.5s infinite ease;
+}
+
+afx-app-window[data-id="MediaPlayer"] .animation span:first-child{
+ left:10px;
+ -webkit-animation-delay:.3s;
+ background-color: red;
+}
+
+afx-app-window[data-id="MediaPlayer"] .animation span:nth-child(2){
+ left:17px;
+ -webkit-animation-delay:.4s;
+ background-color:orange ;
+}
+afx-app-window[data-id="MediaPlayer"] .animation span:nth-child(3){
+ left:24px;
+ -webkit-animation-delay:.6s;
+ background-color: #2786F3;
+}
+afx-app-window[data-id="MediaPlayer"] .animation span:nth-child(4){
+ left:31px;
+ -webkit-animation-delay:.8s;
+ background-color: chocolate;
+}
+afx-app-window[data-id="MediaPlayer"] .animation span:nth-child(5){
+ left:38px;
+ -webkit-animation-delay:1s;
+ background-color: blue;
+}
+
+@-webkit-keyframes bodong{
+ 0%{height:5px; background:bule;}
+ 30%{height:15px; background:bule;}
+ 60%{height:20px; background:bule;}
+ 80%{height:15px; background:bule;}
+ 100%{height:5px; background:bule;}
+}
diff --git a/MediaPlayer/build/debug/main.js b/MediaPlayer/build/debug/main.js
new file mode 100644
index 0000000..78483de
--- /dev/null
+++ b/MediaPlayer/build/debug/main.js
@@ -0,0 +1,444 @@
+(function() {
+ var MediaPlayer;
+
+ MediaPlayer = class MediaPlayer extends this.OS.GUI.BaseApplication {
+ constructor(args) {
+ super("MediaPlayer", args);
+ }
+
+ main() {
+ var me;
+ me = this;
+ this.volsw = this.find("play-vol");
+ this.volctl = this.find("vol-control");
+ this.volsw.set("swon", true);
+ this.volctl.set("onchange", function(v) {
+ if (!(me.volsw.get("swon"))) {
+ return;
+ }
+ return Howler.volume((me.volctl.get("value")) / 100);
+ });
+ this.volctl.set("value", 70);
+ this.playlist = this.find("playlist");
+ this.playtime = this.find("play-time");
+ this.songname = this.find("song-name");
+ this.totaltime = this.find("total-time");
+ this.playpause = this.find("play-pause");
+ this.progress = this.find("play-slide");
+ this.playran = this.find("play-random");
+ this.history = [];
+ this.currsong = void 0;
+ this.timer = void 0;
+ this.animator = this.find("animation");
+ this.volsw.set("onchange", function(e) {
+ if (!e.data) {
+ return Howler.volume(0);
+ }
+ return Howler.volume((me.volctl.get("value")) / 100);
+ });
+ this.playlist.set("buttons", [
+ {
+ text: "+",
+ onbtclick: function() {
+ return me.openDialog("FileDiaLog",
+ function(d,
+ n,
+ p,
+ f) {
+ if (f.type === "dir") {
+ return me.scanDir(f);
+ }
+ f.text = f.filename;
+ f.iconclass = "fa fa-music";
+ return me.playlist.push(f,
+ true);
+ },
+ "__(Select MP3 file or a folder)",
+ {
+ mimes: ["dir",
+ "audio/mpeg"]
+ });
+ }
+ },
+ {
+ text: "-",
+ onbtclick: function() {
+ var sel;
+ sel = me.playlist.get("selected");
+ if (!sel) {
+ return;
+ }
+ if (sel === me.currsong) {
+ me.stop();
+ }
+ return me.playlist.remove(sel,
+ true);
+ }
+ },
+ {
+ text: "",
+ onbtclick: function() {
+ return me.openDialog("PromptDialog",
+ function(link) {
+ var data;
+ if (!(link && link !== "")) {
+ return;
+ }
+ data = {
+ text: link,
+ path: link,
+ iconclass: "fa fa-link",
+ broadcast: true
+ };
+ return me.playlist.push(data,
+ true);
+ },
+ "__(MP3 Radio broadcast)",
+ {
+ label: "Enter radio broadcast link"
+ });
+ },
+ iconclass: "fa fa-link"
+ },
+ {
+ text: "",
+ iconclass: "fa fa-save",
+ onbtclick: function() {
+ var fp,
+ i,
+ len1,
+ playlist,
+ ref,
+ v;
+ playlist = [];
+ ref = me.playlist.get("items");
+ for (i = 0, len1 = ref.length; i < len1; i++) {
+ v = ref[i];
+ playlist.push({
+ text: v.text,
+ path: v.path,
+ iconclass: v.iconclass,
+ broadcast: v.broadcast ? v.broadcast : false
+ });
+ }
+ fp = "Untitled".asFileHandler();
+ return me.openDialog("FileDiaLog",
+ function(d,
+ n,
+ p,
+ f) {
+ fp = `${d}/${n}`.asFileHandler();
+ fp.cache = playlist;
+ return fp.write("object",
+ function(r) {
+ if (r.error) {
+ return me.error(__("Cannot save playlist: {0}",
+ r.error));
+ }
+ return me.notify(__("Playlist saved"));
+ });
+ },
+ "__(Save Playlist)",
+ {
+ file: fp
+ });
+ }
+ },
+ {
+ text: "",
+ iconclass: "fa fa-folder",
+ onbtclick: function() {
+ return me.openDialog("FileDiaLog",
+ function(d,
+ n,
+ p,
+ f) {
+ return f.path.asFileHandler().read(function(d) {
+ me.stop();
+ return me.playlist.set("items",
+ d);
+ },
+ "json");
+ },
+ "__(Open Playlist)",
+ {
+ mimes: ["application/json"]
+ });
+ }
+ }
+ ]);
+ this.playlist.set("onlistdbclick", function(e) {
+ if (!e) {
+ return;
+ }
+ e.data.index = e.idx;
+ return me.play(e.data);
+ });
+ this.progress.set("onchange", function(s) {
+ return me.seek(s);
+ });
+ this.playpause.set("onchange", function(e) {
+ return me.togglePlayPause();
+ });
+ (this.find("play-prev")).set("onbtclick", function() {
+ return me.prevSong();
+ });
+ (this.find("play-next")).set("onbtclick", function() {
+ return me.nextSong();
+ });
+ return $(this.animator).css("visibility", "hidden");
+ }
+
+ scanDir(f) {
+ var me;
+ me = this;
+ return f.path.asFileHandler().read(function(d) {
+ var i, len1, ref, results, v;
+ if (d.error) {
+ return me.error(__("Unable to read {0}", d.error));
+ }
+ ref = d.result;
+ results = [];
+ for (i = 0, len1 = ref.length; i < len1; i++) {
+ v = ref[i];
+ if (!(v.mime.match(/audio\/mpeg/))) {
+ continue;
+ }
+ v.iconclass = "fa fa-music";
+ v.text = v.filename;
+ results.push(me.playlist.push(v, true));
+ }
+ return results;
+ });
+ }
+
+ togglePlayPause() {
+ var sound;
+ if (!(this.currsong && this.currsong.howl)) {
+ return this.playpause.set("swon", false);
+ }
+ sound = this.currsong.howl;
+ if (sound.playing()) {
+ return sound.pause();
+ } else {
+ return sound.play();
+ }
+ }
+
+ nextSong() {
+ var idx, len, sel;
+ idx = -1;
+ if (this.playran.get("swon")) {
+ idx = this.randomSong();
+ } else {
+ len = (this.playlist.get("items")).length;
+ if (len > 0) {
+ idx = 0;
+ if (this.currsong) {
+ idx = this.currsong.index + 1;
+ }
+ if (idx >= len) {
+ idx = 0;
+ }
+ }
+ }
+ if (idx === -1) {
+ return;
+ }
+ if (history.length >= 10) {
+ this.history.pop();
+ }
+ if (this.currsong) {
+ this.history.unshift(this.currsong.index);
+ }
+ this.playlist.set("selected", idx);
+ sel = this.playlist.get("selected");
+ sel.index = idx;
+ return this.play(sel);
+ }
+
+ prevSong() {
+ var idx, len, sel;
+ idx = -1;
+ if (this.playran.get("swon")) {
+ if (this.history.length > 0) {
+ idx = this.history.shift();
+ }
+ } else {
+ len = (this.playlist.get("items")).length;
+ if (len > 0) {
+ if (this.currsong) {
+ idx = this.currsong.index - 1;
+ }
+ if (idx < 0) {
+ idx = 0;
+ }
+ }
+ }
+ if (idx === -1) {
+ return;
+ }
+ this.playlist.set("selected", idx);
+ sel = this.playlist.get("selected");
+ sel.index = idx;
+ return this.play(sel);
+ }
+
+ randomSong() {
+ var len;
+ len = (this.playlist.get("items")).length;
+ if (!(len > 0)) {
+ return -1;
+ }
+ return Math.floor(Math.random() * Math.floor(len));
+ }
+
+ play(file) {
+ var me, sound;
+ me = this;
+ this.stop();
+ this.currsong = file;
+ sound = file.howl;
+ if (!sound) {
+ sound = file.howl = new Howl({
+ src: [file.path.asFileHandler().getlink()],
+ preload: true,
+ buffer: true,
+ html5: true, // Force to HTML5 so that the audio can stream in (best for large files).
+ format: ['mp3', 'aac'],
+ onplay: function() {
+ var duration, func;
+ $(me.animator).css("visibility", "visible");
+ //Display the duration.
+ me.playpause.set("swon", true);
+ console.log("play");
+ me.songname.set("text", file.text);
+ duration = Math.round(sound.duration());
+ if (duration !== 2e308) {
+ me.totaltime.set("text", me.formatDuration(duration));
+ me.progress.set("max", duration);
+ } else {
+ me.totaltime.set("text", "--:--");
+ me.progress.set("max", 0);
+ }
+ if (!file.broadcast) {
+ func = function() {
+ var seek;
+ if (sound.playing()) {
+ seek = Math.round(sound.seek()) || 0;
+ me.progress.set("value", seek);
+ me.playtime.set("text", me.formatDuration(seek));
+ return me.timer = setTimeout((function() {
+ return func();
+ }), 1000);
+ }
+ };
+ return func();
+ } else {
+ me.totaltime.set("text", "--:--");
+ me.progress.set("value", me.progress.get("max"));
+ func = function() {
+ var seek;
+ if (sound.playing()) {
+ seek = Math.round(sound.seek()) || 0;
+ me.playtime.set("text", me.formatDuration(seek));
+ return me.timer = setTimeout((function() {
+ return func();
+ }), 1000);
+ }
+ };
+ return func();
+ }
+ },
+ onload: function() {
+ // Start the wave animation.
+ console.log("load");
+ $(me.animator).css("visibility", "hidden");
+ if (!file.broadcast) {
+ return sound.play();
+ }
+ },
+ onend: function() {
+ // Stop the wave animation.
+ me.progress.set("value", 0);
+ if (me.timer) {
+ clearTimeout(me.timer);
+ }
+ me.playpause.set("swon", false);
+ $(me.animator).css("visibility", "hidden");
+ return me.nextSong();
+ },
+ onpause: function() {
+ // Stop the wave animation.
+ console.log("pause");
+ if (me.timer) {
+ clearTimeout(me.timer);
+ }
+ me.playpause.set("swon", false);
+ return $(me.animator).css("visibility", "hidden");
+ },
+ onstop: function() {
+ me.progress.set("value", 0);
+ if (me.timer) {
+ clearTimeout(me.timer);
+ }
+ me.playpause.set("swon", false);
+ $(me.animator).css("visibility", "hidden");
+ return console.log("stop");
+ }
+ });
+ if (file.broadcast) {
+ sound.play();
+ }
+ } else {
+ sound.play();
+ }
+ return $(this.animator).css("visibility", "visible");
+ }
+
+ stop() {
+ if (this.currsong && this.currsong.howl) {
+ if (this.currsong.howl.playing()) {
+ return this.currsong.howl.stop();
+ }
+ }
+ }
+
+ seek(v) {
+ var sound;
+ if (!(this.currsong && this.currsong.howl && !this.currsong.broadcast)) {
+ return;
+ }
+ if (!((this.progress.get("max")) > 0)) {
+ return;
+ }
+ sound = this.currsong.howl;
+ return sound.seek(v);
+ }
+
+ formatDuration(s) {
+ var min, sec;
+ min = Math.floor(s / 60);
+ sec = s % 60;
+ min = min < 10 ? `0${min}` : `${min}`;
+ sec = sec < 10 ? `0${sec}` : `${sec}`;
+ return `${min}:${sec}`;
+ }
+
+ cleanup(evt) {
+ return this.stop();
+ }
+
+ };
+
+ // only one instance is allow
+ MediaPlayer.singleton = true;
+
+ this.OS.register("MediaPlayer", MediaPlayer);
+
+}).call(this);
+
+/*! howler.js v2.0.9 | (c) 2013-2018, James Simpson of GoldFire Studios | MIT License | howlerjs.com */
+!function(){"use strict";var e=function(){this.init()};e.prototype={init:function(){var e=this||n;return e._counter=1e3,e._codecs={},e._howls=[],e._muted=!1,e._volume=1,e._canPlayEvent="canplaythrough",e._navigator="undefined"!=typeof window&&window.navigator?window.navigator:null,e.masterGain=null,e.noAudio=!1,e.usingWebAudio=!0,e.autoSuspend=!0,e.ctx=null,e.mobileAutoEnable=!0,e._setup(),e},volume:function(e){var t=this||n;if(e=parseFloat(e),t.ctx||_(),void 0!==e&&e>=0&&e<=1){if(t._volume=e,t._muted)return t;t.usingWebAudio&&t.masterGain.gain.setValueAtTime(e,n.ctx.currentTime);for(var o=0;o=0;t--)e._howls[t].unload();return e.usingWebAudio&&e.ctx&&void 0!==e.ctx.close&&(e.ctx.close(),e.ctx=null,_()),e},codecs:function(e){return(this||n)._codecs[e.replace(/^x-/,"")]},_setup:function(){var e=this||n;if(e.state=e.ctx?e.ctx.state||"running":"running",e._autoSuspend(),!e.usingWebAudio)if("undefined"!=typeof Audio)try{var t=new Audio;void 0===t.oncanplaythrough&&(e._canPlayEvent="canplay")}catch(n){e.noAudio=!0}else e.noAudio=!0;try{var t=new Audio;t.muted&&(e.noAudio=!0)}catch(e){}return e.noAudio||e._setupCodecs(),e},_setupCodecs:function(){var e=this||n,t=null;try{t="undefined"!=typeof Audio?new Audio:null}catch(n){return e}if(!t||"function"!=typeof t.canPlayType)return e;var o=t.canPlayType("audio/mpeg;").replace(/^no$/,""),r=e._navigator&&e._navigator.userAgent.match(/OPR\/([0-6].)/g),a=r&&parseInt(r[0].split("/")[1],10)<33;return e._codecs={mp3:!(a||!o&&!t.canPlayType("audio/mp3;").replace(/^no$/,"")),mpeg:!!o,opus:!!t.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,""),ogg:!!t.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),oga:!!t.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),wav:!!t.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),aac:!!t.canPlayType("audio/aac;").replace(/^no$/,""),caf:!!t.canPlayType("audio/x-caf;").replace(/^no$/,""),m4a:!!(t.canPlayType("audio/x-m4a;")||t.canPlayType("audio/m4a;")||t.canPlayType("audio/aac;")).replace(/^no$/,""),mp4:!!(t.canPlayType("audio/x-mp4;")||t.canPlayType("audio/mp4;")||t.canPlayType("audio/aac;")).replace(/^no$/,""),weba:!!t.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,""),webm:!!t.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,""),dolby:!!t.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/,""),flac:!!(t.canPlayType("audio/x-flac;")||t.canPlayType("audio/flac;")).replace(/^no$/,"")},e},_enableMobileAudio:function(){var e=this||n,t=/iPhone|iPad|iPod|Android|BlackBerry|BB10|Silk|Mobi/i.test(e._navigator&&e._navigator.userAgent),o=!!("ontouchend"in window||e._navigator&&e._navigator.maxTouchPoints>0||e._navigator&&e._navigator.msMaxTouchPoints>0);if(!e._mobileEnabled&&e.ctx&&(t||o)){e._mobileEnabled=!1,e._mobileUnloaded||44100===e.ctx.sampleRate||(e._mobileUnloaded=!0,e.unload()),e._scratchBuffer=e.ctx.createBuffer(1,1,22050);var r=function(){n._autoResume();var t=e.ctx.createBufferSource();t.buffer=e._scratchBuffer,t.connect(e.ctx.destination),void 0===t.start?t.noteOn(0):t.start(0),"function"==typeof e.ctx.resume&&e.ctx.resume(),t.onended=function(){t.disconnect(0),e._mobileEnabled=!0,e.mobileAutoEnable=!1,document.removeEventListener("touchstart",r,!0),document.removeEventListener("touchend",r,!0)}};return document.addEventListener("touchstart",r,!0),document.addEventListener("touchend",r,!0),e}},_autoSuspend:function(){var e=this;if(e.autoSuspend&&e.ctx&&void 0!==e.ctx.suspend&&n.usingWebAudio){for(var t=0;t0?i._seek:o._sprite[e][0]/1e3),s=Math.max(0,(o._sprite[e][0]+o._sprite[e][1])/1e3-_),l=1e3*s/Math.abs(i._rate);i._paused=!1,i._ended=!1,i._sprite=e,i._seek=_,i._start=o._sprite[e][0]/1e3,i._stop=(o._sprite[e][0]+o._sprite[e][1])/1e3,i._loop=!(!i._loop&&!o._sprite[e][2]);var c=i._node;if(o._webAudio){var f=function(){o._refreshBuffer(i);var e=i._muted||o._muted?0:i._volume;c.gain.setValueAtTime(e,n.ctx.currentTime),i._playStart=n.ctx.currentTime,void 0===c.bufferSource.start?i._loop?c.bufferSource.noteGrainOn(0,_,86400):c.bufferSource.noteGrainOn(0,_,s):i._loop?c.bufferSource.start(0,_,86400):c.bufferSource.start(0,_,s),l!==1/0&&(o._endTimers[i._id]=setTimeout(o._ended.bind(o,i),l)),t||setTimeout(function(){o._emit("play",i._id)},0)};"running"===n.state?f():(o.once("resume",f),o._clearTimer(i._id))}else{var p=function(){c.currentTime=_,c.muted=i._muted||o._muted||n._muted||c.muted,c.volume=i._volume*n.volume(),c.playbackRate=i._rate;try{var r=c.play();if("undefined"!=typeof Promise&&r instanceof Promise){o._playLock=!0;var a=function(){o._playLock=!1,t||o._emit("play",i._id)};r.then(a,a)}else t||o._emit("play",i._id);if(c.paused)return void o._emit("playerror",i._id,"Playback was unable to start. This is most commonly an issue on mobile devices where playback was not within a user interaction.");"__default"!==e?o._endTimers[i._id]=setTimeout(o._ended.bind(o,i),l):(o._endTimers[i._id]=function(){o._ended(i),c.removeEventListener("ended",o._endTimers[i._id],!1)},c.addEventListener("ended",o._endTimers[i._id],!1))}catch(e){o._emit("playerror",i._id,e)}},m=window&&window.ejecta||!c.readyState&&n._navigator.isCocoonJS;if(c.readyState>=3||m)p();else{var v=function(){p(),c.removeEventListener(n._canPlayEvent,v,!1)};c.addEventListener(n._canPlayEvent,v,!1),o._clearTimer(i._id)}}return i._id},pause:function(e){var n=this;if("loaded"!==n._state||n._playLock)return n._queue.push({event:"pause",action:function(){n.pause(e)}}),n;for(var t=n._getSoundIds(e),o=0;o=0?t=parseInt(r[0],10):e=parseFloat(r[0])}else r.length>=2&&(e=parseFloat(r[0]),t=parseInt(r[1],10));var a;if(!(void 0!==e&&e>=0&&e<=1))return a=t?o._soundById(t):o._sounds[0],a?a._volume:0;if("loaded"!==o._state)return o._queue.push({event:"volume",action:function(){o.volume.apply(o,r)}}),o;void 0===t&&(o._volume=e),t=o._getSoundIds(t);for(var u=0;u0?o/_:o),l=Date.now();e._fadeTo=t,e._interval=setInterval(function(){var r=(Date.now()-l)/o;l=Date.now(),i+=d*r,i=Math.max(0,i),i=Math.min(1,i),i=Math.round(100*i)/100,u._webAudio?e._volume=i:u.volume(i,e._id,!0),a&&(u._volume=i),(tn&&i>=t)&&(clearInterval(e._interval),e._interval=null,e._fadeTo=null,u.volume(t,e._id),u._emit("fade",e._id))},s)},_stopFade:function(e){var t=this,o=t._soundById(e);return o&&o._interval&&(t._webAudio&&o._node.gain.cancelScheduledValues(n.ctx.currentTime),clearInterval(o._interval),o._interval=null,t.volume(o._fadeTo,e),o._fadeTo=null,t._emit("fade",e)),t},loop:function(){var e,n,t,o=this,r=arguments;if(0===r.length)return o._loop;if(1===r.length){if("boolean"!=typeof r[0])return!!(t=o._soundById(parseInt(r[0],10)))&&t._loop;e=r[0],o._loop=e}else 2===r.length&&(e=r[0],n=parseInt(r[1],10));for(var a=o._getSoundIds(n),u=0;u=0?t=parseInt(r[0],10):e=parseFloat(r[0])}else 2===r.length&&(e=parseFloat(r[0]),t=parseInt(r[1],10));var i;if("number"!=typeof e)return i=o._soundById(t),i?i._rate:o._rate;if("loaded"!==o._state)return o._queue.push({event:"rate",action:function(){o.rate.apply(o,r)}}),o;void 0===t&&(o._rate=e),t=o._getSoundIds(t);for(var d=0;d=0?t=parseInt(r[0],10):o._sounds.length&&(t=o._sounds[0]._id,e=parseFloat(r[0]))}else 2===r.length&&(e=parseFloat(r[0]),t=parseInt(r[1],10));if(void 0===t)return o;if("loaded"!==o._state)return o._queue.push({event:"seek",action:function(){o.seek.apply(o,r)}}),o;var i=o._soundById(t);if(i){if(!("number"==typeof e&&e>=0)){if(o._webAudio){var d=o.playing(t)?n.ctx.currentTime-i._playStart:0,_=i._rateSeek?i._rateSeek-i._seek:0;return i._seek+(_+d*Math.abs(i._rate))}return i._node.currentTime}var s=o.playing(t);if(s&&o.pause(t,!0),i._seek=e,i._ended=!1,o._clearTimer(t),s&&o.play(t,!0),!o._webAudio&&i._node&&(i._node.currentTime=e),s&&!o._webAudio){var l=function(){o._playLock?setTimeout(l,0):o._emit("seek",t)};setTimeout(l,0)}else o._emit("seek",t)}return o},playing:function(e){var n=this;if("number"==typeof e){var t=n._soundById(e);return!!t&&!t._paused}for(var o=0;o=0&&n._howls.splice(a,1)}var u=!0;for(o=0;o=0;a--)r[a].id&&r[a].id!==n&&"load"!==e||(setTimeout(function(e){e.call(this,n,t)}.bind(o,r[a].fn),0),r[a].once&&o.off(e,r[a].fn,r[a].id));return o._loadQueue(e),o},_loadQueue:function(e){var n=this;if(n._queue.length>0){var t=n._queue[0];t.event===e&&(n._queue.shift(),n._loadQueue()),e||t.action()}return n},_ended:function(e){var t=this,o=e._sprite;if(!t._webAudio&&e._node&&!e._node.paused&&!e._node.ended&&e._node.currentTime=0;o--){if(t<=n)return;e._sounds[o]._ended&&(e._webAudio&&e._sounds[o]._node&&e._sounds[o]._node.disconnect(0),e._sounds.splice(o,1),t--)}}},_getSoundIds:function(e){var n=this;if(void 0===e){for(var t=[],o=0;o0&&(r[t._src]=e,d(t,e))},function(){t._emit("loaderror",null,"Decoding audio data failed.")})},d=function(e,n){n&&!e._duration&&(e._duration=n.duration),0===Object.keys(e._sprite).length&&(e._sprite={__default:[0,1e3*e._duration]}),"loaded"!==e._state&&(e._state="loaded",e._emit("load"),e._loadQueue())},_=function(){try{"undefined"!=typeof AudioContext?n.ctx=new AudioContext:"undefined"!=typeof webkitAudioContext?n.ctx=new webkitAudioContext:n.usingWebAudio=!1}catch(e){n.usingWebAudio=!1}var e=/iP(hone|od|ad)/.test(n._navigator&&n._navigator.platform),t=n._navigator&&n._navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),o=t?parseInt(t[1],10):null;if(e&&o&&o<9){var r=/safari/.test(n._navigator&&n._navigator.userAgent.toLowerCase());(n._navigator&&n._navigator.standalone&&!r||n._navigator&&!n._navigator.standalone&&!r)&&(n.usingWebAudio=!1)}n.usingWebAudio&&(n.masterGain=void 0===n.ctx.createGain?n.ctx.createGainNode():n.ctx.createGain(),n.masterGain.gain.setValueAtTime(n._muted?0:1,n.ctx.currentTime),n.masterGain.connect(n.ctx.destination)),n._setup()};"function"==typeof define&&define.amd&&define([],function(){return{Howler:n,Howl:t}}),"undefined"!=typeof exports&&(exports.Howler=n,exports.Howl=t),"undefined"!=typeof window?(window.HowlerGlobal=e,window.Howler=n,window.Howl=t,window.Sound=o):"undefined"!=typeof global&&(global.HowlerGlobal=e,global.Howler=n,global.Howl=t,global.Sound=o)}();
+/*! Spatial Plugin */
+!function(){"use strict";HowlerGlobal.prototype._pos=[0,0,0],HowlerGlobal.prototype._orientation=[0,0,-1,0,1,0],HowlerGlobal.prototype.stereo=function(n){var e=this;if(!e.ctx||!e.ctx.listener)return e;for(var t=e._howls.length-1;t>=0;t--)e._howls[t].stereo(n);return e},HowlerGlobal.prototype.pos=function(n,e,t){var o=this;return o.ctx&&o.ctx.listener?(e="number"!=typeof e?o._pos[1]:e,t="number"!=typeof t?o._pos[2]:t,"number"!=typeof n?o._pos:(o._pos=[n,e,t],o.ctx.listener.setPosition(o._pos[0],o._pos[1],o._pos[2]),o)):o},HowlerGlobal.prototype.orientation=function(n,e,t,o,r,a){var i=this;if(!i.ctx||!i.ctx.listener)return i;var p=i._orientation;return e="number"!=typeof e?p[1]:e,t="number"!=typeof t?p[2]:t,o="number"!=typeof o?p[3]:o,r="number"!=typeof r?p[4]:r,a="number"!=typeof a?p[5]:a,"number"!=typeof n?p:(i._orientation=[n,e,t,o,r,a],i.ctx.listener.setOrientation(n,e,t,o,r,a),i)},Howl.prototype.init=function(n){return function(e){var t=this;return t._orientation=e.orientation||[1,0,0],t._stereo=e.stereo||null,t._pos=e.pos||null,t._pannerAttr={coneInnerAngle:void 0!==e.coneInnerAngle?e.coneInnerAngle:360,coneOuterAngle:void 0!==e.coneOuterAngle?e.coneOuterAngle:360,coneOuterGain:void 0!==e.coneOuterGain?e.coneOuterGain:0,distanceModel:void 0!==e.distanceModel?e.distanceModel:"inverse",maxDistance:void 0!==e.maxDistance?e.maxDistance:1e4,panningModel:void 0!==e.panningModel?e.panningModel:"HRTF",refDistance:void 0!==e.refDistance?e.refDistance:1,rolloffFactor:void 0!==e.rolloffFactor?e.rolloffFactor:1},t._onstereo=e.onstereo?[{fn:e.onstereo}]:[],t._onpos=e.onpos?[{fn:e.onpos}]:[],t._onorientation=e.onorientation?[{fn:e.onorientation}]:[],n.call(this,e)}}(Howl.prototype.init),Howl.prototype.stereo=function(e,t){var o=this;if(!o._webAudio)return o;if("loaded"!==o._state)return o._queue.push({event:"stereo",action:function(){o.stereo(e,t)}}),o;var r=void 0===Howler.ctx.createStereoPanner?"spatial":"stereo";if(void 0===t){if("number"!=typeof e)return o._stereo;o._stereo=e,o._pos=[e,0,0]}for(var a=o._getSoundIds(t),i=0;i
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MediaPlayer/coffees/main.coffee b/MediaPlayer/coffees/main.coffee
new file mode 100644
index 0000000..889f7fc
--- /dev/null
+++ b/MediaPlayer/coffees/main.coffee
@@ -0,0 +1,262 @@
+class MediaPlayer extends this.OS.GUI.BaseApplication
+ constructor: ( args ) ->
+ super "MediaPlayer", args
+
+ main: () ->
+ me = @
+ @volsw = @find "play-vol"
+ @volctl = @find "vol-control"
+ @volsw.set "swon", true
+ @volctl.set "onchange", (v) ->
+ return unless (me.volsw.get "swon")
+ Howler.volume (me.volctl.get "value")/100
+ @volctl.set "value", 70
+ @playlist = @find "playlist"
+ @playtime = @find "play-time"
+ @songname = @find "song-name"
+ @totaltime = @find "total-time"
+ @playpause = @find "play-pause"
+ @progress = @find "play-slide"
+ @playran = @find "play-random"
+ @history = []
+ @currsong = undefined
+ @timer = undefined
+ @animator = @find "animation"
+
+ @volsw.set "onchange", (e) ->
+ return Howler.volume 0 if not e.data
+ Howler.volume (me.volctl.get "value")/100
+ @playlist.set "buttons", [
+ {
+ text: "+",
+ onbtclick: () ->
+ me.openDialog "FileDiaLog", (d,n,p,f) ->
+ return me.scanDir f if f.type is "dir"
+ f.text = f.filename
+ f.iconclass = "fa fa-music"
+ me.playlist.push f, true
+ , "__(Select MP3 file or a folder)"
+ , { mimes: ["dir", "audio/mpeg"] }
+ },
+ {
+ text: "-",
+ onbtclick: () ->
+ sel = me.playlist.get "selected"
+ return unless sel
+ me.stop() if sel is me.currsong
+ me.playlist.remove sel, true
+ },
+ {
+ text: "",
+ onbtclick: () ->
+ me.openDialog "PromptDialog", (link) ->
+ return unless link and link isnt ""
+ data = {
+ text: link,
+ path: link,
+ iconclass: "fa fa-link",
+ broadcast: true
+ }
+ me.playlist.push data, true
+ , "__(MP3 Radio broadcast)", { label:"Enter radio broadcast link" }
+ , iconclass: "fa fa-link"
+ },
+ {
+ text:"",
+ iconclass: "fa fa-save",
+ onbtclick: () ->
+ playlist = []
+ for v in me.playlist.get "items"
+ playlist.push {
+ text: v.text,
+ path: v.path,
+ iconclass: v.iconclass,
+ broadcast: if v.broadcast then v.broadcast else false
+ }
+ fp = "Untitled".asFileHandler()
+ me.openDialog "FileDiaLog", (d,n,p,f) ->
+ fp = "#{d}/#{n}".asFileHandler()
+ fp.cache = playlist
+ fp.write "object", (r) ->
+ return me.error __("Cannot save playlist: {0}", r.error) if r.error
+ me.notify __("Playlist saved")
+ , "__(Save Playlist)", { file: fp }
+ },
+ {
+ text:"",
+ iconclass: "fa fa-folder",
+ onbtclick: () ->
+ me.openDialog "FileDiaLog", (d,n,p,f) ->
+ f.path.asFileHandler().read (d) ->
+ me.stop()
+ me.playlist.set "items", d
+ , "json"
+ , "__(Open Playlist)", { mimes: ["application/json"] }
+ }
+ ]
+ @playlist.set "onlistdbclick", (e) ->
+ return unless e
+ e.data.index = e.idx
+ me.play e.data
+ @progress.set "onchange", (s) ->
+ me.seek s
+ @playpause.set "onchange", (e) ->
+ me.togglePlayPause()
+ (@find "play-prev").set "onbtclick", () ->
+ me.prevSong()
+ (@find "play-next").set "onbtclick", () ->
+ me.nextSong()
+ $(@animator).css("visibility", "hidden")
+ scanDir: (f) ->
+ me = @
+ f.path.asFileHandler().read (d) ->
+ return me.error __("Unable to read {0}", d.error) if d.error
+ for v in d.result when v.mime.match /audio\/mpeg/
+ v.iconclass = "fa fa-music"
+ v.text = v.filename
+ me.playlist.push v, true
+
+
+ togglePlayPause: () ->
+ return @playpause.set "swon",false unless @currsong and @currsong.howl
+ sound = @currsong.howl
+ if sound.playing()
+ sound.pause()
+ else
+ sound.play()
+
+ nextSong: () ->
+ idx = -1
+ if (@playran.get "swon")
+ idx = @randomSong()
+ else
+ len = (@playlist.get "items").length
+ if len > 0
+ idx = 0
+ idx = @currsong.index + 1 if @currsong
+ idx = 0 if idx >= len
+ return if idx is -1
+ @history.pop() if history.length >= 10
+ @history.unshift @currsong.index if @currsong
+ @playlist.set "selected", idx
+ sel = @playlist.get "selected"
+ sel.index = idx
+ @play sel
+
+ prevSong: () ->
+ idx = -1
+ if (@playran.get "swon")
+ idx = @history.shift() if @history.length > 0
+ else
+ len = (@playlist.get "items").length
+ if len > 0
+ idx = @currsong.index - 1 if @currsong
+ idx = 0 if idx < 0
+ return if idx is -1
+ @playlist.set "selected", idx
+ sel = @playlist.get "selected"
+ sel.index = idx
+ @play sel
+
+ randomSong: () ->
+ len = (@playlist.get "items").length
+ return -1 unless len > 0
+ return Math.floor(Math.random() * Math.floor(len))
+
+ play: (file) ->
+ me = @
+ @stop()
+ @currsong = file
+ sound = file.howl
+ if not sound
+ sound = file.howl = new Howl {
+ src: [
+ file.path.asFileHandler().getlink()
+ ],
+ preload:true,
+ buffer: true,
+ html5: true, # Force to HTML5 so that the audio can stream in (best for large files).
+ format: ['mp3', 'aac'],
+ onplay: () ->
+ $(me.animator).css("visibility", "visible")
+ #Display the duration.
+ me.playpause.set "swon", true
+ console.log "play"
+ me.songname.set "text", file.text
+ duration = Math.round(sound.duration())
+ if duration isnt Infinity
+ me.totaltime.set "text", me.formatDuration duration
+ me.progress.set "max", duration
+ else
+ me.totaltime.set "text", "--:--"
+ me.progress.set "max", 0
+ if not file.broadcast
+ func = () ->
+ if sound.playing()
+ seek = Math.round(sound.seek()) || 0
+ me.progress.set "value", seek
+ me.playtime.set "text", me.formatDuration seek
+ me.timer = setTimeout (() -> func()), 1000
+ func()
+ else
+ me.totaltime.set "text", "--:--"
+ me.progress.set "value", (me.progress.get "max")
+ func = () ->
+ if sound.playing()
+ seek = Math.round(sound.seek()) || 0
+ me.playtime.set "text", me.formatDuration seek
+ me.timer = setTimeout (() -> func()), 1000
+ func()
+ onload: () ->
+ # Start the wave animation.
+ console.log "load"
+ $(me.animator).css("visibility", "hidden")
+ sound.play() if not file.broadcast
+
+ onend: () ->
+ # Stop the wave animation.
+ me.progress.set "value", 0
+ clearTimeout me.timer if me.timer
+ me.playpause.set "swon", false
+ $(me.animator).css("visibility", "hidden")
+ me.nextSong()
+ onpause: ()->
+ # Stop the wave animation.
+ console.log "pause"
+ clearTimeout me.timer if me.timer
+ me.playpause.set "swon", false
+ $(me.animator).css("visibility", "hidden")
+
+ onstop: () ->
+ me.progress.set "value", 0
+ clearTimeout me.timer if me.timer
+ me.playpause.set "swon", false
+ $(me.animator).css("visibility", "hidden")
+ console.log "stop"
+ }
+ sound.play() if file.broadcast
+ else
+ sound.play()
+ $(@animator).css("visibility", "visible")
+ stop: () ->
+ if @currsong and @currsong.howl
+ @currsong.howl.stop() if @currsong.howl.playing()
+
+ seek: (v) ->
+ return unless @currsong and @currsong.howl and not @currsong.broadcast
+ return unless (@progress.get "max") > 0
+ sound = @currsong.howl
+ sound.seek(v)
+
+ formatDuration: (s) ->
+ min = Math.floor(s/60)
+ sec = s % 60
+ min = if min < 10 then "0#{min}" else "#{min}"
+ sec = if sec < 10 then "0#{sec}" else "#{sec}"
+ "#{min}:#{sec}"
+
+ cleanup: (evt) ->
+ @stop()
+# only one instance is allow
+MediaPlayer.singleton = true
+this.OS.register "MediaPlayer", MediaPlayer
\ No newline at end of file
diff --git a/MediaPlayer/css/main.css b/MediaPlayer/css/main.css
new file mode 100644
index 0000000..a1ed196
--- /dev/null
+++ b/MediaPlayer/css/main.css
@@ -0,0 +1,107 @@
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-button button{
+ border: 0;
+ font-size: 25px;
+ padding-top:9px;
+ background-color: transparent;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-pause"]{
+ padding-top:5px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-pause"] span::before{
+ content: "\f144";
+ font-size: 40px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-pause"] .swon::before{
+ content: "\f28b";
+}
+afx-app-window[data-id="MediaPlayer"] afx-label[data-id="play-time"] {
+ text-align: left;
+}
+afx-app-window[data-id="MediaPlayer"] afx-label[data-id="total-time"] {
+ text-align: right;
+}
+afx-app-window[data-id="MediaPlayer"] afx-label[data-id="song-name"] {
+ text-align: center;
+ display: inline;
+ overflow: hidden;
+}
+afx-app-window[data-id="MediaPlayer"] afx-slider .dragpoint {
+ width:12px;
+ height: 12px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-slider[data-id="vol-control"] .progress {
+ background-color: #a6a6a6;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-vol"] {
+ margin-top:10px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-vol"] span::before{
+ content: "\f026";
+ font-size: 19px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-vol"] .swon::before{
+ content: "\f028";
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-random"] span::before{
+ content: "\f074";
+ font-size: 16px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-random"] .swon::before{
+ content: "\f074";
+}
+afx-app-window[data-id="MediaPlayer"] afx-hbox.play-control afx-switch[data-id="play-random"] {
+ margin-top:10px;
+}
+afx-app-window[data-id="MediaPlayer"] afx-list-view[data-id="playlist"] {
+ border:1px solid #a6a6a6;
+}
+afx-app-window[data-id="MediaPlayer"] afx-button.ctlbtn button:active{
+ background-color: transparent;
+ color:#2786F3;
+}
+afx-app-window[data-id="MediaPlayer"] .animation {
+ position: relative;
+}
+
+afx-app-window[data-id="MediaPlayer"] .animation span{
+ width:5px;
+ height: 5px;
+ bottom:18px;
+ position:absolute;
+ -webkit-animation: bodong 0.5s infinite ease;
+}
+
+afx-app-window[data-id="MediaPlayer"] .animation span:first-child{
+ left:10px;
+ -webkit-animation-delay:.3s;
+ background-color: red;
+}
+
+afx-app-window[data-id="MediaPlayer"] .animation span:nth-child(2){
+ left:17px;
+ -webkit-animation-delay:.4s;
+ background-color:orange ;
+}
+afx-app-window[data-id="MediaPlayer"] .animation span:nth-child(3){
+ left:24px;
+ -webkit-animation-delay:.6s;
+ background-color: #2786F3;
+}
+afx-app-window[data-id="MediaPlayer"] .animation span:nth-child(4){
+ left:31px;
+ -webkit-animation-delay:.8s;
+ background-color: chocolate;
+}
+afx-app-window[data-id="MediaPlayer"] .animation span:nth-child(5){
+ left:38px;
+ -webkit-animation-delay:1s;
+ background-color: blue;
+}
+
+@-webkit-keyframes bodong{
+ 0%{height:5px; background:bule;}
+ 30%{height:15px; background:bule;}
+ 60%{height:20px; background:bule;}
+ 80%{height:15px; background:bule;}
+ 100%{height:5px; background:bule;}
+}
diff --git a/MediaPlayer/javascripts/howler.min.js b/MediaPlayer/javascripts/howler.min.js
new file mode 100644
index 0000000..b6a1145
--- /dev/null
+++ b/MediaPlayer/javascripts/howler.min.js
@@ -0,0 +1,4 @@
+/*! howler.js v2.0.9 | (c) 2013-2018, James Simpson of GoldFire Studios | MIT License | howlerjs.com */
+!function(){"use strict";var e=function(){this.init()};e.prototype={init:function(){var e=this||n;return e._counter=1e3,e._codecs={},e._howls=[],e._muted=!1,e._volume=1,e._canPlayEvent="canplaythrough",e._navigator="undefined"!=typeof window&&window.navigator?window.navigator:null,e.masterGain=null,e.noAudio=!1,e.usingWebAudio=!0,e.autoSuspend=!0,e.ctx=null,e.mobileAutoEnable=!0,e._setup(),e},volume:function(e){var t=this||n;if(e=parseFloat(e),t.ctx||_(),void 0!==e&&e>=0&&e<=1){if(t._volume=e,t._muted)return t;t.usingWebAudio&&t.masterGain.gain.setValueAtTime(e,n.ctx.currentTime);for(var o=0;o=0;t--)e._howls[t].unload();return e.usingWebAudio&&e.ctx&&void 0!==e.ctx.close&&(e.ctx.close(),e.ctx=null,_()),e},codecs:function(e){return(this||n)._codecs[e.replace(/^x-/,"")]},_setup:function(){var e=this||n;if(e.state=e.ctx?e.ctx.state||"running":"running",e._autoSuspend(),!e.usingWebAudio)if("undefined"!=typeof Audio)try{var t=new Audio;void 0===t.oncanplaythrough&&(e._canPlayEvent="canplay")}catch(n){e.noAudio=!0}else e.noAudio=!0;try{var t=new Audio;t.muted&&(e.noAudio=!0)}catch(e){}return e.noAudio||e._setupCodecs(),e},_setupCodecs:function(){var e=this||n,t=null;try{t="undefined"!=typeof Audio?new Audio:null}catch(n){return e}if(!t||"function"!=typeof t.canPlayType)return e;var o=t.canPlayType("audio/mpeg;").replace(/^no$/,""),r=e._navigator&&e._navigator.userAgent.match(/OPR\/([0-6].)/g),a=r&&parseInt(r[0].split("/")[1],10)<33;return e._codecs={mp3:!(a||!o&&!t.canPlayType("audio/mp3;").replace(/^no$/,"")),mpeg:!!o,opus:!!t.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,""),ogg:!!t.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),oga:!!t.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),wav:!!t.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),aac:!!t.canPlayType("audio/aac;").replace(/^no$/,""),caf:!!t.canPlayType("audio/x-caf;").replace(/^no$/,""),m4a:!!(t.canPlayType("audio/x-m4a;")||t.canPlayType("audio/m4a;")||t.canPlayType("audio/aac;")).replace(/^no$/,""),mp4:!!(t.canPlayType("audio/x-mp4;")||t.canPlayType("audio/mp4;")||t.canPlayType("audio/aac;")).replace(/^no$/,""),weba:!!t.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,""),webm:!!t.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,""),dolby:!!t.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/,""),flac:!!(t.canPlayType("audio/x-flac;")||t.canPlayType("audio/flac;")).replace(/^no$/,"")},e},_enableMobileAudio:function(){var e=this||n,t=/iPhone|iPad|iPod|Android|BlackBerry|BB10|Silk|Mobi/i.test(e._navigator&&e._navigator.userAgent),o=!!("ontouchend"in window||e._navigator&&e._navigator.maxTouchPoints>0||e._navigator&&e._navigator.msMaxTouchPoints>0);if(!e._mobileEnabled&&e.ctx&&(t||o)){e._mobileEnabled=!1,e._mobileUnloaded||44100===e.ctx.sampleRate||(e._mobileUnloaded=!0,e.unload()),e._scratchBuffer=e.ctx.createBuffer(1,1,22050);var r=function(){n._autoResume();var t=e.ctx.createBufferSource();t.buffer=e._scratchBuffer,t.connect(e.ctx.destination),void 0===t.start?t.noteOn(0):t.start(0),"function"==typeof e.ctx.resume&&e.ctx.resume(),t.onended=function(){t.disconnect(0),e._mobileEnabled=!0,e.mobileAutoEnable=!1,document.removeEventListener("touchstart",r,!0),document.removeEventListener("touchend",r,!0)}};return document.addEventListener("touchstart",r,!0),document.addEventListener("touchend",r,!0),e}},_autoSuspend:function(){var e=this;if(e.autoSuspend&&e.ctx&&void 0!==e.ctx.suspend&&n.usingWebAudio){for(var t=0;t0?i._seek:o._sprite[e][0]/1e3),s=Math.max(0,(o._sprite[e][0]+o._sprite[e][1])/1e3-_),l=1e3*s/Math.abs(i._rate);i._paused=!1,i._ended=!1,i._sprite=e,i._seek=_,i._start=o._sprite[e][0]/1e3,i._stop=(o._sprite[e][0]+o._sprite[e][1])/1e3,i._loop=!(!i._loop&&!o._sprite[e][2]);var c=i._node;if(o._webAudio){var f=function(){o._refreshBuffer(i);var e=i._muted||o._muted?0:i._volume;c.gain.setValueAtTime(e,n.ctx.currentTime),i._playStart=n.ctx.currentTime,void 0===c.bufferSource.start?i._loop?c.bufferSource.noteGrainOn(0,_,86400):c.bufferSource.noteGrainOn(0,_,s):i._loop?c.bufferSource.start(0,_,86400):c.bufferSource.start(0,_,s),l!==1/0&&(o._endTimers[i._id]=setTimeout(o._ended.bind(o,i),l)),t||setTimeout(function(){o._emit("play",i._id)},0)};"running"===n.state?f():(o.once("resume",f),o._clearTimer(i._id))}else{var p=function(){c.currentTime=_,c.muted=i._muted||o._muted||n._muted||c.muted,c.volume=i._volume*n.volume(),c.playbackRate=i._rate;try{var r=c.play();if("undefined"!=typeof Promise&&r instanceof Promise){o._playLock=!0;var a=function(){o._playLock=!1,t||o._emit("play",i._id)};r.then(a,a)}else t||o._emit("play",i._id);if(c.paused)return void o._emit("playerror",i._id,"Playback was unable to start. This is most commonly an issue on mobile devices where playback was not within a user interaction.");"__default"!==e?o._endTimers[i._id]=setTimeout(o._ended.bind(o,i),l):(o._endTimers[i._id]=function(){o._ended(i),c.removeEventListener("ended",o._endTimers[i._id],!1)},c.addEventListener("ended",o._endTimers[i._id],!1))}catch(e){o._emit("playerror",i._id,e)}},m=window&&window.ejecta||!c.readyState&&n._navigator.isCocoonJS;if(c.readyState>=3||m)p();else{var v=function(){p(),c.removeEventListener(n._canPlayEvent,v,!1)};c.addEventListener(n._canPlayEvent,v,!1),o._clearTimer(i._id)}}return i._id},pause:function(e){var n=this;if("loaded"!==n._state||n._playLock)return n._queue.push({event:"pause",action:function(){n.pause(e)}}),n;for(var t=n._getSoundIds(e),o=0;o=0?t=parseInt(r[0],10):e=parseFloat(r[0])}else r.length>=2&&(e=parseFloat(r[0]),t=parseInt(r[1],10));var a;if(!(void 0!==e&&e>=0&&e<=1))return a=t?o._soundById(t):o._sounds[0],a?a._volume:0;if("loaded"!==o._state)return o._queue.push({event:"volume",action:function(){o.volume.apply(o,r)}}),o;void 0===t&&(o._volume=e),t=o._getSoundIds(t);for(var u=0;u0?o/_:o),l=Date.now();e._fadeTo=t,e._interval=setInterval(function(){var r=(Date.now()-l)/o;l=Date.now(),i+=d*r,i=Math.max(0,i),i=Math.min(1,i),i=Math.round(100*i)/100,u._webAudio?e._volume=i:u.volume(i,e._id,!0),a&&(u._volume=i),(tn&&i>=t)&&(clearInterval(e._interval),e._interval=null,e._fadeTo=null,u.volume(t,e._id),u._emit("fade",e._id))},s)},_stopFade:function(e){var t=this,o=t._soundById(e);return o&&o._interval&&(t._webAudio&&o._node.gain.cancelScheduledValues(n.ctx.currentTime),clearInterval(o._interval),o._interval=null,t.volume(o._fadeTo,e),o._fadeTo=null,t._emit("fade",e)),t},loop:function(){var e,n,t,o=this,r=arguments;if(0===r.length)return o._loop;if(1===r.length){if("boolean"!=typeof r[0])return!!(t=o._soundById(parseInt(r[0],10)))&&t._loop;e=r[0],o._loop=e}else 2===r.length&&(e=r[0],n=parseInt(r[1],10));for(var a=o._getSoundIds(n),u=0;u=0?t=parseInt(r[0],10):e=parseFloat(r[0])}else 2===r.length&&(e=parseFloat(r[0]),t=parseInt(r[1],10));var i;if("number"!=typeof e)return i=o._soundById(t),i?i._rate:o._rate;if("loaded"!==o._state)return o._queue.push({event:"rate",action:function(){o.rate.apply(o,r)}}),o;void 0===t&&(o._rate=e),t=o._getSoundIds(t);for(var d=0;d=0?t=parseInt(r[0],10):o._sounds.length&&(t=o._sounds[0]._id,e=parseFloat(r[0]))}else 2===r.length&&(e=parseFloat(r[0]),t=parseInt(r[1],10));if(void 0===t)return o;if("loaded"!==o._state)return o._queue.push({event:"seek",action:function(){o.seek.apply(o,r)}}),o;var i=o._soundById(t);if(i){if(!("number"==typeof e&&e>=0)){if(o._webAudio){var d=o.playing(t)?n.ctx.currentTime-i._playStart:0,_=i._rateSeek?i._rateSeek-i._seek:0;return i._seek+(_+d*Math.abs(i._rate))}return i._node.currentTime}var s=o.playing(t);if(s&&o.pause(t,!0),i._seek=e,i._ended=!1,o._clearTimer(t),s&&o.play(t,!0),!o._webAudio&&i._node&&(i._node.currentTime=e),s&&!o._webAudio){var l=function(){o._playLock?setTimeout(l,0):o._emit("seek",t)};setTimeout(l,0)}else o._emit("seek",t)}return o},playing:function(e){var n=this;if("number"==typeof e){var t=n._soundById(e);return!!t&&!t._paused}for(var o=0;o=0&&n._howls.splice(a,1)}var u=!0;for(o=0;o=0;a--)r[a].id&&r[a].id!==n&&"load"!==e||(setTimeout(function(e){e.call(this,n,t)}.bind(o,r[a].fn),0),r[a].once&&o.off(e,r[a].fn,r[a].id));return o._loadQueue(e),o},_loadQueue:function(e){var n=this;if(n._queue.length>0){var t=n._queue[0];t.event===e&&(n._queue.shift(),n._loadQueue()),e||t.action()}return n},_ended:function(e){var t=this,o=e._sprite;if(!t._webAudio&&e._node&&!e._node.paused&&!e._node.ended&&e._node.currentTime=0;o--){if(t<=n)return;e._sounds[o]._ended&&(e._webAudio&&e._sounds[o]._node&&e._sounds[o]._node.disconnect(0),e._sounds.splice(o,1),t--)}}},_getSoundIds:function(e){var n=this;if(void 0===e){for(var t=[],o=0;o0&&(r[t._src]=e,d(t,e))},function(){t._emit("loaderror",null,"Decoding audio data failed.")})},d=function(e,n){n&&!e._duration&&(e._duration=n.duration),0===Object.keys(e._sprite).length&&(e._sprite={__default:[0,1e3*e._duration]}),"loaded"!==e._state&&(e._state="loaded",e._emit("load"),e._loadQueue())},_=function(){try{"undefined"!=typeof AudioContext?n.ctx=new AudioContext:"undefined"!=typeof webkitAudioContext?n.ctx=new webkitAudioContext:n.usingWebAudio=!1}catch(e){n.usingWebAudio=!1}var e=/iP(hone|od|ad)/.test(n._navigator&&n._navigator.platform),t=n._navigator&&n._navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),o=t?parseInt(t[1],10):null;if(e&&o&&o<9){var r=/safari/.test(n._navigator&&n._navigator.userAgent.toLowerCase());(n._navigator&&n._navigator.standalone&&!r||n._navigator&&!n._navigator.standalone&&!r)&&(n.usingWebAudio=!1)}n.usingWebAudio&&(n.masterGain=void 0===n.ctx.createGain?n.ctx.createGainNode():n.ctx.createGain(),n.masterGain.gain.setValueAtTime(n._muted?0:1,n.ctx.currentTime),n.masterGain.connect(n.ctx.destination)),n._setup()};"function"==typeof define&&define.amd&&define([],function(){return{Howler:n,Howl:t}}),"undefined"!=typeof exports&&(exports.Howler=n,exports.Howl=t),"undefined"!=typeof window?(window.HowlerGlobal=e,window.Howler=n,window.Howl=t,window.Sound=o):"undefined"!=typeof global&&(global.HowlerGlobal=e,global.Howler=n,global.Howl=t,global.Sound=o)}();
+/*! Spatial Plugin */
+!function(){"use strict";HowlerGlobal.prototype._pos=[0,0,0],HowlerGlobal.prototype._orientation=[0,0,-1,0,1,0],HowlerGlobal.prototype.stereo=function(n){var e=this;if(!e.ctx||!e.ctx.listener)return e;for(var t=e._howls.length-1;t>=0;t--)e._howls[t].stereo(n);return e},HowlerGlobal.prototype.pos=function(n,e,t){var o=this;return o.ctx&&o.ctx.listener?(e="number"!=typeof e?o._pos[1]:e,t="number"!=typeof t?o._pos[2]:t,"number"!=typeof n?o._pos:(o._pos=[n,e,t],o.ctx.listener.setPosition(o._pos[0],o._pos[1],o._pos[2]),o)):o},HowlerGlobal.prototype.orientation=function(n,e,t,o,r,a){var i=this;if(!i.ctx||!i.ctx.listener)return i;var p=i._orientation;return e="number"!=typeof e?p[1]:e,t="number"!=typeof t?p[2]:t,o="number"!=typeof o?p[3]:o,r="number"!=typeof r?p[4]:r,a="number"!=typeof a?p[5]:a,"number"!=typeof n?p:(i._orientation=[n,e,t,o,r,a],i.ctx.listener.setOrientation(n,e,t,o,r,a),i)},Howl.prototype.init=function(n){return function(e){var t=this;return t._orientation=e.orientation||[1,0,0],t._stereo=e.stereo||null,t._pos=e.pos||null,t._pannerAttr={coneInnerAngle:void 0!==e.coneInnerAngle?e.coneInnerAngle:360,coneOuterAngle:void 0!==e.coneOuterAngle?e.coneOuterAngle:360,coneOuterGain:void 0!==e.coneOuterGain?e.coneOuterGain:0,distanceModel:void 0!==e.distanceModel?e.distanceModel:"inverse",maxDistance:void 0!==e.maxDistance?e.maxDistance:1e4,panningModel:void 0!==e.panningModel?e.panningModel:"HRTF",refDistance:void 0!==e.refDistance?e.refDistance:1,rolloffFactor:void 0!==e.rolloffFactor?e.rolloffFactor:1},t._onstereo=e.onstereo?[{fn:e.onstereo}]:[],t._onpos=e.onpos?[{fn:e.onpos}]:[],t._onorientation=e.onorientation?[{fn:e.onorientation}]:[],n.call(this,e)}}(Howl.prototype.init),Howl.prototype.stereo=function(e,t){var o=this;if(!o._webAudio)return o;if("loaded"!==o._state)return o._queue.push({event:"stereo",action:function(){o.stereo(e,t)}}),o;var r=void 0===Howler.ctx.createStereoPanner?"spatial":"stereo";if(void 0===t){if("number"!=typeof e)return o._stereo;o._stereo=e,o._pos=[e,0,0]}for(var a=o._getSoundIds(t),i=0;i