Riccardo Cagnasso Riccardo Cagnasso - 2 months ago 47
Python Question

Gstreamer dynamically change source before EOS

I'm trying to create a dynamic pipeline with GStreamer 1.8.2 and Python 3.5. The goal is to be able to playback some video and change it at EOS, achieving gapless playback in a way similar to using about-to-finish of playbin.

My idea is filesrc -> decodebin -> queue -> videosink, then place a probe on decodebin video src, wait for EOS event, unlink filesrc and decodebin, create a new filesrc and a new decodebin ad link them to the video sink after setting them to PLAYING status. I don't know if this is the best/correct approach but to my knowledge it should work.

My first attempt is this. The playback works fine for the first loop, then the video starts to play too fast. I think that there's some problem regarding timestamps and/or pipeline clocks, but I wasn't able to find a solution or to better diagnose the problem.

EDIT: setting max-lateness to -1 in vaapisink, the playback it still faster but a lot less faster. So IT IS a timing problem.


Well what can I tell you - use concat or videomixer/audiomixer (I prefer concat way) .. you do not need any custom solutions :)

Concat does exactly what you want it switches to another source upon EOS of current source.. Here is nice example.

Its little more tricky with multiple streams (audio, video, subtitles .. ) you then need to incorporate stream sychroniser or something similar as said here ..

Also check this answer there is already an example on concat.. but also read the comments.

UPDATE reagarding the manual way:

Using videomixer and audiomixer its little bit tricky.

Lets think about the video part..

You will create bin for stream you want to play(the first one) - lets say you have uridecodebin there which will preroll the whole thing and create pads.. when you find out the new pad is of video/x-raw you will add pad probe there and plug to videomixer.

Then some time later (when possible or so) you will create another bin with another uridecodebin (so this is the second "track" in your hypothetic playlist) and again do preroll of this. When you get the pads you do not connect them to videomixer but block the whole thing (I think PAUSED is suitable enough)

When the first one goes EOS then you will enable the second one and in the first one you will flush the rest of the video.

The same thing you will do with audio of course..

Now the tricky part - you have to align the video against audio (the audio is more presize, you compare timestamps until the audio matches the video and you throw away the rest of the audio or so) - this is needed in order to not go out of sync.

This approach is very hard to do.. I did it once and we had infinite problems of synchronisation of audio and video.