+#!/usr/bin/python
+# qice.py
+# Copyright 2008 kinta <kinta@communia.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+# deps= libshout shout2send aumix osso-xterm mplayer
+import sys
+from PyQt4 import QtCore
+from PyQt4 import QtGui
+import os
+import subprocess
+import pygst
+pygst.require('0.10')
+import gst
+import gst.interfaces
+import ConfigParser
+#
+import gobject
+#
+
+stream=["host", "port", "mountpoint", "user", "pw"]
+sndarch="dsppcmsrc"#"alsasrc"
+sndarchsink="dsppcmsink"#"alsasink"
+term="osso-xterm"#"xterm"
+home_directory = os.popen("echo $HOME").readline()[0:-1]
+config_directory = home_directory + '/.qice'
+if os.path.isdir(config_directory):
+ pass
+else:
+ os.popen("mkdir "+config_directory)
+config_file = config_directory + '/server.cfg'
+config = ConfigParser.ConfigParser()
+config.read(config_file)
+if config.has_section("server"):
+ print("configuracio trobada")
+else:
+ print("no te lopcio per tant escribim")
+ config.add_section("server")
+ for index,item in enumerate(stream):
+ config.set("server",item,item)
+ targetwrite=file(config_file,'w')
+ config.write(targetwrite)
+ targetwrite.close()
+
+
+class MainWindow(QtGui.QMainWindow):
+ def __init__(self, * args):
+ apply(QtGui.QMainWindow.__init__, (self, ) + args)
+ gobject.threads_init()
+ self.vlayout = QtGui.QGridLayout()
+
+ self.fileMenu = QtGui.QMenu(self.tr("&File"), self)
+ self.quitAction = self.fileMenu.addAction(self.tr("E&xit"))
+ self.editServer = self.fileMenu.addAction(self.tr("Edit c&onnection"))
+ self.mixer = self.fileMenu.addAction(self.tr("&Mixer"))
+ self.menuBar().addMenu(self.fileMenu)
+
+ self.stream = QtGui.QPushButton("Stream", self)
+ self.dump = QtGui.QPushButton("dump", self)
+ self.monitor = QtGui.QPushButton("Monitor", self)
+ self.record = QtGui.QPushButton("Record", self)
+ self.label = QtGui.QTextEdit("",self)
+
+ self.label.setReadOnly(True)
+ self.label.setGeometry(10, 100, 361, 141)
+ self.stream.setCheckable(1)
+ self.dump.setCheckable(1)
+ self.monitor.setCheckable(1)
+ self.record.setCheckable(1)
+
+ self.dump.setEnabled(False)
+
+ self.vlayout.addWidget(self.stream,0,0,1,1)
+ self.vlayout.addWidget(self.dump,1,0,1,1)
+ #self.vlayout.addSpacing(20)
+ self.vlayout.addWidget(self.monitor,0,1,1,1)
+ self.vlayout.addWidget(self.record,0,2,1,1)
+ self.vlayout.addWidget(self.label,2,0,1,3)
+
+ self.connect(self.stream, QtCore.SIGNAL("clicked()"), self.streamcon)
+ self.connect(self.dump, QtCore.SIGNAL("clicked()"), self.dumpstream)
+ self.connect(self.monitor, QtCore.SIGNAL("clicked()"), self.monstr)
+ self.connect(self.record, QtCore.SIGNAL("clicked()"), self.recordstr)
+ self.connect(self.quitAction, QtCore.SIGNAL("triggered()"), self.quito)
+ self.connect(self.editServer, QtCore.SIGNAL("triggered()"), self.setserver)
+ self.connect(self.mixer, QtCore.SIGNAL("triggered()"), self.aumixer)
+ central = QtGui.QWidget(self)
+ central.setLayout(self.vlayout)
+ self.setCentralWidget(central)
+
+ def streamcon(self):
+ if self.stream.isChecked():
+ try:
+ self.label.append("connecting")
+ self.server=config.get("server","host")
+ self.port=config.get("server","port")
+ self.mount=config.get("server","mountpoint")
+ self.pw=config.get("server","pw")
+ self.user=config.get("server","user")
+ self.audio_pipeline = gst.parse_launch(sndarch+" ! audioconvert ! vorbisenc name=\"enc\" quality=0.10 ! queue ! oggmux name=mux ! queue ! shout2send ip="+self.server+" port="+self.port+" password="+self.pw+" mount=/"+self.mount)
+ self.audio_pipeline.get_bus().add_watch(self.connectEventos)
+ self.audio_pipeline.set_state(gst.STATE_PLAYING)
+ self.label.append("connected")
+ self.record.setEnabled(False)
+ self.monitor.setEnabled(False)
+ self.dump.setEnabled(True)
+ except gobject.GError, e:
+ self.label.append("No es posible crear la tuberia, " + str(e))
+ self.stream.setChecked(0)
+ return -1
+ else:
+ self.label.append("disconnecting")
+ try:
+ self.dump.setChecked(False)
+ self.dumpstream()
+ self.audio_pipeline.set_state(gst.STATE_NULL)
+ self.label.append("disconnected")
+ self.record.setEnabled(True)
+ self.monitor.setEnabled(True)
+ self.dump.setEnabled(False)
+ except gobject.GError, e:
+ self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
+ return -1
+
+ def monstr(self):
+ if self.monitor.isChecked():
+ try:
+ self.label.append("monitoring")
+ self.mon_pipeline = gst.parse_launch(sndarch+" !"+sndarchsink)
+ self.mon_pipeline.get_bus().add_watch(self.eventos)
+ self.mon_pipeline.set_state(gst.STATE_PLAYING)
+ self.record.setEnabled(False)
+ self.stream.setEnabled(False)
+ except gobject.GError, e:
+ self.label.append("No es posible crear la tuberia, " + str(e))
+ self.monitor.setChecked(0)
+ return -1
+ else:
+ self.label.append("disabling monitor")
+ try:
+ self.mon_pipeline.set_state(gst.STATE_NULL)
+ self.label.append("unmonitoring")
+ self.record.setEnabled(True)
+ self.stream.setEnabled(True)
+ except gobject.GError, e:
+ self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
+ return -1
+ def recordstr(self):
+ if self.record.isChecked():
+ filename = QtGui.QFileDialog.getSaveFileName(self, 'Where?',home_directory)
+ filename = str(filename)
+ try:
+ self.label.append("recording")
+ self.rec_pipeline = gst.parse_launch(sndarch+" ! audioconvert ! vorbisenc name=\"enc\" quality=0.10 ! queue ! oggmux name=mux ! queue ! filesink location="+filename)
+ self.rec_pipeline.get_bus().add_watch(self.eventos)
+ self.rec_pipeline.set_state(gst.STATE_PLAYING)
+ self.stream.setEnabled(False)
+ self.monitor.setEnabled(False)
+ except gobject.GError, e:
+ self.label.append("No es posible crear la tuberia, " + str(e))
+ self.record.setChecked(0)
+ return -1
+ else:
+ self.label.append("stop recording")
+ try:
+ self.rec_pipeline.set_state(gst.STATE_NULL)
+ self.label.append("stoped")
+ self.stream.setEnabled(True)
+ self.monitor.setEnabled(True)
+ except gobject.GError, e:
+ self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
+ return -1
+
+
+ def alert(self, msg):
+ QtGui.QMessageBox.critical(self, 'CRITICAL', msg, QtGui.QMessageBox.Ok)
+ def pregunta(self, msg):
+ pregunta=QtGui.QMessageBox.question(self, 'ATENCIO', msg, QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
+ #resposta=pregunta.exec()
+ if pregunta == 1024:
+ return "OK"
+ else :
+ return "Cancel"
+ def quito(self,**kwargs):
+ self.close()
+ def setserver(self,**kwargs):
+ os.popen2(term+" -e \"nano ~/.qice/server.cfg\"")
+ config.read(config_file)
+ def aumixer(self,**kwargs):
+ os.popen2("aumix")
+ def eventos(self, bus, msg):
+ #DEBUG = print(str(msg)+" "+str(msg.type))
+ t = msg.type
+ if t == gst.MESSAGE_UNKNOWN:
+ e, d = msg.parse_error()
+ self.label.append("CONNECT ERROR: "+e)
+ if t == gst.MESSAGE_ERROR:
+ e, d = msg.parse_error()
+ self.label.append("ERROR: "+e)
+ return True
+ def connectEventos(self, bus, msg):
+ #DEBUG = print(str(msg)+" "+str(msg.type))
+ t = msg.type
+ if t == gst.MESSAGE_UNKNOWN:
+ e, d = msg.parse_error()
+ self.label.append("CONNECT ERROR: "+e)
+ if t == gst.MESSAGE_ERROR:
+ e, d = msg.parse_error()
+ self.label.append("ERROR: "+e)
+ self.stream.setChecked(False)
+ self.streamcon()
+ return True
+ def dumpstream(self):
+ if self.dump.isChecked():
+ self.server=config.get("server","host")
+ self.port=config.get("server","port")
+ self.mount=config.get("server","mountpoint")
+ self.pw=config.get("server","pw")
+ self.user=config.get("server","user")
+ filename = QtGui.QFileDialog.getSaveFileName(self, 'Where?',home_directory)
+ self.filename = str(filename)
+ self.label.append("dumping")
+ mplayer=os.popen2( term+" -e \"mplayer http://"+self.server+":"+self.port+"/"+self.mount+" -dumpstream -dumpfile "+self.filename+" && sleep 2\"")[1].readline()
+
+ else:
+ pidofmp=os.popen2("pidof mplayer")[1].readline()
+ if pidofmp!="":
+ os.popen2("kill -15 `pidof mplayer`")
+
+
+def main(args):
+ app=QtGui.QApplication(args)
+ win=MainWindow()
+ win.show()
+ win.setWindowTitle("Qice")
+ app.connect(app, QtCore.SIGNAL("lastWindowClosed()")
+ , app
+ , QtCore.SLOT("quit()")
+ )
+ app.exec_()
+
+if __name__=="__main__":
+ main(sys.argv)