subscribe
Tags:
 
2010
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
Posts Tagged 'Gstreamer'
2010-04-01
Since not everyone want to read a bunch of pointless April fools crap postings on the internets, and just in time to probably fail to compile with the latest version of Vala, I have a new little project written in Vala!

Quite a while ago, I made a basic metronome application and named it hubcap in honor of Linux Outlaws host Dan Lynch. Anyone that has ever heard me play music knows just how much I really need a metronome, but that is beyond the point, and I promise that this won't be some pointless April 1st crap.

Fortunately, the Linux Outlaws has two hosts and I had a yearning to hack code and process data.

Say hello to Shnerkel!
Shnerkel is an aggregator and player of the Linux Outlaws ogg feed. Sauce: shnerkel.tar.gz


--Requirments--
gstreamer-0.10
gtk+-2.0
webkit-1.0
libxml-2.0
Vala ( for compiling )

The main impetus for creating this application was to play with webkit in Vala. As I see it, there are a few bonus results of creating this app.

1. Since the app plays the ogg version of the Linux Outlaws audcast, the statics for numbers of downloads of the mp3 and ogg versions will hopefully tip towards ogg.

2. It is a fairly easy way to increase the expose of Linux Outlaws and Ogg, although I'm probably preaching to the choir on both accounts.

3. Almost a full dozen people will have something real to read on April 1st.

The Good
With shnerkel, there is no more waiting to download the audcast. The audio file is streamed over HTTP by the gstreamer library. Shnerkel uses the same audio player class as sap, which really cut down on development time. Thanks Open Source.

The Bad
You will notice the lack of a progress bar. For some reason gstreamer doesn't return the duration of an ogg file being played over HTTP. What the hell is up with that? It is either a problem with Gstreamer or a problem with the Ogg format.

The Ugly
plenty. Before you complain, go look in the mirror. Oh snap! You got burned by that one! In the appwindow.vala file, I pull information from a GTK TreeStore as follows:
string description=""; string file=""; tree_selection = tv.get_selection(); tree_selection.get_selected(out model, out iter); episodeTreeStore.get(iter,3,&description,2,&file,-1);
It seems to me that passing 'description' and 'file' to the function as references is rather un-vala like and the function should instead use 'out' to pass data to the strings. Oh well...

It's almost midnight, but I don't think I'll stay up and write the first page of my movie script for the ScriptFrenzy challenge.


Now quit reading, and go find the elusive Dirk Shnerkelberger.
Comments
Jezra, do you have any plans to package this into an RPM? I would love to include this in BrownHat. (we would also welcome any of your other software, it is for the Outlaws by the Outlaws afterall)
jezra:
No, I will not be making an RPM. What I will do, is put the code on launchpad and improve the build system so that it will be easier for others to make distro specific packages.
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
2 plus 9
Answer:
required
2008-05-23
When creating audio file playing software, it is nice to be able to access the tags of the audio files for display to the user. Since I am planning to use gstreamer to handle the playing of audio in my Luma project, I thought it would be best to make a very simple test app to handle the retrieval of tags from an audio file. Actually, I still need to test this with the various filetypes that gstreamer supports; specifically vorbis files. Anyway, on with the show.

#!/usr/bin/env python
import os
import sys
import gst
import gobject

class tag_getter:
def __init__(self):
#make a dictionary to hold our tag info
self.file_tags = {}
#make a playbin to parse the audio file
self.pbin = gst.element_factory_make("playbin")
#we need to receive signals from the playbin's bus
self.bus = self.pbin.get_bus()
#make sure we are watching the signals on the bus
self.bus.add_signal_watch()
#what do we do when a tag is part of the bus signal?
self.bus.connect("message::tag", self.bus_message_tag)
#create a loop to control our app
self.mainloop = gobject.MainLoop()

def bus_message_tag (self, bus, message):
#we received a tag message
taglist = message.parse_tag()
#put the keys in the dictionary
for key in taglist.keys():
self.file_tags[key] = taglist[key]
#for this test, if we have the artist tag, we can quit
if self.file_tags['artist']:
print self.file_tags
sys.exit()

def set_file(self,file):
#set the uri of the playbin to our audio file
self.pbin.set_property("uri","file://"+file)
#pause the playbin, we don't really need to play
self.pbin.set_state(gst.STATE_PAUSED)

def run(self):
#start the main loop
self.mainloop.run()

