2017-12-19 8 views
0

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!

Antwort

0
  1. Der Fehler mit dem Pad scheint offensichtlich. Ohne auf die Pipeline zu schauen, wenn sie korrekt ist - no such pad 'sink' in element "videotestsrc0": Also das ist nicht Sink sondern ein src Element. Und natürlich haben diese keine Sinkpads, da sie Quellen sind.

  2. Ich habe keine Ahnung, wie der Rest Ihrer App aussieht. Das "Ausführen" einer Pipeline ist jedoch ein nicht blockierender Aufruf. Wenn Sie also keine ordnungsgemäße Anwendungsschleife haben oder nur auf andere Weise warten, wird die Anwendung möglicherweise sofort beendet.

  3. x264enc key-int-max=<max-number-of-frames>. Oder idk.set_property('key-int-max', 60).

+0

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

Verwandte Themen