Thursday, March 20, 2008

GStreamer with Python in Qt (Learning by Example)

When I was getting started with python, my first solution is to buy a book because you have to learn first the fundamentals of the language before writing software. What amazes me about python is that once you learn the basics, you can choose which GUI (Graphical User Interface) toolkit you would like to use. These are GTK (using Glade), Tkinter (which comes with python), wxPython, MFC, and Swing, and of course Qt.

The best way to learn programming is by practice. Therefore, I decided to write a small program that shows a VU meter when music is playing. I decided to use Gstreamer since it is used in Linux, Windows, and Mac OSX.

My goal of writing this blog is to get other people new to Gstreamer, Python, and Qt and help them get started.

First, I would recommend reading PyQt's site to learn how to use Qt in python. Then, read this blog to have an introduction in Gstreamer, and this python tutorial.

Requirements:
1.Python
2.Qt
3.PyQt
4.Gstreamer 0.10 and plug-ins

Here is the source code:
from PyQt4 import QtCore, QtGui
import pygst
import sys, os, time, math
pygst.require("0.10")
import gst
import gobject

#This class runs the code it contains in another thread using QThread
class Player(QtCore.QThread):
def __init__(self):

QtCore.QThread.__init__(self)

def run(self):
#create the pipeline
player = gst.Pipeline("player")
#filesrc element
source = gst.element_factory_make("filesrc", "file-source")
#volume element to adjust volume of audio
volume = gst.element_factory_make("volume", "volume")
#level element to get the rms/peak property
level = gst.element_factory_make("level", "volume-level")
#decoder to play mp3 files
decoder = gst.element_factory_make("mad", "mp3-decoder")
#convert the audio to play to speakers
conv = gst.element_factory_make("audioconvert", "converter")
#autosink if not alsa
sink = gst.element_factory_make("autoaudiosink", "audio-output")

#add the elements to the pipeline
player.add(source, volume, level, decoder, conv, sink)

#link the elements in order
gst.element_link_many(source, decoder, conv, volume, level, sink)
#set properties of elements
player.get_by_name("volume").set_property('volume', 1)
player.get_by_name("volume-level").set_property('peak-ttl' , 0)
player.get_by_name("volume-level").set_property('peak-falloff', 20)
#add bus to listen signal from
bus = gst.Pipeline.get_bus(player)
gst.Bus.add_signal_watch(bus)

#the source of the player
filepath = "the path of your mp3 file"
#set the property of the element filesrc
player.get_by_name("file-source").set_property('location', filepath)
#play the file
player.set_state(gst.STATE_PLAYING)
#get the current thread in Qt
play_thread_id = self.currentThread

#set the minimum decibels
MIN_DB = -45
#set the maximum decibels
MAX_DB = 0
#if current thread is running
while play_thread_id == self.currentThread:
#listen to messages that emit during playing
messagePoll = bus.poll(gst.MESSAGE_ANY,-1)
#if the message is level
if messagePoll.src == level:
#get the structure of the message
struc = messagePoll.structure
#if the structure message is rms
if struc.has_key('rms'):
rms = struc["rms"]
#get the values of rms in a list
rms0 = abs(float(rms[0]))
#compute for rms to decibels
rmsdb = 10 * math.log(rms0 / 32768 )
#compute for progress bar
vlrms = (rmsdb-MIN_DB) * 100 / (MAX_DB-MIN_DB)
#emit the signal to the qt progress bar
self.emit(QtCore.SIGNAL("setLabel"), abs(vlrms))
#set timer
time.sleep(0.05)

#this code produced using pyuic from qt designer
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(QtCore.QSize(QtCore.QRect(0,0,94,300).size()).expandedTo(Dialog.minimumSizeHint()))

self.progressBar = QtGui.QProgressBar(Dialog)
self.progressBar.setGeometry(QtCore.QRect(10,10,31,281))
self.progressBar.setProperty("value",QtCore.QVariant(24))
self.progressBar.setOrientation(QtCore.Qt.Vertical)
self.progressBar.setObjectName("progressBar")
self.progressBar.setValue(0)
self.progressBar.setMinimum(0)
self.progressBar.setMaximum(100)

self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
#sets the value of the progress bar emited
def setLabel(self,value):
self.progressBar.setValue(value)

def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))