if __name__=="__main__":
if len(sys.argv)>1:
file = sys.argv[1]
pwd = os.getcwd()
filepath = os.path.join(pwd,file)
getter = tag_getter()
getter.set_file(file)
getter.run()

else:
print "select an audio file"


Useful? Not really, but it certainly is a good building block for a more advanced application.
Comments
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
6 plus 9
Answer:
required
  • Tags:
  • Python
  • Gstreamer
2008-05-22
In preparation for my Luma media player, I wanted to create a simple audio player with visualization. Based upon what I have read, this would require a "tee" when using gstreamer. The tee in gstreamers is much like a tee in piped shell commands; data gets copied at the tee and travels in multiple directions. In gstreamer, one needs to create a queue for each new direction that the data will flow down in the pipeline.

It took me a while to wrangle with the tee requirements for handling queues. I could see how, but I couldn't understand why. So anyway, this is what I came up with:
1. a tee in the pipeline gets a name
2. the end of a queue gets declared as part of the tee, and is given the name of the tee followed by a period
3. add a queue to the gstreamer pipeline
4. the end of the queue thingy gets placed at the end of the queues ( this doesn't seem to be required for the last queue)

My gstreamer pipeline looks like this:
#!/bin/sh
gst-launch
filesrc location=/path/to/audio/file
! decodebin ! audioconvert
! tee name=myT myT.
! queue ! autoaudiosink myT.
! queue ! goom ! ffmpegcolorspace ! autovideosink


sweet! Now on to a my pythonic version using pygst
#!/usr/bin/env python

import sys
import gst
import time
class myPlayer ():
def __init__(self):
self.pipeline = gst.Pipeline()
self.src = gst.element_factory_make("filesrc", "src")
self.decoder = gst.element_factory_make("decodebin", "decoder")
self.decoder.connect("new-decoded-pad", self.onNewDecodedPad)
self.goom = gst.element_factory_make("goom")
self.colorspace = gst.element_factory_make("ffmpegcolorspace","color")
self.conv = gst.element_factory_make("audioconvert", "conv")
self.vidsink = gst.element_factory_make("autovideosink","videosink")
self.asink = gst.element_factory_make("autoaudiosink", "aoutput")
self.tee = gst.element_factory_make('tee', "tee")
self.queuea = gst.element_factory_make("queue", "queuea")
self.queuev = gst.element_factory_make("queue", "queuev")
self.pipeline.add(self.src,self.decoder,self.conv,self.tee,self.queuea)
self.pipeline.add(self.asink,self.queuev,self.goom, self.colorspace, self.vidsink)
gst.element_link_many(self.src,self.decoder)
gst.element_link_many(self.conv,self.tee)
self.tee.link(self.queuea)
self.queuea.link(self.asink)
self.tee.link(self.queuev)
gst.element_link_many(self.queuev, self.goom,self.colorspace, self.vidsink)
def onNewDecodedPad(self,decodebin, pad, islast):
#link the pad to the converter
decodebin.link(self.conv)

def playfile(self,file):
self.src.set_property('location', file)
self.pipeline.set_state(gst.STATE_PLAYING)
pipelinestate = self.pipeline.get_state()

while pipelinestate[1] == gst.STATE_PLAYING:
time.sleep(1)
pipelinestate = self.pipeline.get_state()
sys.exit()

if __name__ == '__main__':
if (len(sys.argv) > 1):
file = sys.argv[1]
player = myPlayer()
player.playfile(file)
else:
print "you must select a tune"


The big difference here, at least to me, is that the decodebin isn't really a bin, but it represents a series of possible bins. So if one where to select a vorbis file to play, the decodebin will determine the correct type of bin needed to handle the file and would create an instance of that type of bin, the same is true for wav,flac,aac,mp3, etc; all of which have a specific decoder that I don't want to have to figure out, so I let the decodebin do it for me. This line: self.decoder.connect("new-decoded-pad", self.onNewDecodedPad), will call a function whenever a new bin is created by the decoder bin and it is in the onNewDecodedPad function that the decodebin links to the rest of the pipeline. Does that make sense?
Comments
Thanks for the example. There is one minor typo...

"self.popeline.add" should be "self.pipeline.add"
Thanks for the catch! The code has been updated.
Thanks for the great example - I spent an hour trying to fit a pipeline for goom... You saved me :-)
Now this works on my...drumroll...Nokia N900! Maemo forever :-)
That is awesome Tom! I've always wanted to how well gstreamer runs on ARM based systems.
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
0 plus 6
Answer:
required
  • Tags:
  • Python
  • Gstreamer