diff --git a/bin/ascoltami2 b/bin/ascoltami2
new file mode 100644
--- /dev/null
+++ b/bin/ascoltami2
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+import web, thread, gobject, sys, optparse, logging
+from rdflib import URIRef
+sys.path.append(".")
+from light9.ascoltami.player import Player
+from light9.ascoltami.webapp import makeApp
+from light9 import networking, showconfig
+
+log = logging.getLogger()
+logging.basicConfig()
+gobject.threads_init()
+
+parser = optparse.OptionParser()
+parser.add_option('--show',
+ help='show URI, like http://light9.bigasterisk.com/show/dance2008')
+parser.add_option("-v", "--verbose", action="store_true",
+ help="logging.DEBUG")
+graph = showconfig.getGraph()
+(options, args) = parser.parse_args()
+
+
+log.setLevel(logging.DEBUG if options.verbose else logging.INFO)
+
+graph = showconfig.getGraph()
+if not options.show:
+ raise ValueError("missing --show http://...")
+
+player = Player()
+
+# the cherrypy server would wedge when vidref pounds on it; this
+# one seems to run
+thread.start_new(web.httpserver.runbasic,
+ (makeApp(player, graph, URIRef(options.show)).wsgifunc(),
+ ('0.0.0.0', networking.musicPort())))
+
+mainloop = gobject.MainLoop()
+mainloop.run()
diff --git a/light9/ascoltami/__init__.py b/light9/ascoltami/__init__.py
new file mode 100644
diff --git a/light9/ascoltami/index.html b/light9/ascoltami/index.html
new file mode 100644
--- /dev/null
+++ b/light9/ascoltami/index.html
@@ -0,0 +1,111 @@
+
+
+
+
+ ascoltami
+
+
+
+
+
+
+
+
+
+
+
+
+ Song:
+ Time:
+ Left:
+
+
+
+
+
+
+
+
+
+
+bind keys, spacebar, css work
+
+
+
+
+
+
\ No newline at end of file
diff --git a/light9/ascoltami/player.py b/light9/ascoltami/player.py
new file mode 100644
--- /dev/null
+++ b/light9/ascoltami/player.py
@@ -0,0 +1,103 @@
+#!/usr/bin/python
+
+"""
+alternate to the mpd music player, for ascoltami
+"""
+from __future__ import division
+import time, logging
+import gst
+log = logging.getLogger()
+
+class Player(object):
+ def __init__(self):
+
+ self.playbin = self.pipeline = gst.parse_launch("playbin2 name=b")
+ self.playStartTime = 0
+ self._duration = 0
+ self.pauseTime = 0
+
+ self.setSong("file:///my/proj/light9/show/dance2010/music/07-jacksonmix-complete.wav")
+
+ #self.pipeline = gst.parse_launch("filesrc name=file location=%s ! wavparse name=src ! audioconvert ! alsasink name=out" % songFile)
+
+ def on_any(bus, msg):
+ print bus, msg
+
+ bus = self.pipeline.get_bus()
+ bus.add_signal_watch()
+ #bus.connect('message', on_any)
+
+ def onStreamStatus(bus, message):
+ (statusType, _elem) = message.parse_stream_status()
+ if statusType == gst.STREAM_STATUS_TYPE_ENTER:
+ self.setupAutostop()
+
+ # we should run our own poller looking for crosses over the autostop threshold and pausing. When i used the pipeline.seek end-time, it caused lots of unwanted other pausing and was hard to turn off.
+
+ #print message, bus
+ bus.connect('message::stream-status', onStreamStatus)
+
+ def seek(self, t):
+ assert self.playbin.seek_simple(
+ gst.FORMAT_TIME,
+ gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE | gst.SEEK_FLAG_SKIP,
+ t * gst.SECOND)
+ self.playStartTime = time.time()
+
+ def setSong(self, songUri):
+ """
+ uri like file:///my/proj/light9/show/dance2010/music/07.wav
+ """
+ log.info("set song to %r" % songUri)
+ self.pipeline.set_state(gst.STATE_READY)
+ self.pipeline.set_property("uri", songUri)
+ self.pipeline.set_state(gst.STATE_PLAYING)
+ self.playStartTime = time.time()
+
+
+
+# GST_MESSAGE_DURATION
+
+
+ def currentTime(self):
+ cur, _format = self.playbin.query_position(gst.FORMAT_TIME)
+ return cur / gst.SECOND
+
+ def duration(self):
+ return self.playbin.query_duration(gst.FORMAT_TIME)[0] / gst.SECOND
+
+ def pause(self):
+ self.pipeline.set_state(gst.STATE_PAUSED)
+
+ def resume(self):
+ self.pipeline.set_state(gst.STATE_PLAYING)
+ pos = self.currentTime()
+ autoStop = self.duration() - 10
+ if abs(pos - autoStop) < .01:
+ self.releaseAutostop()
+
+
+ def setupAutostop(self):
+ return
+ dur = self.duration()
+ autoStop = (dur - 10.0)
+ log.info("autostop will be at %s", autoStop)
+ print "seek", self.pipeline.seek(1.0, gst.FORMAT_TIME,
+ gst.SEEK_FLAG_ACCURATE,
+ gst.SEEK_TYPE_NONE, 0,
+ gst.SEEK_TYPE_SET, autoStop * gst.SECOND)
+
+ def releaseAutostop(self):
+ log.info("release autostop")
+
+ print "seek", self.pipeline.seek(
+ 1.0, gst.FORMAT_TIME,
+ gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE | gst.SEEK_FLAG_SKIP,
+ gst.SEEK_TYPE_NONE, 0,
+ gst.SEEK_TYPE_END, 0)
+ print self.pipeline.get_state()
+ self.pipeline.set_state(gst.STATE_PLAYING)
+
+
+
+
diff --git a/light9/ascoltami/webapp.py b/light9/ascoltami/webapp.py
new file mode 100644
--- /dev/null
+++ b/light9/ascoltami/webapp.py
@@ -0,0 +1,64 @@
+import web, jsonlib
+from twisted.python.util import sibpath
+from light9.namespaces import L9, MUS
+
+player = None
+graph = None
+show = None
+
+class root(object):
+ def GET(self):
+ web.header("Content-type", "application/xhtml+xml")
+ return open(sibpath(__file__, "index.html")).read()
+
+class timeResource(object):
+ def GET(self):
+ return jsonlib.write({"song" : player.playbin.get_property("uri"),
+ "started" : player.playStartTime,
+ "duration" : player.duration(),
+ "t" : player.currentTime()})
+
+ def POST(self):
+ params = jsonlib.read(web.data(), use_float=True)
+ if params.get('pause', False):
+ player.pause()
+ if params.get('resume', False):
+ player.resume()
+ if 't' in params:
+ player.seek(params['t'])
+ return "ok"
+
+class songs(object):
+ def GET(self):
+
+ playList = graph.value(show, L9['playList'])
+ if not playList:
+ raise ValueError("%r has no l9:playList" % show)
+ songs = list(graph.items(playList))
+
+
+ web.header("Content-type", "application/json")
+ return jsonlib.write({"songs" : [
+ {"uri" : s,
+ "path" : graph.value(s, L9['showPath']),
+ "label" : graph.label(s)} for s in songs]})
+
+class songResource(object):
+ def POST(self):
+ """post a uri of song to switch to (and start playing)"""
+ player.setSong(web.data())
+ return "ok"
+
+def makeApp(thePlayer, theGraph, theShow):
+ global player, graph, show
+ player, graph, show = thePlayer, theGraph, theShow
+
+ urls = ("/", "root",
+ "/time", "timeResource",
+ "/song", "songResource",
+ "/songs", "songs",
+ "/api/position", "timeResource", # old
+ )
+
+ app = web.application(urls, globals(), autoreload=False)
+ return app
diff --git a/static/style.css b/static/style.css
new file mode 100644
--- /dev/null
+++ b/static/style.css
@@ -0,0 +1,9 @@
+.songs button {
+ display: inline-block;
+ width: 300px;
+height: 30px;
+ text-align: left;
+}
+.songs button:hover {
+ background: yellow;
+}
\ No newline at end of file