gstreamer, Audio/Video abspielen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
jb_alvarado
User
Beiträge: 55
Registriert: Mittwoch 11. Juli 2018, 11:11

Hallo Allerseits,
ich versuche mich gerade in die GStreamer Python Bindings einzuarbeiten. Video alleine kann ich schon abspielen, aber sobald ich noch Audio dazu tun will klappt es nicht mehr. Es wird zwar das Videofenster angezeigt, bleibt aber beim ersten Frame stehen.

Verwende Python3 mit gstreamer 1.14 unter Fedora. Hier ist mein Code:

Code: Alles auswählen

#!/usr/bin/env python3

import gi
gi.require_version('Gst', '1.0')
gi.require_version('GLib', '2.0')
from gi.repository import GLib, Gst

Gst.debug_set_active(True)
Gst.debug_set_default_threshold(3)


def on_new_decoded_pad(dbin, pad):
    type = pad.query_caps(None).to_string()
    decode = pad.get_parent()
    pipeline = decode.get_parent()

    if type.startswith("video"):
        video_queue = pipeline.get_by_name("video_queue")
        decode.link(video_queue)
        print("linked video")
    if type.startswith("audio"):
        audio_queue = pipeline.get_by_name("audio_queue")
        decode.link(audio_queue)
        print("linked audo")


def main():
    Gst.init(None)

    pipe = Gst.Pipeline.new('pipleline')

    src = Gst.ElementFactory.make('filesrc', "src")
    decode = Gst.ElementFactory.make('decodebin', 'decode')

    video_queue = Gst.ElementFactory.make('queue', 'video_queue')
    video_sink = Gst.ElementFactory.make('autovideosink', 'video_sink')

    audio_queue = Gst.ElementFactory.make('queue', 'audio_queue')
    audio_convert = Gst.ElementFactory.make('audioconvert', 'audio_convert')
    audio_sink = Gst.ElementFactory.make('autovideosink', 'audio_sink')

    src.set_property('location', 'voice.mp4')
    video_sink.set_property('sync', 'true')
    audio_sink.set_property('sync', 'true')

    pipe.add(src)
    pipe.add(decode)
    pipe.add(video_queue)
    pipe.add(video_sink)
    pipe.add(audio_queue)
    pipe.add(audio_convert)
    pipe.add(audio_sink)

    src.link(decode)
    video_queue.link(video_sink)
    audio_queue.link(audio_convert)
    audio_convert.link(audio_sink)

    decode.connect('pad-added', on_new_decoded_pad)

    loop = GLib.MainLoop()
    pipe.set_state(Gst.State.PLAYING)
    loop.run()

    # cleanup
    pipe.set_state(Gst.State.NULL)


if __name__ == '__main__':
    main()

Habt ihr eine Idee wo das Problem liegt?

Grüße

Jonathan
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mit Python hat das ja erstmal wenig zu tun. Für solche Fragen ist die gstreamer community eher geeignet.

Was mir mit meiner beschränkten Erfahrung auffällt:

- warum 2 Queues? Beziehungsweise überhaupt eine Queue? Weißt du was die tut? Und warum denkst du brauchst du das?
- warum nicht einfach playbin2 ?
jb_alvarado
User
Beiträge: 55
Registriert: Mittwoch 11. Juli 2018, 11:11

__deets__ hat geschrieben: Mittwoch 26. Dezember 2018, 10:20 Mit Python hat das ja erstmal wenig zu tun. Für solche Fragen ist die gstreamer community eher geeignet.
Ich hatte hier schon andere Frage bezüglich GStreamer gesehen, daher dachte ich es kennen sich hier Leute damit aus. In der GStreamer Community kann es ja genau
so passieren, dass man sich dort nicht so gut mit Python auskennt...
__deets__ hat geschrieben: Mittwoch 26. Dezember 2018, 10:20 Was mir mit meiner beschränkten Erfahrung auffällt:

- warum 2 Queues? Beziehungsweise überhaupt eine Queue? Weißt du was die tut? Und warum denkst du brauchst du das?
- warum nicht einfach playbin2 ?
Soviel ich verstanden habe, haben Queues zwei Aufgaben, zum einen endet der Ausgang der Queue in einem neuem Thread und zum anderen hält es den Stream im Buffer um es zu ermöglichen dass Audio und Video synchron ausgegeben werden können. Im schlimmsten Fall kann es passieren, dass z.B. ein MP4 File so gespeichert ist, dass erst mal 2 Sekunden Video kommt dann zwei Sekunden Audio, um das zu synchronisieren muss beides in einen Buffer. Das meinte zumindest ein Entwickler in einem Tutorial. Habe aber auch Setups gesehen, wo nur Audio durch eine Queue ging, vielleicht reicht das auch, aber die meisten Beispiele hatte zwei Queues.

Playbin2 ist für mich unbrauchbar, weil die Pipeline noch um einiges komplexer und dynamischer wird.
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich denke mal gstreamer Komponenten zu verknüpfen ist recht unabhängig von der Sprache. Darum haben die da garantiert mehr Ahnung.

Und playbin2 kann ja auch explizite Video und Audio sinks. Du kannst also nach der dekodierung alles weitere kontrollieren.
jb_alvarado
User
Beiträge: 55
Registriert: Mittwoch 11. Juli 2018, 11:11

Habe eine Antwort von der Mailingliste bekommen. Hatte einen Copy/Past Fehler drin... Anstatt autoaudiosink hatte ich noch das autovideosink drinnen...
Antworten