Python ogg converter

Code junkies hangout here

Moderators: ChrisThornett, LXF moderators

Python ogg converter

Postby LGLudd » Wed Oct 19, 2011 3:31 pm

I have been attempting to follow Nicks python tutorials in the magazine and thought I would have have gone off at a bit of a tangent from the latest one which amongst other things shows you how to play music files using gst.

Anyway, I thought it would be fun to attempt to write a small app to convert music files to mp3 format for my wife so she can load my ogg files onto her ipod.

Unfortunately I have fallen at pretty much the first hurdle in that I cannot get my conversion process to work.

from the command line I can run:
Code: Select all
gst-launch -v filesrc location=HappyShopper.ogg ! decodebin ! audioconvert ! audioresample ! lame bitrate=192 ! id3v2mux ! filesink location=music.mp3

and it converts fine, but putting this in a script either as:
Code: Select all
import gobject, gst

converter = gst.parse_launch('filesrc location="HappyShopper.ogg" ! decodebin ! audioconvert ! audioresample ! lame bitrate=192 ! id3v2mux ! filesink location="happyshopper.mp3"')
converter.set_state(gst.STATE_PLAYING)

gobject.threads_init()
gobject.MainLoop().run()

or
Code: Select all
import gobject, gst

converter = gst.Pipeline('converter')

source = gst.element_factory_make('filesrc')
source.set_property('location','HappyShopper.ogg')

decoder = gst.element_factory_make('vorbisdec')
convert = gst.element_factory_make('audioconvert')
resample=gst.element_factory_make('audioresample')

encoder = gst.element_factory_make('lame')
encoder.set_property('bitrate',192)

id3tag=gst.element_factory_make('id3v2mux')

sink = gst.element_factory_make('filesink')
sink.set_property('location','HappyShopper.mp3')

converter.add(source,decoder,convert,resample,encoder,id3tag,sink)
gst.element_link_many(source,decoder,convert,resample,encoder,id3tag,sink)

gobject.threads_init()
gobject.MainLoop().run()

just returns the message:
** Message: pygobject_register_sinkfunc is deprecated (GstObject)

I have searched and found suggestions that it could be the pygobject package that is out of date (I am using version 2.21.5) but this is the most recent one available to me on Fedora 14 I also came across a posting with a very similar issue that then followed up their own post with a comment that the version was not the problem but a fault in the posters original code (however there was no explanation of what the fault was).

Can anyone please help?

Thanks
Leo
LGLudd
 
Posts: 8
Joined: Sat Oct 15, 2011 10:50 am

Fixed

Postby LGLudd » Fri Oct 21, 2011 9:44 am

ok, after much heartache I have fixed this (with help from google and a shove in the right direction from the #python irc channel)

The previous comment I found about the warning not being the issue was correct

There were two problems with the code above.

Firstly the code was not actually converting the music file as (I think) it was not ready to join the elements together correctly.

This was remedied by creating a demux element (I don't know why this is required for an audio only file) and monitoring it for the pad-added signal at which point it would be linked to the decoder element.
The elements are linked in two stages to account for this.

The other issue was that the MainLoop was never being terminated and so the code was never completing cleanly.

This was fixed by creating a bus object for the converter pipeline object and monitoring the messages for the MESSAGE_EOS signal and then terminating the MainLoop from there.

I switched to using gtk instead of gobject in an attempt to get rid of the deprecated message (this did not work) and because the example code I found on the pygst tutorial :oops:

Anyway, just in case anyone is interested the code is now as follows:
Code: Select all
import gst
import gtk

class OggConvert():

    def __init__(self):
        self.converter = gst.Pipeline('converter')
       
        source = gst.element_factory_make('filesrc')
        source.set_property('location','/home/user/Music/HappyShopper.ogg')
       
        demuxer = gst.element_factory_make("oggdemux", "demuxer")
        demuxer.connect("pad-added", self.demuxer_callback)

        self.decoder = gst.element_factory_make('vorbisdec')
        convert = gst.element_factory_make('audioconvert')
        resample=gst.element_factory_make('audioresample')
       
        encoder = gst.element_factory_make('lame')
        encoder.set_property('bitrate',192)
       
        id3tag=gst.element_factory_make('id3v2mux')
       
        sink = gst.element_factory_make('filesink')
        sink.set_property('location','/home/user/Music/converted.mp3')
       
       
        self.converter.add(source,demuxer,self.decoder,convert,resample,encoder,id3tag,sink)
        gst.element_link_many(source,demuxer)
        gst.element_link_many(self.decoder,convert,resample,encoder,id3tag,sink)
       
        bus = self.converter.get_bus()
        bus.add_signal_watch()
        bus.connect("message", self.on_message)

        self.converter.set_state(gst.STATE_PLAYING)

    def on_message(self,bus,message):
        t = message.type
        if t == gst.MESSAGE_EOS:
            self.converter.set_state(gst.STATE_NULL)
            gtk.main_quit()
        elif t == gst.MESSAGE_ERROR:
            self.converter.set_state(gst.STATE_NULL)
        else:
            print message

    def demuxer_callback(self, demuxer, pad):
        adec_pad = self.decoder.get_pad("sink")
        pad.link(adec_pad)
       
def main():
    gtk.gdk.threads_init()
    gtk.main()

if __name__ == "__main__":
    OggConvert()
    main()

This is now going to be extended to take parameters defining the track to convert and its destination as well as using it to convert a whole list of tracks selected by a user from a gui frontend.

Leo
LGLudd
 
Posts: 8
Joined: Sat Oct 15, 2011 10:50 am

Postby evilnick » Sat Jan 07, 2012 11:27 pm

nice work. Sorry I have not been hanging around in the forums so much or I could have helped you out - but it looks like you did an excellent job on your own!
User avatar
evilnick
Moderator
 
Posts: 151
Joined: Mon Apr 04, 2005 11:47 am
Location: LXF towers


Return to Programming

Who is online

Users browsing this forum: Exabot [Bot] and 1 guest