if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(window)
window.show()
#creates instance of the Player class
player=Player()
#connect to signal emitted in Player class
QtCore.QObject.connect(player, QtCore.SIGNAL("setLabel"), ui.setLabel, QtCore.Qt.QueuedConnection)
#run the Player class thread
player.start()
app.exec_()

Sunday, January 20, 2008

How To Install Xdebug (PHP Web Server Debugger) In Ubuntu Linux

As I mentioned from my previous blog, a how to in web development in Linux (September 2007), you just download the Eclipse IDE package in Zend. This package contains the zend debugger for debugging PHP scripts, but for a web server, you may use zend or xdebug.

Here is how to install xdebug:
1.In Synaptic: Install php-pear and php5-dev
2.In terminal: #sudo pecl install xdebug
3.Add these 2 lines to php.ini:

zend_extension="(path to xdebug.so)"
xdebug.remote_enable=1

4.In Eclipse, click “debug” icon->Open Debug Dialog->PHP Web Page->New->choose Xdebug in Server Debugger.

That's it!

Saturday, December 29, 2007

How to Convert Standard MIDI files to WAV Audio Format

Applications->Add/Remove Programs->and Install Timidity
from prompt: $timidity [midi_filename].mid -Ow -o [wav_filename].wav

You can also check out the manual: $man timidity
if you want to output to a different format.

Reference: Thanks to Ubuntu Philippine Team especially to Samhain13! :)

Monday, December 17, 2007

How to Install Ubuntu on a USB Flash Drive

Read this link: Live USB Drive,
this: Bootable USB,
and this: Making the USB Persistent

Note: Even it is stated to use ext2 filesystem for casper-rw, I partitioned the disk with ext3 for filesystem use.

Now you have Ubuntu-On-A-Stick! :)

Friday, December 7, 2007

Mplayer: Cannot find codec for audio format 0x56444152

I experienced this problem when playing VCD using command line: $mplayer -zoom -vo x11 -framedrop vcd://1 and it will output this:
--------------------------------------------------------------------
Opening audio decoder: [libdv] Raw DV Audio Decoder
Unknown/missing audio format -> no sound
ADecoder init failed :(
Opening audio decoder: [ffmpeg] FFmpeg/libavcodec audio decoders
Cannot find codec 'dvaudio' in libavcodec...
ADecoder init failed :(
ADecoder init failed :(
Cannot find codec for audio format 0x56444152.
Read DOCS/HTML/en/codecs.html!
Audio: no sound
Starting playback...
V: 0.0 0/ 0 ??% ??% ??,?% 0 0
gnome_screensaver_control()
Exiting... (End of file)
--------------------------------------------------------------------
This could be resolved in two ways:

1. $mplayer -vo x11 -zoom -framedrop vcd://n
where 'n' is the track or chapter (it should be 2 or greater).
-vo x11 is the video output since I'm using vesa driver
-zoom is the scaling of video so I could watch in fullscreen
-framedrop so the video and audio syncs.

2. $mplayer -gui -zoom -vo x11 vcd://n
where 'n' is the track or chapter
-gui the mplayer playback controls will show

This will play the VCD and an gnome-screensaver-control error will show. Ignore the error by clicking ok then right-click on mplayer screen select Open->Play VCD. enjoy! :)

Saturday, December 1, 2007

Adjusting Amarok's Buffer

edit /home/(username)/.kde/share/apps/amarok/xine-config and find the line: #engine buffers_audio_num_buffers:230. Instead of 230, put 10000 then uncomment the line by removing '#'. That's it!

Saturday, October 27, 2007

Just the Other Day...

           Just the other day I was searching every posts in forums on how I could get my blender running since it keeps on crashing on my new laptop. Yeah, I am using Ubuntu GNU/Linux version 7.10- the latest. My first thought was blender uses OpenGL and that is connected to the video card. And since this is the newest laptop around, I guess Ubuntu's latest version didn't have the capability to render correctly on my laptop, but I got graphics though and with a few tweaks, I have desktop effects, which is cool. I can see the driver I am using is Intel's experimental driver. So, I got connected and browsed the forums. Fortunately, I read this post saying that he tried to use the vesa driver instead of intel's. I typed in my console $dpkg -reconfigure xserver-xorg, and chose vesa as my default and restarted my desktop manager. Behold, blender is working perfectly! Sure, 3D acceleration is not available maybe in a month or so still, it's ok.