3 # Copyright 2008 kinta <kinta@communia.org>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # deps= libshout shout2send aumix osso-xterm mplayer
21 from PyQt4 import QtCore
22 from PyQt4 import QtGui
34 stream=["host", "port", "mountpoint", "user", "pw"]
35 sndarch="dsppcmsrc"#"alsasrc"
36 sndarchsink="dsppcmsink"#"alsasink"
37 term="osso-xterm"#"xterm"
38 home_directory = os.popen("echo $HOME").readline()[0:-1]
39 config_directory = home_directory + '/.qice'
40 if os.path.isdir(config_directory):
43 os.popen("mkdir "+config_directory)
44 config_file = config_directory + '/server.cfg'
45 config = ConfigParser.ConfigParser()
46 config.read(config_file)
47 if config.has_section("server"):
48 print("configuracio trobada")
50 print("no te lopcio per tant escribim")
51 config.add_section("server")
52 for index,item in enumerate(stream):
53 config.set("server",item,item)
54 targetwrite=file(config_file,'w')
55 config.write(targetwrite)
59 class MainWindow(QtGui.QMainWindow):
60 def __init__(self, * args):
61 apply(QtGui.QMainWindow.__init__, (self, ) + args)
62 gobject.threads_init()
63 self.vlayout = QtGui.QGridLayout()
65 self.fileMenu = QtGui.QMenu(self.tr("&File"), self)
66 self.quitAction = self.fileMenu.addAction(self.tr("E&xit"))
67 self.editServer = self.fileMenu.addAction(self.tr("Edit c&onnection"))
68 self.mixer = self.fileMenu.addAction(self.tr("&Mixer"))
69 self.menuBar().addMenu(self.fileMenu)
71 self.stream = QtGui.QPushButton("Stream", self)
72 self.dump = QtGui.QPushButton("dump", self)
73 self.monitor = QtGui.QPushButton("Monitor", self)
74 self.record = QtGui.QPushButton("Record", self)
75 self.label = QtGui.QTextEdit("",self)
77 self.label.setReadOnly(True)
78 self.label.setGeometry(10, 100, 361, 141)
79 self.stream.setCheckable(1)
80 self.dump.setCheckable(1)
81 self.monitor.setCheckable(1)
82 self.record.setCheckable(1)
84 self.dump.setEnabled(False)
86 self.vlayout.addWidget(self.stream,0,0,1,1)
87 self.vlayout.addWidget(self.dump,1,0,1,1)
88 #self.vlayout.addSpacing(20)
89 self.vlayout.addWidget(self.monitor,0,1,1,1)
90 self.vlayout.addWidget(self.record,0,2,1,1)
91 self.vlayout.addWidget(self.label,2,0,1,3)
93 self.connect(self.stream, QtCore.SIGNAL("clicked()"), self.streamcon)
94 self.connect(self.dump, QtCore.SIGNAL("clicked()"), self.dumpstream)
95 self.connect(self.monitor, QtCore.SIGNAL("clicked()"), self.monstr)
96 self.connect(self.record, QtCore.SIGNAL("clicked()"), self.recordstr)
97 self.connect(self.quitAction, QtCore.SIGNAL("triggered()"), self.quito)
98 self.connect(self.editServer, QtCore.SIGNAL("triggered()"), self.setserver)
99 self.connect(self.mixer, QtCore.SIGNAL("triggered()"), self.aumixer)
100 central = QtGui.QWidget(self)
101 central.setLayout(self.vlayout)
102 self.setCentralWidget(central)
105 if self.stream.isChecked():
107 self.label.append("connecting")
108 self.server=config.get("server","host")
109 self.port=config.get("server","port")
110 self.mount=config.get("server","mountpoint")
111 self.pw=config.get("server","pw")
112 self.user=config.get("server","user")
113 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)
114 self.audio_pipeline.get_bus().add_watch(self.connectEventos)
115 self.audio_pipeline.set_state(gst.STATE_PLAYING)
116 self.label.append("connected")
117 self.record.setEnabled(False)
118 self.monitor.setEnabled(False)
119 self.dump.setEnabled(True)
120 except gobject.GError, e:
121 self.label.append("No es posible crear la tuberia, " + str(e))
122 self.stream.setChecked(0)
125 self.label.append("disconnecting")
127 self.dump.setChecked(False)
129 self.audio_pipeline.set_state(gst.STATE_NULL)
130 self.label.append("disconnected")
131 self.record.setEnabled(True)
132 self.monitor.setEnabled(True)
133 self.dump.setEnabled(False)
134 except gobject.GError, e:
135 self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
139 if self.monitor.isChecked():
141 self.label.append("monitoring")
142 self.mon_pipeline = gst.parse_launch(sndarch+" !"+sndarchsink)
143 self.mon_pipeline.get_bus().add_watch(self.eventos)
144 self.mon_pipeline.set_state(gst.STATE_PLAYING)
145 self.record.setEnabled(False)
146 self.stream.setEnabled(False)
147 except gobject.GError, e:
148 self.label.append("No es posible crear la tuberia, " + str(e))
149 self.monitor.setChecked(0)
152 self.label.append("disabling monitor")
154 self.mon_pipeline.set_state(gst.STATE_NULL)
155 self.label.append("unmonitoring")
156 self.record.setEnabled(True)
157 self.stream.setEnabled(True)
158 except gobject.GError, e:
159 self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
162 if self.record.isChecked():
163 filename = QtGui.QFileDialog.getSaveFileName(self, 'Where?',home_directory)
164 filename = str(filename)
166 self.label.append("recording")
167 self.rec_pipeline = gst.parse_launch(sndarch+" ! audioconvert ! vorbisenc name=\"enc\" quality=0.10 ! queue ! oggmux name=mux ! queue ! filesink location="+filename)
168 self.rec_pipeline.get_bus().add_watch(self.eventos)
169 self.rec_pipeline.set_state(gst.STATE_PLAYING)
170 self.stream.setEnabled(False)
171 self.monitor.setEnabled(False)
172 except gobject.GError, e:
173 self.label.append("No es posible crear la tuberia, " + str(e))
174 self.record.setChecked(0)
177 self.label.append("stop recording")
179 self.rec_pipeline.set_state(gst.STATE_NULL)
180 self.label.append("stoped")
181 self.stream.setEnabled(True)
182 self.monitor.setEnabled(True)
183 except gobject.GError, e:
184 self.label.append("No es posible canviar a estat nul la tuberia, " + str(e))
188 def alert(self, msg):
189 QtGui.QMessageBox.critical(self, 'CRITICAL', msg, QtGui.QMessageBox.Ok)
190 def pregunta(self, msg):
191 pregunta=QtGui.QMessageBox.question(self, 'ATENCIO', msg, QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
192 #resposta=pregunta.exec()
197 def quito(self,**kwargs):
199 def setserver(self,**kwargs):
200 os.popen2(term+" -e \"nano ~/.qice/server.cfg\"")
201 config.read(config_file)
202 def aumixer(self,**kwargs):
204 def eventos(self, bus, msg):
205 #DEBUG = print(str(msg)+" "+str(msg.type))
207 if t == gst.MESSAGE_UNKNOWN:
208 e, d = msg.parse_error()
209 self.label.append("CONNECT ERROR: "+e)
210 if t == gst.MESSAGE_ERROR:
211 e, d = msg.parse_error()
212 self.label.append("ERROR: "+e)
214 def connectEventos(self, bus, msg):
215 #DEBUG = print(str(msg)+" "+str(msg.type))
217 if t == gst.MESSAGE_UNKNOWN:
218 e, d = msg.parse_error()
219 self.label.append("CONNECT ERROR: "+e)
220 if t == gst.MESSAGE_ERROR:
221 e, d = msg.parse_error()
222 self.label.append("ERROR: "+e)
223 self.stream.setChecked(False)
226 def dumpstream(self):
227 if self.dump.isChecked():
228 self.server=config.get("server","host")
229 self.port=config.get("server","port")
230 self.mount=config.get("server","mountpoint")
231 self.pw=config.get("server","pw")
232 self.user=config.get("server","user")
233 filename = QtGui.QFileDialog.getSaveFileName(self, 'Where?',home_directory)
234 self.filename = str(filename)
235 self.label.append("dumping")
236 mplayer=os.popen2( term+" -e \"mplayer http://"+self.server+":"+self.port+"/"+self.mount+" -dumpstream -dumpfile "+self.filename+" && sleep 2\"")[1].readline()
239 pidofmp=os.popen2("pidof mplayer")[1].readline()
241 os.popen2("kill -15 `pidof mplayer`")
245 app=QtGui.QApplication(args)
248 win.setWindowTitle("Qice")
249 app.connect(app, QtCore.SIGNAL("lastWindowClosed()")
251 , QtCore.SLOT("quit()")
255 if __name__=="__main__":