What is the correct way to recover from an error during gapless playback?

lev lev.zelenskiy at nokia.com
Tue Jun 5 17:42:06 PDT 2012


Hi,
I'm trying to implement gapless playback for audio files using playbin2.
It works well when all files are valid, but there's a problem processing
invalid files.
I receive an error message about file being invalid, but then I'm not sure
what I need to do to continue playback with other files.
I'm trying to reset playbin state to NULL and then change the uri to a new
file, but I keep getting error messages for the old invalid file, and
playback doesn't resume after I set playbin back to PLAYING state.

Here's a sample python script:

validfile = "file://" + os.path.abspath("test_tone.wav") # using
uncompressed PCM
invalidfile = "file://" + os.path.abspath("invalid")

class Player:
    restarted = 0

    def __init__(self, filename):
        self.filename = filename
        
        #this only works with playbin2
        self.player = gst.element_factory_make("playbin2", "player")
        self.player.set_property("uri", filename)
        self.player.set_property("audio-sink",
gst.element_factory_make("pulsesink", "audiosink"))
        self.player.connect("about-to-finish", self.on_about_to_finish)
        
        bus = self.player.get_bus()
        bus.add_signal_watch()
        bus.connect("message", self.on_message)

    def run(self):
        self.player.set_state(gst.STATE_PLAYING)
        loop = gobject.MainLoop()
        loop.run()

    def on_about_to_finish(self, player):
        #The current song is about to finish, if we want to play another
        #song after this, we have to do that now

        print "about-to-finish, setting uri to file:", invalidfile
        player.set_property("uri", invalidfile)

    def on_message(self, bus, message):
      if message.type == gst.MESSAGE_ERROR:
	err, debug = message.parse_error()
	print "Error:" , err
	if self.restarted == 0:
	  self.restarted = 1
	  print "Attempt to restart the playbin with file:", validfile
	  self.player.set_state(gst.STATE_NULL)
	  self.player.set_property("uri", validfile)
	  self.player.set_state(gst.STATE_PLAYING)

if __name__ == "__main__":
    gobject.threads_init()
    player = Player(validfile)
    player.run()

According to documentation for playbin2:
"When playback has finished (an EOS message has been received on the bus) or
an error has occured (an ERROR message has been received on the bus) or the
user wants to play a different track, playbin should be set back to READY or
NULL state, then the "uri" property should be set to the new location and
then playbin be set to PLAYING state again."

I've submitted a bug some time ago: 
https://bugzilla.gnome.org/show_bug.cgi?id=673888
But haven't got any response yet.

I saw some projects (e.g. Banshee) are destroying the pipeline on error. Is
it something I have to do? Is there a way to avoid this and reuse the
pipeline? 

Thank you,
Lev

--
View this message in context: http://gstreamer-devel.966125.n4.nabble.com/What-is-the-correct-way-to-recover-from-an-error-during-gapless-playback-tp4655193.html
Sent from the GStreamer-devel mailing list archive at Nabble.com.


More information about the gstreamer-devel mailing list