diff options
author | Jon Bergli Heier <snakebite@jvnv.net> | 2011-08-08 00:11:01 +0200 |
---|---|---|
committer | Jon Bergli Heier <snakebite@jvnv.net> | 2011-08-08 00:11:01 +0200 |
commit | 97d7c9014855449fe04162308feac66a35e007ea (patch) | |
tree | 8133c59cb0f066d992f434109818dd771e73f544 /static |
Initial commit.
app.py
- WSGI application and handlers.
config.py
- Config helper class.
directory.py
- Directory and file helper classes.
events.py
- zeromq event publisher and subscriber.
recode.py
- Codecs and stuff
static/
- Web interface
Diffstat (limited to 'static')
-rw-r--r-- | static/audio.js | 19 | ||||
-rw-r--r-- | static/icons/folder.png | bin | 0 -> 537 bytes | |||
-rw-r--r-- | static/icons/loading.gif | bin | 0 -> 1737 bytes | |||
-rw-r--r-- | static/icons/music-cached.png | bin | 0 -> 633 bytes | |||
-rw-r--r-- | static/icons/music-queued.png | bin | 0 -> 646 bytes | |||
-rw-r--r-- | static/icons/music.png | bin | 0 -> 385 bytes | |||
-rw-r--r-- | static/icons/readme.txt | 22 | ||||
-rw-r--r-- | static/index.html | 28 | ||||
-rw-r--r-- | static/player.js | 170 | ||||
-rw-r--r-- | static/style.css | 9 |
10 files changed, 248 insertions, 0 deletions
diff --git a/static/audio.js b/static/audio.js new file mode 100644 index 0000000..6eaec56 --- /dev/null +++ b/static/audio.js @@ -0,0 +1,19 @@ +function Audio() { + this.audio = document.getElementById('audio'); + + this.set_src = function(src) { + this.audio.setAttribute('src', src); + } + + this.play = function() { + this.audio.play(); + } + + this.pause = function() { + this.audio.pause(); + } + + this.stop = function() { + this.audio.stop(); + } +} diff --git a/static/icons/folder.png b/static/icons/folder.png Binary files differnew file mode 100644 index 0000000..784e8fa --- /dev/null +++ b/static/icons/folder.png diff --git a/static/icons/loading.gif b/static/icons/loading.gif Binary files differnew file mode 100644 index 0000000..1560b64 --- /dev/null +++ b/static/icons/loading.gif diff --git a/static/icons/music-cached.png b/static/icons/music-cached.png Binary files differnew file mode 100644 index 0000000..6802f99 --- /dev/null +++ b/static/icons/music-cached.png diff --git a/static/icons/music-queued.png b/static/icons/music-queued.png Binary files differnew file mode 100644 index 0000000..5034c06 --- /dev/null +++ b/static/icons/music-queued.png diff --git a/static/icons/music.png b/static/icons/music.png Binary files differnew file mode 100644 index 0000000..a8b3ede --- /dev/null +++ b/static/icons/music.png diff --git a/static/icons/readme.txt b/static/icons/readme.txt new file mode 100644 index 0000000..400a64d --- /dev/null +++ b/static/icons/readme.txt @@ -0,0 +1,22 @@ +Silk icon set 1.3
+
+_________________________________________
+Mark James
+http://www.famfamfam.com/lab/icons/silk/
+_________________________________________
+
+This work is licensed under a
+Creative Commons Attribution 2.5 License.
+[ http://creativecommons.org/licenses/by/2.5/ ]
+
+This means you may use it for any purpose,
+and make any changes you like.
+All I ask is that you include a link back
+to this page in your credits.
+
+Are you using this icon set? Send me an email
+(including a link or picture if available) to
+mjames@gmail.com
+
+Any other questions about this icon set please
+contact mjames@gmail.com
\ No newline at end of file diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..ea20792 --- /dev/null +++ b/static/index.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> + <title>foo</title> + <script src="/static/audio.js" type="text/javascript"></script> + <script src="/static/player.js" type="text/javascript"></script> + <link rel="stylesheet" href="/static/style.css" type="text/css" /> +</head> +<body> + <div id="transcode-div"> + <label for="trans_enabled"><input type="checkbox" id="trans_enabled" /> Transcode</label> + from + <select id="trans_from"> + <option value="ffmpeg">FFmpeg</option> + </select> + to + <select id="trans_to"> + <option value="ffmpeg">FFmpeg</option> + </select> + </div> + <textarea id="logbox" readonly="readonly" rows="10" cols="50"></textarea> + <div><input type="button" value="Close event source" onclick="source.close()" /></div> + <div id="current-dir"></div> + <ul id="song-links"></ul> + <div id="audio-src-url">none</div> + <audio id="audio" controls="controls"></audio> +</body> +</html> diff --git a/static/player.js b/static/player.js new file mode 100644 index 0000000..70b5a6d --- /dev/null +++ b/static/player.js @@ -0,0 +1,170 @@ +audio = null; + +// pre-load some icons +cache_images = new Array( + 'music-cached.png', + 'music-queued.png', + 'loading.gif' +); +var img = new Image(); +for(var i = 0; i < cache_images.length; i++) { + img.src = '/static/icons/' + cache_images[i]; +} + +function MusicListing(type, path, name, cached) { + this.type = type; + this.path = path; + this.name = name ? name : path.split('/').pop(); + this.a = document.createElement('a'); + this.a.tag = path; + + this.play = function() { + var transcode = document.getElementById('trans_enabled').checked; + var trans_from = document.getElementById('trans_from').value; + var trans_to = document.getElementById('trans_to').value; + var p = path; + if(transcode) + p += '?decoder=' + trans_from + '&encoder=' + trans_to; + log('playing ' + p); + change_url('/files/' + p); + audio.play(); + } + + this.cache = function() { + var path = '/cache?path=' + encodeURIComponent(this.path) + + '&decoder=' + document.getElementById('trans_from').value + + '&encoder=' + document.getElementById('trans_to').value; + var a = this.a; + var ml = this; + var xmlhttp = new XMLHttpRequest(); + a.setAttribute('class', 'file file-queued'); + xmlhttp.open('GET', path); + xmlhttp.send(null); + } + + this.get_anchor = function() { + var a = this.a; + var className = type; + if(cached) + className += ' file-cached' + a.setAttribute('class', className); + a.setAttribute('href', '#'); + a.appendChild(document.createTextNode(this.name)); + var ml = this; + + a.onclick = function() { + if(type == 'dir') { + list(path); + } else if(type == 'file') { + var transcode = document.getElementById('trans_enabled').checked; + var trans_from = document.getElementById('trans_from').value; + var trans_to = document.getElementById('trans_to').value; + + var p = path; + if(transcode) { + ml.cache(p); + } else { + ml.play(); + } + } + return false; + } + return a; + } +} + +function set_current(path) { + document.getElementById('current-dir').innerHTML = 'Directory: ' + path; +} + +function log(s) { + logbox = document.getElementById('logbox'); + logbox.value += s + '\n'; + logbox.scrollTop = logbox.scrollHeight; +} + +function change_url(url) { + audio.set_src(url); + + var audio_src_url = document.getElementById('audio-src-url'); + audio_src_url.innerHTML = 'Playing: ' + url.replace('&', '&'); +} + +function output_link(obj) { + var a = obj.get_anchor(); + + var li = document.createElement('li'); + li.appendChild(a); + + var song_links = document.getElementById('song-links'); + song_links.appendChild(li); +} + +function list(root) { + log('listing ' + root); + var xmlhttp = new XMLHttpRequest(); + xmlhttp.onreadystatechange = function() { + if(xmlhttp.readyState == 4) { + set_current(root); + var json = JSON.parse(xmlhttp.responseText); + document.getElementById('song-links').innerHTML = ''; + // add "up" link + if(root.length > 1) { + up = root.substr(0, root.lastIndexOf('/')); + if(up.length == 0) + up = '/'; + l = new MusicListing('dir', up, '..'); + output_link(l); + } + for(var i = 0; i < json.length; i++) { + var type = json[i]["type"]; + var path = json[i]["name"]; + var name = path.substring(path.lastIndexOf('/')+1); + var cached = type == "file" ? json[i]["cached"] : false; + var l = new MusicListing(type, path, name, cached); + output_link(l); + } + } + } + + path = '/list?directory=' + encodeURIComponent(root); + xmlhttp.open('GET', path); + xmlhttp.send(); +} + +var source = null; + +function get_a(path) { + var as = document.getElementsByTagName('a'); + for(var i = 0; i < as.length; i++) { + var a = as[i]; + if(a.tag == path) + return a; + } +} + +function event_handler(event) { + data = JSON.parse(event.data); + switch(data['type']) { + case 'cached': + case 'recoding': + log('[' + data['type'] + '] ' + data['path']); + var a = get_a(data['path']); + if(a) + a.setAttribute('class', 'file file-' + data['type']); + break; + default: + log('[event] unknown type: ' + data['type']); + } +} + +window.onload = function() { + source = new EventSource('/events'); + source.onopen = function() { log('event source opened'); } + source.onmessage = event_handler; + source.onerror = function(event) { log('event source error'); } + log('event source status: ' + source.readyState); + + audio = new Audio(); + list('/'); +} diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..d086227 --- /dev/null +++ b/static/style.css @@ -0,0 +1,9 @@ +ul#song-links { list-style-type: none; } +ul#song-links a { text-decoration: none; color: inherit; } +ul#song-links a:hover { text-decoration: underline; } +a.dir { background-image: url('/static/icons/folder.png'); } +a.file { background-image: url('/static/icons/music.png'); } +a.file-cached { background-image: url('/static/icons/music-cached.png'); } +a.dir, a.file { background-repeat: no-repeat; padding-left: 20px; } +a.file-recoding { background-image: url('/static/icons/loading.gif'); } +a.file-queued { background-image: url('/static/icons/music-queued.png'); } |