Create  Edit  FrontPage  Index  Search  Changes  History  RSS  Back  Login

tut-gst-helloworld Diff - Ruby-GNOME2 Project Website

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

= Hello World
{{link("tut-gst-elements-state", nil, "tut-gst", "tut-gst-helloworld-conclusion")}}

We will create a simple first application, a complete MP3 player, using standard GStreamer components. The player will read from a file that is given as the first argument to the program.

== The code

  #!/usr/bin/ruby -w
  

  require 'gst'

  Gst.init
  
  unless ARGV.length == 1
    $stderr.puts "Usage: #{__FILE__} <mp3 filename>"
    exit 1
  end

  
  # create a new pipeline to hold the elements
  pipeline = Gst::Pipeline.new

  
  # create a disk reader
  filesrc = Gst::ElementFactory.make("filesrc")
  filesrc.location = ARGV.first

  
  # now it's time to get the decoder
  decoder = Gst::ElementFactory.make("mad")

  
  # and an audio sink
  audiosink = Gst::ElementFactory.make("osssink")

Gst::ElementFactory.make("autoaudiosink")
  

  # add objects to the main pipeline
  pipeline.add(filesrc, decoder, audiosink)

  
  # link elements
  filesrc >> decoder >> audiosink

  
  # create the program's main loop
  loop = GLib::MainLoop.new(nil, false)
  
  # listen to playback events
  bus = pipeline.bus
  bus.add_watch do |bus, message|
    case message.type
    when Gst::Message::EOS
      loop.quit
    when Gst::Message::ERROR
      p message.parse
      loop.quit
    end
    true
  end
  

  # start playing
  pipeline.play
  begin
    loop.run

  while pipeline.iterate do end

  # stop the pipeline
rescue Interrupt
  ensure
    
pipeline.stop
  end


== The Code Explained

Let's go through this example step by step.

The first thing you have to do is to require the Ruby/GStreamer library and initialize the framework.library.

  require 'gst'
  Gst.init
  ...

We are going to create an empty pipeline. As you have seen in the basic introduction, this pipeline will hold and manage all the elements we are going to pack into it.

  ...
  # create a new pipeline to hold the elements
  pipeline = Gst::Pipeline.new
  ...

We use the standard constructor for a pipeline: Gst::Pipeline.new.

We then create a disk source element. The disk source element is able to read from a file. We use the standard GLib::Object property mechanism to set a property of the element: the file to read from.

  ...
  # create a disk reader
  filesrc = Gst::ElementFactory.make("filesrc")
  filesrc.location = ARGV.first
  ...
  
((*Note*)) You can check if filesrc.nil? to verify the creation of the disk source element.

We now create the MP3 decoder element. This assumes that the 'mad' plugin is installed on the system where this application is executed.

  ...
  # now it's time to get the decoder
  decoder = Gst::ElementFactory.make("mad")
  ...

Gst::ElementFactory.make may take two arguments: a string that will identify the element you need and a second argument: how you want to name the element. The name of the element is something you can choose yourself and might be used to retrieve the element from a bin/pipeline.  Here we choose to not provide a name for the element, it means that GStreamer will automatically generate a name for us.

Finally we create our audio sink element. This element will be able to play back the audio using OSS.whatever sound system is available.

  ...
  # and an audio sink
  audiosink = Gst::ElementFactory.make("osssink")Gst::ElementFactory.make("autoaudiosink")
  ...

We then add the elements to the pipeline.

  ...
  # add objects to the main pipeline
  pipeline.add(filesrc, decoder, audiosink)
  ...

We link the different pads of the elements together like this:

  ...
  # link elements
  filesrc >> decoder >> audiosink
  ...

We now have a created a complete pipeline. We can visualise the pipeline as follows:

{{image_left("hello-world.png")}}
{{br}}

To know when the pipeline is done playing, or if an error occurs, we need to listen to events and handle them:

  ...
  # listen to playback events
  bus = pipeline.bus
  bus.add_watch do |bus, message|
    case message.type
    when Gst::Message::EOS
      loop.quit
    when Gst::Message::ERROR
      p message.parse
      loop.quit
    end
    true
  end
  ...

Everything is now set up to start streaming. We use the following statements to change the state of the pipeline:

  ...
  # start playing
  pipeline.play
  ...

((*Note*)) GStreamer will take care of the READY and PAUSED state for you when going from NULL to PLAYING.

Since we do not use threads, nothing will happen yet. We have to call Gst::Bin#iterate to execute one iteration of start the pipeline.main loop that we created earlier:

  ...
  while pipeline.iterate do endbegin
    loop.run

  ...

The Gst::Bin#iterate method will return true as long as something interesting happened inside the pipeline. When the end-of-file has been reached the Gst::Bin#iterate method will return false and we can end the loop.

rescue Interrupt
  ensure
    pipeline.stop
  end

  ...
  # stop the pipeline
  pipeline.stop

((*Note*)) Don't forget to stop the pipeline after use.  This will free all of the resources held by the elements.

== Running Hello World

Just save the code in a file named (({helloworld.rb})) and do:

  ruby helloworld.rb foo.mp3