Since a long ago I'm looking for a media player for listening my music. In that aspect I'm really exigent. Is not that I need lots of plugins and eye candy, no, I just need a media player that fits my way to listen music.
How do I listen to music? All day long, for starters. I have a
collection of .ogg files, which I normally listen in
random mode. From time to time I want to listen certain song, so I
either queue it or simply stop the current one and start the one I
want. Sometimes I enqueue several songs, which might not be related
between them (maybe only in my head they are).
I've been using Amarok, I really like its random
albums feature; that is, I listen to a whole album, and when it
finishes, another album is picked at random and I listen to all its
songs. The last feature, a really important one: My collection is
my playlist and viceversa. I don't build playlists; if I want to
listen to certain songs I just queue them. One feature I like also
is a tag editor and the posibility to rearrange the songs based on
its tags (with support for albums with songs from various authors,
like OST's). Last but no least, reacting to new files in the
collection is also well regarded.
I used to use xmms. I still think it's a very good
player for me, but it lacks utf support and doesn't react when I
add songs to the collection. Then I used Amarok,
Juk, QuodLibet, Audacious (I
was using it up to today) and probably a couple more. None of them
support all the features, so today, completely tired of this
situation, I started writing my own. I called it
Satyr. Another reason to do it is to play a little
more with PyKDE. Talking about Python and
KDE, I know the existence of minirok, but
it uses GStreamer, and I wanted to play with
Phonon.
So, what's different in this media player? If you think about it, if you have a CD (vinyl, cassettes maybe?) collection in your home, what you have is exactly that: a collection of Albums. Most media players manage Songs, grouping them in Albums and by Author too. Notably Amarok used to manage Albums with several artists (what's called a 'Various artists' Album), but since Amarok 2 it doesn't do it anymore, nor the queuing works. So the basic idea is exactly that: you have a Collection of Albums, most of them with songs from the same Author (and sometimes Featuring some other Authors[1]), but sometimes with Songs from different Authors. Of course I will try to implement all the features I mentioned above.
Ok, enough introduction. This post was aimed to show some code, and that's what I'm going to do now. This afternoon I was testing the Phonon Python bindings, trying to make a script to play a simple file. This snippet works:
# qt/kde related
from PyKDE4.kdecore import KCmdLineArgs, KAboutData, i18n, ki18n
from PyKDE4.kdeui import KApplication
# from PyKDE4.phonon import Phonon
from PyQt4.phonon import Phonon
from PyQt4.QtCore import SIGNAL
media= Phonon.MediaObject ()
ao= Phonon.AudioOutput (Phonon.MusicCategory, app)
print ao.outputDevice ().name ()
Phonon.createPath (media, ao)
media.setCurrentSource (Phonon.MediaSource ("/home/mdione/test.ogg")
media.play ()
app.connect (media, SIGNAL("finished ()"), app.quit)
app.exec_ ()
Of course, this must be preceded by the bureaucratic creation of
a KApplication, but it basically plays an ogg file and
quits. You just have to define a MediaObject as the
source, an AudioOutput as the sink, and then you
createPath between them. As you can see, with Phonon
you don't even have to worry about where the output will be going:
that is defined by the system/user configuration. You only have to
declare that your AudioOutput is going to play Music
(the second actual line of code).
There are a couple of peculiarities with the Python
bindings. First of all, Phonon comes both with Qt and
separately. The separate one has a binding in the
PyKDE4 package, but it seems that it doesn't work very
well, so I used the PyQt binding. For that, I had to
install the python-pyqt4-phonon package. Second, the
bindings don't support to call setCurrentSource() with
a string; you have to wrap it in a MediaSource. The
original API supports it. Third, it seems that
Phonon.createPlayer() is not supported by the bindings
either, so I had to build the AudioOutput by hand. I
don't care, it's just a couple lines more.
This code also shows the name of the selected
OutputDevice. I my machine it shows HDA Intel
(STAC92xx Analog).
In the following days I'll be posting more info about what comes out of this project. I will only reveal that right now the code has classes called Player, PlayList and Collection. It can scan a Collection from a path given in the command line and play all the files found there. Soon more features will come.
[1] I'm not planing to do anything about it... yet.