Ich versuche, ein Programm oder einen Roboter zu bauen, Audio und Video im laufenden Betrieb generieren und es zu einem RTMP-Server wie Twitch oder Youtube streamen kann. Ich habe festgestellt, dass ich mit Gstreamer Videostreams und Audiostreams abrufen kann. Ich habe auch gefunden, dass Gstreamer eine Bibliothek in Python hat, die gut ist, weil mein Roboter bereits in Python geschrieben ist.Gstreamer in Python beendet sofort, aber ist in Ordnung auf der Kommandozeile
Das Problem ist, beim Testen mit der testvideosrc-Eingabe kann ich den Befehl sowohl mit Audio und Video in der Befehlszeile einwandfrei funktionieren lassen, aber es wird sofort beendet, wenn ich versuche, es auszuführen.
Der Code ist
# Command Trying to Replicate in Python
# gst-launch-1.0 videotestsrc is-live=true ! videoconvert ! x264enc bitrate=1000 tune=zerolatency ! queue ! flvmux name=mux ! rtmpsink location='rtmp://live.twitch.tv/app/STREAM_KEY_HERE' audiotestsrc is-live=true ! audioconvert ! audioresample ! audio/x-raw,rate=48000 ! voaacenc bitrate=96000 ! audio/mpeg ! aacparse ! audio/mpeg, mpegversion=4 ! mux.
# ORIGINAL (UNEDITED) COMMAND - gst-launch-1.0 videotestsrc is-live=true ! videoconvert ! x264enc bitrate=1000 tune=zerolatency ! video/x-h264 ! h264parse ! video/x-h264 ! queue ! flvmux name=mux ! rtmpsink location='rtmp://live.twitch.tv/app/STREAM_KEY_HERE' audiotestsrc is-live=true ! audioconvert ! audioresample ! audio/x-raw,rate=48000 ! voaacenc bitrate=96000 ! audio/mpeg ! aacparse ! audio/mpeg, mpegversion=4 ! mux.
STREAM_URL = "rtmp://REDACTED"
# For StackExchange - gst-launch-1.0 videotestsrc is-live=true ! autovideoconvert ! x264enc bitrate=1000 tune=zerolatency ! queue ! flvmux name=mux ! rtmpsink location='rtmp://live.twitch.tv/app/STREAM_KEY_HERE' audiotestsrc is-live=true ! audioconvert ! audioresample ! audio/x-raw,rate=48000 ! voaacenc bitrate=96000
# Imports
import gi
import time
from gi.repository import GObject, Gst
import os
# OS Variables and Requirements
gi.require_version('Gst', '1.0')
os.environ["GST_DEBUG"] = "4" # Enable Debug
# Initialize GStreamer
Gst.init(None) # gst-launch-1.0 !
pipeline = Gst.Pipeline()
# Create Video Source (Video Test Source)
videosrc = Gst.ElementFactory.make("videotestsrc") # videotestsrc is-live=true !
#videosrc.set_property('pattern', 18)
videosrc.set_property('is-live', True)
pipeline.add(videosrc)
# Convert Video (to x264enc?)
videoconvert = Gst.ElementFactory.make('autovideoconvert') # videoconvert
pipeline.add(videoconvert)
# IDK
idk = Gst.ElementFactory.make("x264enc") # x264enc bitrate=1000 tune=zerolatency
idk.set_property('bitrate', 1000)
idk.set_property('tune', 'zerolatency')
pipeline.add(idk)
# Queue Data
queueRTMP = Gst.ElementFactory.make("queue") # queue
pipeline.add(queueRTMP)
# Convert to Mux
flvmux = Gst.ElementFactory.make("flvmux", "mux") # flvmux name=mux
pipeline.add(flvmux)
# Stream to RTMP Server
rtmpsink = Gst.ElementFactory.make("rtmpsink") # rtmpsink location='rtmp://live.twitch.tv/app/STREAM_KEY_HERE'
rtmpsink.set_property("location", STREAM_URL)
pipeline.add(rtmpsink)
# audiotestsrc is-live=true ! audioconvert ! audioresample ! audio/x-raw,rate=48000 ! voaacenc bitrate=96000 ! audio/mpeg ! aacparse ! audio/mpeg, mpegversion=4 ! mux.
videosrc.link(videoconvert)
videoconvert.link(idk)
idk.link(queueRTMP)
queueRTMP.link(flvmux)
flvmux.link(rtmpsink)
pipeline.set_state(Gst.State.PLAYING)
Aus dem, was ich versuchte, es zu reparieren, ursprünglich konnte ich nicht den Strom an der Arbeit, weil ich in ihm einen extra „sink“ hatte. Der einzige Unterschied zwischen dieser Datei und der mit dem "Sink" Problem ist, dass "autovideconvert" "Videokonvertierung" war. Dieser Befehl funktioniert einwandfrei, wenn er in der Befehlszeile ausgeführt wird.
Sink Problem Fehlermeldung:
0:00:00.038202264 25199 0x272a370 INFO GST_ELEMENT_PADS gstelement.c:892:gst_element_get_static_pad: no such pad 'sink' in element "videotestsrc0"
Jetzt gibt es keine Fehlermeldung mit "autovideoconvert" mit. Stattdessen wird das Programm gerade beendet, auch wenn sich der Stream im Wiedergabezustand befindet.
Das Waschbecken Problem wird gezeigt mit dieser Nachricht in dem Protokoll zu lösen:
0:00:00.039500044 25214 0x2568d40 INFO GST_PADS gstpad.c:2388:gst_pad_link_full: linked videoconvert0:src and '':sink_internal, successful
Die letzte Zustandsänderungsmeldung, die im Protokoll unter auftaucht ist:
0:00:00.043316535 25214 0x2568d40 INFO GST_STATES gstelement.c:2328:gst_element_continue_state:<videoscale0> completed state change to PLAYING
0:00:00.043341987 25214 0x2568d40 INFO GST_STATES gstelement.c:2233:_priv_gst_element_state_changed:<videoscale0> notifying about state-changed PAUSED to PLAYING (VOID_PENDING pending)
Dies sind alles Wenn die Protokollierungsstufe auf 4 gesetzt ist. Was ich nicht verstehen kann, ist, was ich falsch mache, damit der Befehl funktioniert, aber nicht die Python-Version des Befehls. Es ist ein Bonus, wenn jemand weiß, wie man das Keyframe-Intervall ändert. Youtube möchte nicht kooperieren, wenn ich es nicht auf 4 Sekunden und schneller einstellen kann. Vielen Dank!
Vielen Dank! Ich hatte angenommen, dass der Betrieb der Pipeline ein blockierender Anruf war. Hinzufügen eines Sleep-Timers funktioniert. Ich habe jetzt auch keine Beschwerden mehr über meine Keyframe-Einstellungen. – SenorContento