 Schön, dass ihr da seid. Ich erzähle euch was über G-Streamer. Ihr habt bestimmt den Begriff schon mal irgendwo gehört und deswegen interessiert es euch vielleicht. Ich weiß jetzt noch nicht so genau, ob das ein Man-Talk oder ein Workshop ist. Guck mal, was daraus wird. Es ist also auf jeden Fall so, dass es für euch einen Link gibt. Pads.schaffenburg.org. Und da sind alle Command Lines drin, die ich jetzt verwenden werde. Da müsst ihr also nichts von den Folien abtippen. Ja auch schön, wenn ihr dann G-Streamer gleich installiert, wenn ihr es noch nicht drauf habt. So für die Hauptdistros ist es auch in dem Pad drin. Also da könnt ihr dann einfach hier den Kram raus kopieren und ausführen bei euch im Terminal. Als irgendwie in den ersten paar Folien, wo ich ein bisschen was zu den Grundlagen erzähle, das drauf installieren. Ich brauche mal hier noch Fullscreen. Gut, also erstmal zu mir. Ich heiß Andreas Frisch und ich bin aus Aschaffenburg. Das ist hier so ein Nachbarstadt mehr oder weniger. Und ich beschäftige mich schon seit über 10 Jahren mit G-Streamer. Das hat begonnen bei der Firma Dream Multimedia. Wir haben linux-basierte Set-Up-Boxen gebaut, die sich eben auf G-Streamer gestützt haben für alles, was keine direkte Fernsehwiedergabe war. Also wenn man mit diesem Resif irgendeinen Internet-Stream abgespielt hat oder eine MP3, dann lief das über G-Streamer. Seit anderthalb Jahren bin ich jetzt bei Make TV und da verwenden wir eben G-Streamer im Backend für so cloud-basierte Streaming-Produktionen. Also zum Beispiel die ESL verwendet da unseren Kram, ein paar Fernsehstationen. Und nebenbei mache ich das noch im Aschaffenburger Hacker Space bei Schaffenburg eV. Da haben wir vorne im Hackcenter unsere Photobooth zum Beispiel stehen, die verwendet für die Foto und für die Videopipeline auch G-Streamer. Gut, also zur Gliederung. Ich erzähle erstmal, was G-Streamer nicht ist und was es ist, was es sein möchte und wofür es gut ist. Und dann ein bisschen so über den Grundaufbau, wie das Innen unter der Haube aussieht. Dann erzähle ich was über die Benutzung der Werkzeuge, die da mitgeliefert werden. Da sind so ein paar Tools dabei, die einem den Einstieg sehr erleichtern und dann auch die Arbeit damit. Und dann wenn alles so läuft, wie ich mir das gedacht habe, dann können wir vielleicht noch zusammen ein bisschen rumbasteln mit G-Streamer. Also ich fange vielleicht mal an, was es nicht ist, da herrschen ein paar Missverständnisse. Es ist nämlich zum Beispiel mal kein Media Player, also G-Streamer ist kein VLC oder sowas in der Art. Man kann ein Media Player damit bauen und es ist auch so ein minimal Beispiel eines Command Line Abspielprogramms dabei. Aber es ist mehr als nur ein Media Player. Es ist auch nicht nur eine Codec-Sammlung, so wie FFM-Pack oder sowas in der Art. Es hat Codecs dabei, aber es ist wiederum mehr als das. Es ist auch kein großes Konvertierungsprogramm, es ist kein Streaming-Server, es ist kein Ersatz für ALSA oder Pulse-Audio, sondern es benutzt es alles oder es kann benutzt werden, um sowas zu bauen. G-Streamer nennt sich eine Open-Source-Kosplattform pipeline-basierte, erweiterbare Multimedia-Framework. Zu den einzelnen Begriffen zeige ich gerade jeweils ein ganz kleines bisschen. Open-Source ist schon ein sehr altes Projekt, wurde 1999 schon begonnen. Es hat eine sehr aktive Community von den Entwicklern, von den Core-Entwicklern und auch von den Nutzer-Entwicklern, die es einsetzen. Das erleichtert einem den Einstieg ungemein. Es gibt zum Beispiel einen sehr aktiven IRC-Channel, wo man mit den dümmsten Anfängerfragen trotzdem nicht ablitzt, sondern es wird einem immer geholfen, es ist wirklich super. Es gibt einen prallvollen Buxilla mit tausenden von Bux, also es wird ständig neu released. Mailingliste ist klar, das ist also wirklich vorbildlich. Und es schwirren in manchen Distros immer noch 0-10er-Fessionen von G-Streamer herum. Die ist aber seit sechs Jahren inaktiv, wird nicht mehr gepflegt und sollte dann nicht mehr benutzt werden, spricht nichts dagegen, eben die neue 1.0-AP zu benutzen. Die Rolling Release Distros haben 1114 jetzt seit ein paar Tagen, aber wenn ihr 1.10 oder 1.12 drauf habt, kein Problem. Geht alles auch, was ich jetzt zeigen will. Cross-Plattform versteht sie von selbst. Es hat natürlich angefangen unter Linux, BSD, Unix, Sysch, Kram. Ganz wichtig ist der Embedded-Bereich. Also wenn ihr zum Beispiel an Smart-Hiff verausdenkt oder an die Entertainment-Dinger in Flugzeug, das ist oftmals G-Streamer, was da drin steckt. Oder wie ihr erwähnt, in Set-Up-Boxen ist es oftmals verwendet. Ganz lustige Anwendungsgebiete gibt es auch noch zum Beispiel, das ist vor letztes Jahr oder so rausgekommen, dass die das benutzt haben, um diese Gravitational Waves, diese Gravitationswellenforschung. Da haben die auch in irgendeiner Berechnung G-Streamer eingesetzt, irgendwelche G-Streamer-Elemente und auch auf der ISS gibt es G-Streamer. Es wird also teilweise für Videostreaming verwendet auf der internationalen Raumstation. Abgesehen davon natürlich so für die normalen Desktops, auch Apple und Windows und natürlich auch für Android gibt es G-Streamer-Bills. Pipeline basiert, bedeutet in G-Streamer dreht sich alles darum, dass man Elemente hintereinander reiht. Man kann sich zum Beispiel eine Wiedergabe vorstellen, wie so ein Strom von Daten. Das fängt auf der einen Seite an in der Source immer und auf der anderen Seite ist eine Sync und dazwischen sind irgendwelche verarbeitene Elemente. In dem Fall wäre das jetzt hier eine Wiedergabe von der OCT-Datei. Die wird gelesen in der Filesource, dann wird sie auseinandergenommen in einem OCT-Demuxer, dann wird dieser codierte Datensstrom in einem Warbis-Dekoder dekodiert, in Raw-Audio, wie sich das nennt. Also in einem Format, wo die unkomprimiert vorliegen, die Audio-Daten, dass sie dann eben abgespielt werden können, zum Beispiel mit einer Pulse oder mit einer Alsa-Sync. Es gibt verschiedene Typen von diesen Elementen. Also ganz grundlegend ist mal diese Pipeline. Das ist das, was alles umschließt. Das ist ein Binn, sozusagen, in einer Eimer, wo man was reinschmeißen kann. Dann gibt es, wie gesagt, Sources. Das muss nicht unbedingt eine Filesource sein. Das kann auch eine Netzwerksource zum Beispiel sein, die was aus dem Internet lädt oder resifft, also irgendwo um Laden, oder auch selber erzeugt oder von der Kamera captured. Das sind eben Source-Elemente. Dann, wie gesagt, Demuxer gibt es eine riesen Vielfalt. Es gibt Filter und Pasa, die die Daten irgendwie umformen. Also zum Beispiel die Größe ändern oder solche Sachen machen. D und Enco, der ist klar. Also wir machen aus Raw Audio eine MP3 oder wir machen aus einem H264 Streams Raw Video Frames, die sich dann anzeigen lassen in der Sync oder speichern lassen oder ins Netzwerk raus streamen lassen. Das ist dann das Sync-Element. Erweiterbar. Also grundsätzlich bringt es schon mal ganz viele Erweiterungen mit. Das ist nämlich aufgespalten in GStreamer Core. Also nur GStreamer ohne eine Endung hinten dran. Da sind eben nur so die ganz wichtigsten Grundelemente und Tools mit drin und dann kommen Base, Good, Bad, Ugly. Also so Plugins, die ganz neu sind, fangen normalerweise in Bad an. Also wenn zum Beispiel noch die Unitest fehlen, ein Dokum fehlt oder sowas, dann fangen wir erst mal in Bad an und irgendwann, wenn sie perfekt funktionieren, kommen sie nach Good. Und in Base sind so eben die ganz grundlegenden Sachen, zum Beispiel die Testzursen und so weiter. Und in Ugly sind diejenigen Plugins, bei denen es zum Beispiel so ein bisschen quirky ist, mit Lizenzen und solche Dinge, wo man eben auf reverse engenierte Sachen zurückgreifen musste. Also die kann man dann halt eben, wenn man irgendwas Offizielles damit bauen will, einfach weglassen, damit man da nicht in die Pridolje gerät. Und dann gibt es noch GST LibAV und das ist eben ein Rapper für LibAV, beziehungsweise FFM-Pack, wie es mal hieß. Und dann hat man eben Zugriff auf diese gesamten Codecs, die da drin enthalten sind und kann die in GStreamer verwenden, codieren und dekodieren. Und diese Plugins kann man auch ganz einfach selber schreiben. Also Firmen, in denen GStreamer eingesetzt werden, haben normalerweise ein Set von Plugins für ihre eigenen Dinge. Also das geht zum Beispiel die Firma Blackmagic, die macht so Videocapture-Karten und von denen gibt es dann Decklink, Sinks und Sources und so weiter. Geht also selber. Kann man natürlich auch properitär machen, das muss man dann nicht veröffentlichen. Genau, Multimedia, da muss man nicht so viel dazu sagen, aber ganz interessant vielleicht zu erwähnen, ist, dass der GStreamer Core an sich vollkommen Media-Agnostic arbeitet. Also einer File-Source oder einem Puffer-Element in der Queue ist es vollkommen burscht, was da jetzt für Daten durchgehen. Man kann damit irgendwie eine binäre, ausführbare Datei lesen, wenn man das will oder eine Text-Datei. Also das muss kein Medienformat sein. Also prinzipiell sind die Elemente erst mal überhaupt nicht eingeschränkt, sondern das spezifiziert sich dann halt je nachdem, was man genutzt. Aber so die Grundelemente sind Media-Agnostic. Gut, und dann ist das Ganze ein Framework. Das bedeutet, wir verwenden es, um andere Sachen zu bauen, im Prinzip. Also hier nochmal so eine Übersicht, was da alles jetzt eben mit rein spielt. Das sind eben diese ganzen Plugins unten, oben die Tools, in Orange Beispiele, wofür es eingesetzt werden kann, wofür es eingesetzt wird. Ja, genau. Und es gibt eben Bindings für ganz viele Sprachen. Das ist jetzt nun ein kleiner Ausschnitt der Bindings. Man kann also eigentlich in seiner Lieblingssprache seine Applications bauen und damit auf GStreamer zurückgreifen. Haben inzwischen Zeit ein paar Leute GStreamer installiert bei sich? Cool. Die Frage war, gibt es APIs für diverse Programmiersprachen, wo ich das reinbauen kann oder brauche ich zur Laufzeit diese GSD-Installation? Also wir brauchen die GStreamer-Installation im Prinzip schon. An API gibt es eigentlich, man braucht nur den GStreamer-Header importieren und danach kann man alle Plugins, die installiert sind, die werden zur Laufzeit gefunden, werden ediziert in der Registrie und die kann man dann verwenden, ohne dass man für die einzelnen Plugins irgendwelche Header oder sowas noch inkludieren müsste. Also das funktioniert dann einfach über die GStreamer-API. Man kann das Ganze auch statisch bauen. Ist natürlich sinnvoll zum Beispiel für Android oder sowas. Das geht auch. Gut. Die Grundtour, übrigens bitte jederzeit unterbrechen. Ich glaube, ich habe es nicht explizit gesagt. Es stand auf einer der Eingangsfolien. Diese Tools, die dabei sind, es gibt noch das eine oder andere, die jetzt nicht unbedingt erwähnenswert sind, aber so die wichtigsten sind GST-Inspect-Launch, Typefind, Discover und Play. Und zu Inspect lässt sich sagen, dieses Tool gibt einem, erst einmal, wenn man es ohne Argumente aufruft, eine Liste aus von allen Plugins, die auf dem System gefunden werden. Also die werden gesucht einmal und danach werden sie in der Registrie gecached, damit es dann beim nächsten Aufruf schneller geht. Beziehungsweise, wenn man ein Programm lädt, was eben GStreamer benutzt. Das sind, wenn man die Pakete alle installiert hat, knapp 250 Stück. Man kann also da drin schon mal so grob greppen, wenn man eine Idee hat. Also man möchte irgendwas mit mp3 machen, dann macht man halt mal ein GST-Inspect 1.0 grepp mp3 oder so und dann kriegt man schon mal die Elemente, die mp3 im Namen haben. Und wenn man GST-Inspect mit einem Element Namen oder Plugin Namen aufruft, dann kriegt man zu denen weitere Informationen angezeigt. Das ist also sehr, sehr praktisch. Dann gibt es GST-Launch. Und das ist eben ein super Praktisches Tun, mit dem man so eine Pipeline aufbauen kann. Einfach auf der Kommandozeile kann man die hintereinander hängen. Man muss also in dem Fall nichts programmieren. Man muss nicht gleich C-Code schreiben, um irgendwas zu testen, sondern man macht GST-Launch und kann dann das reinhacken. Das mache ich jetzt gerade mal. Ich kann ja auch mal hier ein GST-Inspect aufrufen. Dann sieht man auch, was ich hier so drauf habe alles. Also es ist eine große Liste von Sachen. Und wenn ich jetzt hier zum Beispiel File Source eingebe, dann sehe ich eben, was File Source alles so macht. Wer hat es geschrieben? Das ist eine Source, die ist in den Core Elements enthalten. Und das sind jetzt die Properties. Was Properties sind, komme ich gleich dazu. Und wenn ich jetzt mal zum Beispiel das hier mir kopiere und ausführe, dann was erwartet ihr, was vielleicht passieren könnte? Danke für den Hinweis. Dann kriegt man ein Testbild hier oben. Also die Video Test Source erzeugt dieses Semti-Pettern noch mit so einem Rauschen dazu. Video Convert sorgt dafür, dass es auf jeden Fall in das richtige Format konvertiert wird, was dann eine systemspezifische Video Sync anzeigen kann. Also ich könnte da jetzt hier reinschreiben, X-Video Sync, dann funktioniert das nur unter Linux. Wenn ich das Ganze unter Mac ausführe mit der Auto Video Sync, dann nimmt es halt auf Mac gleich die richtige Sync oder auf Windows, je nachdem, was eben da für eine Video Sync vorhanden ist, wird die richtige benutzt. Kriegt ihr das hin mit Audio? Willst du mal jemanden probieren? Wie könnte da die entsprechende Command Line heißen? Ich mache mal der Wahl weiter. GST-Time-Find ist dafür geeignet, um in einer Latei den enthaltenen Streamtyp zu finden. Ja, perfekt. Genau. Also mit Audio Test Source, Audio Convert, Audio Sync kriegt man das Ganze für Audio, macht ein Sinus-Ton. Mit GST-Time-Find kriegen wir den umfassenden Streamtyp, also sozusagen zum Beispiel den Container. Mit GST-Discoverer kriegen wir dann genauere Infos, was ist in so einem Container auch noch an Elementary Streams enthalten und das funktioniert auch über Dateien, über mehrere oder Verzeichnisse hinweg und auch über Netzwerkstreams. Ich kann ja mal gerade hier gucken, ob ich irgendwas habe. Da mache ich mal hier GST-Type-Find von irgendeiner Latei. Dann wird er mir sagen, da ist ein Matroska-Video drin und wenn ich jetzt mal hier das Coverer aufrufe, dann zeigt er mir eben für jede Dateien im Verzeichnis an, was da so drin ist. Matroska-Container enthalten ist ein H264-Video Stream und die Betrate zeigt auch noch an. Gut. GST-Play, das ist jetzt so ein minimaler Media Player. Mit dem kann man eben irgendwas abspielen. Video-Testsauce nochmal, das ist halt hier jetzt mein Groß, dann spielt er das ab. Könnte man auch ein Netzwerkstream eingeben und der sucht sich dann eben die entsprechenden Elemente zusammen und gibt das wieder. Das ist aber mehr zum Testen, also das ist nicht sonderlich komfortabel. Gut, jetzt Properties, habe ich gerade schon mal was dazu gesagt. Das ist dasjenige, was man bei GST-Inspect findet. Und zwar gibt es da für jedes Plug-in eine verschiedene Liste. Name können sie alle, also den kann man immer einen Namen geben. Und hier bei der Filesauce gibt es zum Beispiel die Möglichkeit zu beschränken, wie viele Buffer der liest, ob er einen liest oder ob er die ganze Datei liest, standardmäßig ist die ganze Datei solche Sachen eben. Also das sind Stellschrauben, mit denen man das Verhalten von den Elementen beeinflussen kann. Und diese Properties, die sind keine Erfindungen von G-Streamer, sondern die kommen aus G-Object. Also G-Object ist das Framework, mit dem wiederum das Framework G-Streamer geschrieben ist. Das ist halt so eine objektorientierte Erweiterung für C. Das kommt glaube ich ursprünglich von der Entwicklung von GIMP, wenn mich nicht alles täuscht. Also irgendwo aus der Nome-Welt. Und das ist sehr praktisch und sehr umfangreich. Also G-Object und G-Lip. Und die machen automatisch schon diese Properties. Also G-Objects können Properties haben und die können zum Beispiel bestimmte Ranges unterstützen. Wenn ich jetzt hier GST-Launch, File, Source, Blar, gleich 1, 2, 3 mach, dann wird er mir sagen, Blar gibts nicht. Oder wenn ich mach Numbuffers ist gleich XYZ. Dann wird er mir sagen, Numbuffers. Dass er es nicht auf XYZ setzen kann, weil es eben numerisch sein muss und kein String sein darf. Also darüber braucht sich GST, wie man dann gar keine Gedanken zu machen oder die Elemente müssen das nicht testen, weil das eben vorher schon abgefangen wird. Ja, ich habe es auch schon in verschiedenen Tonhöhen, Piepen hören. Also mit Freak ist gleich in der Zahl, kann man die Frequenz zum Beispiel beeinflussen, die von der Audiotest source genau auf der gegebenen oder erzeugt wird. Gut, jetzt Caps. Was sind Caps? Ich habe was übersprungen. Caps sind Capabilities. Das steht wörtlich übersetzt für Einsatzmöglichkeiten und die definieren eben bei vielen Elementen, was die unterstützen. Also was darf rein, was darf raus. Bei einer File Source ist das Any, die kann alles. File Sync auch, aber die Audiotest source oder die Videotest source zum Beispiel, bei denen ist das eingeschränkt. Ich kann jetzt mal hier diese Kommandozeile ausgeben, also quasi unsere GST-Lounge, aber noch mit einem V hinten dran. Und jetzt kriegt man hier ein paar mehr Infos, nämlich unter anderem, welche Caps die verwenden. Und dann sieht man hier, der hat sich geeinigt auf Video X RAW, also Video-Rohdaten mit einem bestimmten Format, I420. Und jetzt hier eine Width und eine Height. 320 x 240 ist nicht sonderlich groß, aber das ist eben so der Default-Wert. Wenn man nichts anderes angibt und eine Frame Rate von 30 Einteln, also das ist Fraction 30 frames pro Sekunde. Es ist auch möglich, dass diese Caps nicht fix sind, also fest spezifiziert, sondern dass die erst ausgehandelt werden müssen, weil die Plugins eine ganze Reihe von Caps unterstützen. Also das könnten mehrere Formate sein. Das könnten zum Beispiel gleichzeitig MPEG-2 und MPEG-4, aka AAC sein, die ein Element unterstützt. Und dann werden die erst mal ausgehandelt in der Negotiation, bis es dann sich geeinigt hat, die beiden verbundenen Elemente in einem Format und dann läuft es los. Man kann das aber auch selber festlegen, wenn man jetzt zum Beispiel eine größere, größer ausgeben will und eine niedrige Frame Rate, dann kann man das machen mit einem Caps-Filter-Element. Und das ermöglicht einem eben hier ganz eindeutig irgendwelche Properties zu spezifizieren in den Caps. Nämlich in dem Fall die Breite und die Höhe, die hier angegeben sind und eine Frame Rate von nur zwei FPS. Wenn ich das jetzt mache, dann sieht man, es ist viel größer und viel langsamer geworden. Es ist jetzt nicht langsamer, weil das nicht schafft, sondern weil ich das angegeben habe. Das ginge auch schnell. Wenn ich das wegmache, dann defaultet die wieder auf 30 und dann haben wir das Ganze schnell. Ja. Und diese Kurzschreibweise mit den... einfach nur hingeschrieben, diese Caps ist eigentlich... im Hintergrund macht man damit einen Caps-Filter-Element in die Pipeline mit der Property Caps, die dann diesem String entspricht. Untereinander verlinkt man diese Elemente. Wir haben das die ganze Zeit eigentlich schon gemacht in der Pipeline mit GST-Launch mit diesen kleinen Ausrufezeichen. Es ist auch wichtig, dass davor und dahinter immer ein Lehrzeichen ist, damit er das richtig macht. Und wie gesagt, suchen die sich dann automatisch die richtigen Pads aus und die richtigen Caps. Da braucht man eigentlich auf gar nix zu achten. Man kann und teilweise muss man das auch, aber ganz konkret auf dedizierte Pads zugreifen von Elementen, wenn man zum Beispiel ein... ja, ein MPEG-TS-Stream hat mit verschiedenen Sprachen drin. Dann hat man mehrere Audiospuren und woher soll man wissen, welche von denen man jetzt abspielen will. Das kann man machen, indem man auf diesen MPEG-TS-Demux zugreift und dann mit Punkt und dann den Pad-Namen. Wenn man durchnummeriert in dem Fall, das ist auch wieder in GST-Inspect zu finden, nach welchem Schema die benannt werden. Und dann wird es dann im Audio unter Strich 0, Audio unter Strich 1 und so weiter. Und dann hat man da die einzelnen Sprachen drin. Die anderen kann man dann wegschmeißen oder sonst was machen damit. Und diese Pads, die haben auch immer Templates. Und in den Templates ist eben einmal die Richtung enthalten, ob das ein Source oder ein Sync-Temp-Pad ist und ob das always auf Request oder Summ-Times vorhanden ist. Also ich kann ja mal gerade für ein... zum Beispiel für Matros, K-Mux, das Ganze anzeigen. Und dann sehen wir, das hat hier Sync-Video, Sync-Template on Request. Das heißt, nur wenn man ein Videopad dort requested, dann erzeugt er das auch in dem Moment. Standardmäßig sind die nicht vorhanden, weil das eben auch beliebig viele sein könnten. Das gleiche gilt für die Audio-Pads. Andererseits ist das Source-Pad, also dasjenige Pad an dem Matroska-Mux-Element, wo dann der fertig gemuxes Stream rauskommt, always vorhanden, weil immer was rauskommen muss. Ansonsten ist das Ding ja überflüssig. Gut. Dann zur Kommunikation. Innerhalb von unserer Application und von unserer Pipeline gibt es verschiedene Typen. Das sind zum einen erstmal die Buffer. Das sind diese blau-grauen hier unten und die fließen immer den Fluss runter, Downstream, wie man sagt, von Source-Pads zu Sync-Pads. Und die tragen dann konkret wirklich so den Payload, also die Nutztaten weiter. So grau sieht das da gar nicht aus, mehr dunkelblau. Dann gibt es noch diese Signals. Und die Signals sind eben dafür da, dass Elemente der Application-Synchron irgendwelche Dinge mitteilen können. Also zum Beispiel der Ock dem Maxar, könnte der Application sagen PadEdit. Und dann können wir einen Listener verbinden zu diesem PadEdit-Signal und dann kriegen wir einen Callback, der eben aufgerufen wird, wenn der Muxer feststellt in meinem Stream, den ich hier gerade reinkriege, gibt es einen neuen Noise-Audio oder Videopad. Das kann nämlich auch durchaus vorkommen, dass die nicht gleich alle am Anfang da sind, sondern dass die erst irgendwann später mal auftauchen. Und dann kann man darauf reagieren und zum Beispiel diesen Untertitel jetzt anzeigen oder dem Benutzer die Möglichkeit geben, darauf umzuschalten oder so. Umgekehrt kann auch die Application mit Action-Signals Dinge an Elemente schicken. Da gibt es als Beispiel, ich kann ja auch mal hier auf die entsprechende Folie gehen, als Beispiel diese Pushbuffers-Aktion von einer AppSource. AppSource ist ein Element, mit dem man in seiner Application Daten erzeugen kann und in die Pipeline einschleusen kann. Also ich könnte in meiner Application zum Beispiel ein weißes Videoframe generieren und dann in die GStreamer Pipeline rein pushen mit diesem Pushbuffersignal. Dann gibt es noch die Messages. Also man kann ein Message-Boss anlegen und da dann Nachrichten abholen, die Elemente dort reinschreiben. Also das könnten Dinge sein, zum Beispiel, dass Tags gefunden wurden, also irgendwie MP3 Tags, dass sich die Bitrate geändert hat, solche Dinge. Und die werden dann eben im Gegensatz zu den Signals, werden die Asynchronen abgearbeitet im Hauptthread. Das heißt, man muss auch jetzt sich keine Gedanken darüber machen, dass man plötzlich in einem anderen Thread ist, weil bei den Signals ist es so, wenn einem der Demuxer so ein Pad-Edit schickt, dann wird der Callback auch in dem Kontext von dem Demuxer ausgeführt. Also in dem anderen Thread, nicht in meinem Main Thread. Darauf muss man achten, das muss man locken und so weiter. Das muss man bei den Messages nicht, das ist also ein bisschen einfacher. Dann gibt es noch Events und die können Kommando sein, zum Beispiel umzusuchen in so einem Stream oder um ein End-of-Stream auszulösen, also wenn man das Ganze beenden möchte und das können auch Elemente untereinander hin- und herschicken. Also solche Dinge können sowohl den Fluss hoch als auch runterwandern, ab Streams und Downstreams ist eben möglich. Und dann gibt es noch solche Queries-Abfragen und da kann man zum Beispiel die Capabilities von einem bestimmten Pad damit anfragen zu einem bestimmten Zeitpunkt. Also diese Capabilities sind auch möglich auf Pads, nicht nur auf Elemente, aber verschiedene Dinge mit Abfragen. Gut, dann gibt es vier States, die immer nacheinander durchlaufen werden. Das Ganze fängt an mit Null. Bei Null ist ein Element eben im Prinzip zwar vorhanden, aber es hat keinerlei Ressourcen zugewiesen. Es verbraucht auch quasi nichts. Es wird dann erst in Ready alles allokiert und in Pause wird dann so der erste Buffer vorbereitet und in Playing läuft es dann alles durch. Also wenn man jetzt GST-Launch ausführt, dann sieht man sehr schön, wie nacheinander diese einzelnen States angefahren werden. Man kann auch nicht direkt springen von einem zum anderen, sondern die werden immer alle nacheinander schön durchiteriert. Das kann ich auch mal kurz zeigen. Wenn ich das jetzt mal ausführe, unsere altbekannte Pipeline, wenn ich da jetzt hinten dran mal noch ein M hänge, dann kriege ich die Messages, die hier alle auflaufen und dann sieht man das ja hier zum Beispiel mit State Change mit Null anfängt. Das ist der old state und der new state ist dann ready. Also hier geht er von Null auf ready und dann als nächstes geht er von ready auf paused. Das ist dann der nächste, das ist der pending und so weiter. Hier geht er von ready auf paused und dann von paused auf playing. Da sieht man ganz schön, wie die durchlaufen hier und eine Message, die hier auch irgendwo drinstehen dürfte. Ich such grad mal, das ist Stream Start. Die kommt eben von der Pipeline selbst und diese Stream Start Message, wäre jetzt zum Beispiel interessant. Da könnte dann die Application da drauf heuchen und dann eben dieses berühmte Dreieck anzeigen, so ab jetzt läuft es. Also ganz interessant. Mal reinzugucken, was eigentlich abgeht. Gut. Ich habe schon mal kurz threads erwähnt. Also G Streamer beruht ganz heavily, ganz wichtig auf threads. Also jedes Mal, wenn man irgendwo brancht, wenn man irgendwo eine queue einfügt, gibt es einen neuen thread. Das ist eben ganz wichtig, damit sich die einzelnen Äste von diesem Strom nicht gegenseitig blockieren. Das heißt, wir brauchen nach jedem N zu 1 vor jedem N zu 1 und nach jedem 1 zu 1 Element brauchen wir eine queue. Das ist also eigentlich so ein kleiner Zwischenspeicher, der eben die Sache voneinander entkoppelt. Weil es gibt jetzt zum Beispiel MP4-Dateien oder sowas, wo ein Audio-Video-Interleaf von mehreren Sekunden ist. Also in der Datei sind vielleicht mal 2, 3 Sekunden Audio, dann sind 2, 3 Sekunden Video, dann wieder Audio und so weiter. Wenn ich mir vorstelle, mein Demuxer liefert mir die Daten genauso wie sie in der Datei sind. Das heißt, es kriegt jetzt als erstes Mal nur der Audio-Dekoder 2 Sekunden Audio und der Video-Dekoder in der Zeit nichts. Das heißt, was müssen wir machen? Wir müssen diese 2, 3 Sekunden Zwischenspeichern im Audio-Dekoder und dann in dem Moment, wo der Video-Dekoder auch Daten kriegt, dann können die beide zusammen loslaufen. Ansonsten passiert eben gar nichts. Und das ist also was, was ganz wichtig ist. Man muss nach dem Demuxer an jedem Pad vorher erst mal eine queue einbauen. Das kann ich hier auch mal kurz ausführen. Ein T ist ein T-Stück-Element und das brancht eben auch. Damit kann man einen Datenstrom aufteilen. Das ist sehr praktisch, wenn man diese Daten, die die Audio-Test-Source generiert, in 2 verschiedenen Elementen am Ende benutzen will. Also, was ich jetzt hier mache ist, ich tue das einmal abspielen in der Audio-Sync und einmal mache ich eine Waff-Datei draus und schreibe die... Hört sich gut an, oder? Und jetzt, wenn ich mir das mal anschaue, dann habe ich hier diese Bla-Punkt-Waff erzeugt. GST-Type-Find, Bla-Punkt-Waff und sehe da, es ist tatsächlich eine Waff-Datei drin. Also, auf die Art und Weise kann man eben mit T's aufteilen. Was noch wichtig ist, ich muss dem Element einen Namen geben. Ansonsten kriegt es den Default-Namen T0, also die werden dann durchnummeriert, damit ich dann von dort aus wieder weiter verzweigen kann. Also, mit diesem Punkt greife ich eben auf den Namen T zu, den ich hier zugewiesen habe, ohne jetzt konkret ein Pad anzugeben. Ich könnte jetzt hier auch noch Source 0 und Source 1 dahinter schreiben, aber das ist nicht notwendig, weil die eh ja gleich sind. Good. Dann Playbin. Ich habe vorhin den GST-Play kurz gezeigt und der verwendet intern das Element Playbin und das ist eben so ein ganz hochleveliges schlaues Konstrukt, was als einzige Property benötigt eine URL, also eine Quelle, eine UI. Das kann auch File-Doppel-Punkt-Slash-Slash-Slash irgendwas sein, also eine lokale Datei oder eben alle möglichen verschiedenen Netzwerk-Streams. Also jedes Plug-in, was in meiner Registrie steht, meldet sich an, also jedes Source-Element mit den Schemas, die es unterstützt. Also es gibt zum Beispiel eine Sub-HDP-Source und die sagt dann, die kann das Schema HTTPS und HTTPS und wenn jetzt GST-Launch mit Playbin gestartet wird, mit einer UI, die anfängt mit HTTPS, dann weiß die, die kann das Element Super-HTTPS-Source verwenden, um diesen Stream zu empfangen. Dann hat es diesen Stream und dann kann es mit Typefind gucken, was ist da für ein Format drin. Und dann weiß es, okay, da ist jetzt in dem Fall, was ist das? Ein OK Video, also da brauchen wir einen OK Demux. Und dann kann es weiter gucken, was kommen da für einzelne Datenströme aus dem OK Demux raus. Da ist jetzt ein Vorbis-Audio-Stream wahrscheinlich drin und ein Teora-Video-Stream oder sowas und kann dafür die entsprechenden Elemente raussuchen aus der Registrie, die eben diese Capabilities haben, diese Streamtypen zu dekodieren. Und dann haben wir eben Raw Video und Raw Audio, die wir dann anzeigen können. Also dieses Playbin-Element verwendet dann intern nochmal ein Decodebin-Element und das Decodebin ist eben zuständig da, die ganzen entsprechenden Sachen zusammenzusuchen, um das dann im Endeffekt abspielen zu können. Und Playbin verwenden auch die meisten Abspielprogramme, die man mit G Streamer bauen kann. Also auf der Dreambox, der Media Player war auch mit Playbin. Obwohl da ein paar Knifflichkeiten dabei waren, weil die Dreambox zum Beispiel eben auch direkt H264 Streams abspielen kann. Es muss nicht unbedingt oder es darf sogar nicht dekodiert werden zu Raw Video, so wie das beim PC meistens der Fall ist, weil damit kann die gar nichts anfangen. Abgesehen davon würde die das auch nicht schaffen. Also der Chip, der in der Dreambox drin ist, will H264 abspielen, will MPEG 2 abspielen. Man kann also auch die Formate, die Decodebin bzw. Playbin dann ausgeben, nochmal weiter einschränken. Also wenn man nicht unbedingt Raw haben will. Das gleiche gilt natürlich für Audio auch. Okay, dann wenn ihr möchtet, könnt ihr mal ein kleines Hello World schreiben. In dem Pad ist das auch enthalten. Könnt ihr euch raus kopieren oder runterladen mit WGET und dann vielleicht schafft es jemand das zu kompilen. Das wäre sehr cool. Derweil kann ich ja mal hier noch ein paar lustige Dinge zeigen. Also es gibt zum Beispiel, kennt ihr OpenCV, das ist, also wir können erstmal mit Auto Video Source, das gibt es auch, können wir auf Kamera Element zugreifen. Auto Video Sync. Hallo, das ist jetzt so unscharf und speckig von meinem Aufkleber, das ist wahrscheinlich nicht funktioniert, aber wir probieren es mal. Ich schmeiß da jetzt mal ein Face Detect rein. Und dann haben wir jetzt hier zum Beispiel ein Element, was das Gesicht erkennt, mehr oder weniger gut. Und da eben hier diese Kreise einzeichnet. Das könnte man zum Beispiel benutzen oder wir könnten mal eine Datei erzeugen, indem wir aus einer Video Test Source und einer Audio Test Source eine Matroska Datei machen. Also ich höre es schon, weil manchen funktioniert es bereits. Was kann ich jetzt mal machen? Ich lasse es mal ganz kurz laufen. Das ist jetzt eine Sekunde, 1,8 Sekunden gelaufen. Und wenn ich jetzt diese Datei mir mal anguck, test.mkv, dann stelle ich fest, da sind jetzt schon 15,8 Sekunden drin. Kann sich jemand vorstellen, warum das so ist? Ich habe die nur 1,8 Sekunden laufen gehabt, die Pipeline sind aber fast 16 Sekunden drin. Nee, es ist nicht komprimiert, sondern es ist Async. Also ich habe jetzt in dieser Pipeline, nicht wie vorhin bei unserer Waff Datei, noch eine Audio Sync. Die Audio Sync ist Sync, also die ist Synchron. Das heißt, die Pipeline läuft nur in der Geschwindigkeit, in der sie auch abgespielt wird. Jetzt habe ich in dem Beispiel, habe ich aber keine Audio Sync mehr drin, sondern ich habe nur eine File Sync. Und wenn ich jetzt mal GST Inspect auf diese File Sync mache, dann sehe ich, dass die hier ein Async Property hat und die ist default true. Das heißt, die schreibt so schnell wie sie Daten kriegt und die Audio und die Video Source, die produzieren Daten so schnell wie sie können. Das heißt, ich habe jetzt innerhalb von dieser 1 Sekunde, die das gelaufen ist, 16 Sekunden produziert und gespeichert. Wenn ich die jetzt abspielen würde, GST Play Test MKV, dann läuft das auch so lange. Wenn ich ein Video ohne Audio spiele, kann ich machen. Die sind beides selber getimestamped. Also in dem Fall wäre es kein Problem, es würde beides einzeln auch richtig laufen. Also die Frage war, wer synchronisiert das Ganze, wenn nur Video oder nur Audio abgespielt wird. Also in dem Fall, wo wir eine MKV Datei haben, läuft es mit Timestamps. Also es gibt ja 2 Arten von Timestamps, die sind in den Buffern normalerweise enthalten. Es gibt die PTS und DTS Presentation Timestamps, die Code Timestamps und die sind beide gesetzt. Das heißt, wir können das ohne Probleme separat abspielen. Das ging auf jeden Fall. Hat es noch jemand geschafft, es zu kompilen oder braucht jemand Unterstützung dabei? Wo ist noch Programmierung hier? Dann könnte ich vielleicht mal was zu dem Code erzählen. Also wie gesagt, wir müssen eigentlich für das ganze Ding immer nur unsere G-Streamer-Header-Datei inkluden. Das ist alles, was wir brauchen. Eigentlich auch für komplexe Projekte, weil wir hinterher zum Beispiel dieses Signal und so weiter, die können wir alle verwenden, ohne für die einzelnen Elemente nochmal Header zu brauchen. Das ist ganz praktisch. Dann haben wir hier unsere Main-Funktion. Die Pipeline ist unser alles umschließender Bin, wo dann der ganze Krempel hinterher reingesteckt wird. Das brauchen wir auf jeden Fall. Dann haben wir hier noch ein Bus. Wofür wir den brauchen, sage ich gleich. Gut, da müssen wir das GST-Init einmal laufen lassen. Das übergibt in dem Fall jetzt noch die Kommando-Zahlen-Parameter. Das bräuchten wir gar nicht. Also das könnten wir auch klammer auf, klammer zu machen. Und jetzt an der Stelle kommt was, was super praktisch ist fürs Prototyping. Das GST-Pass-Launch. Mit dem kann man so eine Pipeline, wie man sie auch mit GST-Launch ausführen kann, einfach als String direkt reinknallen. Muss sich überhaupt keine Gedanken machen, um irgendwas. Man kann da auch diese Ausrufezeichen setzen, die Elemente hintereinander rein. In dem Fall wird sogar eine Playbin genommen. Die braucht ja nur direkt die Angabe der Uri. Dann macht das hier draus eine Pipeline. Das ist super praktisch. Das 0 hier hinten, das ist für die Error-Behandlung. Also wenn das Ganze schief ginge, dann wird die Fehlermeldung ein G-Error-Pointer reingespeichert. Das ist jetzt ohne Fehlerbehandlung der Einfachkeit halber. Gut, was wir dann machen müssen, um das abzuspielen, ist, wir müssen das Ganze auf State-Playing setzen. Also wir könnten es auch manuell erst auf Ready und dann auf Pause und dann auf Playing. Aber der Core kümmert sich darum, wenn wir es direkt auf Playing setzen und wenn die anderen Zustände durchlaufen. GST Launch macht das automatisch. Also das fängt von alleine an hier mit Playing. Wenn wir das Ganze selber programmieren, müssen wir dem sagen, dass er planen soll. Und jetzt würde er schon abspielen. Das Problem ist nur, wenn ich diese beiden Zeilen nicht habe, dann läuft der C-Code ja weiter und dann im gleichen Moment oder bevor der richtig fertig ist mit dem Abspielen oder richtig angefangen hat, macht er schon wieder die Pipeline zu. Deswegen müssten wir jetzt da irgendeine Art von Main-Loop zum Beispiel haben. Also G-Lip hat G-Main-Loop, die könnte man verwenden. Oder in dem Fall hier in diesem Beispiel, das ist aus der offiziellen G-Streamer Documentation, aus dem Tutorial, der wird eben auf den Boost der Pipeline gehört und dort drin wird blockiert mit diesem Befehl, bis ein Fehler vorbeikommt oder ein Message iOS, also bis quasi das Ende des Streams, End-of-Stream von dieser .hi, die hier abgespielt wird, aus dem Internet dieser Trailer, bis es erreicht wird. Und dann geht es hier weiter mit den Free-Resources. Ansonsten, wie gesagt, wäre das hier nicht drin, würde es zwar auf Plane gehen, aber danach sofort auf Null. Wir brauchen hier irgendwas umzuwarten, damit dieses Video eben abspielen kann. Klappt es bei denjenigen, die es probiert haben? Sehr schön. Ich habe keinen Make-File dafür, tatsächlich nicht. Aber in diesem, na, wo haben wir es? In diesem Pet hier, in dem pats.chaffenburg.org, eH18, steht die Übersetzung oder der Compileraufruf drin. Also das ist im Prinzip nur der Dateiname und dann hinten halt mit den C-Flex und Lips von G-Streamer 1.0. Wer es probieren möchte. Ich glaube, ich habe das selber gar nicht gemacht. Dann muss ich mal ausführen hier auf dem Rechner. Dann laden wir mal runter und kompilen. So, jetzt haben wir hier die Datei, genau die Ausführbare. Und wenn ich das jetzt starte, dann wird er das wahrscheinlich tun. Wenn ich Internet habe, ja, läuft gut. Und jetzt ein wunderwunderbares Environmentalvariabel, mit dem man nach Fehlern suchen kann, ist GST on the Debug. Mit GST on the Debug kann man eine Maske festlegen von Elementen, die mir Debug-Messages geben sollen. Also es gibt verschiedene Levels. Es gibt Error, Warning, Info, Fixme, Debug, Log, Trace, ganz viele. Danach gibt es noch mehr. Und falls es jetzt nicht abspielen sollte, weil ich zum Beispiel kein Netzwerk habe, dann wird mir die HTTP-Source, die da irgendwo in der Pipeline steckt, bestimmt eine Fehlermeldung ausgeben. Ich kann ja jetzt mal in dem Fall mir sogar die Debug-Messages davon ausgeben lassen. Also man könnte auch die Zahl 5 schreiben, das entspricht Debug. Und dann sieht man, was dieses Element so von sich gibt. Also in dem Fall wird es jetzt hier sagen, so was wie Creating Session und Seek to Current Position. Und dann wird es mir ganz oft und ganz oft und noch öfter sagen, dass es jetzt gerade so ungefähr 16 Kilobytes gelesen hat von dem Web-Server. Hier vorne läuft immer die aktuelle Zeit der Pipeline durch. Ja, das Internet ist ein bisschen zu schwach. Genau. Ja, es schafft er nicht ganz. Jedenfalls auf die Art und Weise kriegen wir eben unsere Debug-Messages. Wir könnten hier mal Stern-Doppelpunkt-Debug machen, dann ist es richtig viel. Also das werden schnell Gigabytes. Da muss man aufpassen, weil eben so viele Elemente involviert sind hier drin, dass man also gut daran tut, diese Dinger zu filtern. Man kann die natürlich auch hintereinander rein. Also zum Beispiel, ich will von HTTPSource Debug, ich will von den möglicherweise involvierten Zinks, will ich lock und dann ist es schon mal eingeschränkt, dann ist es nicht mehr ganz zu viel. Dann sehe ich halt hier zum Beispiel, das ist jetzt abspielt hier diese einzelnen Frames mit Audio und Video und so weiter. Gut. Dann möchte ich noch kurz auf die Dokumentation verweisen, die sehr gut ist. Also man sollte sich mal mit G-Lip und G-Object auseinander setzen vorher, damit man eben dieses ganze Rüstzeug für dieses zugrunde liegende Framework hat. Und dann kann man mit den Documentationen dort loslegen, die sind wirklich gut. Also man kommt gut damit zurecht. Und wenn man eine Frage hat, kann man auch jederzeit im IRC oder auf der Mailing-Liste mit Hilfe rechnen. Wie gesagt, die Leute da sind sehr nett. Ansonsten auch gerne mich fragen. Und wer Lust hat, noch ein bisschen rumzuprobieren, G-Streamer-Elemente zusammen zu stöpseln, vielleicht können wir mal von einem zum anderen Laptop was streamen. Können wir mal testen mit RTP oder UDP oder was auch immer. Wir dürfen noch ein bisschen bleiben im Raum. Also wer Lust hat, kann das gerne tun. Ansonsten noch irgendjemand konkrete Fragen jetzt zu irgendwas? Ja, ich hätte noch eine relativ, wahrscheinlich spezielle Frage, die aber dann derzeit bei Dream entgegen kommen dürfte. Hast du Erfahrung damit, auf der Platte liegende Media-Dateien, zum Beispiel MPEG-Files oder MP4-Files, in einem CBR MPEG-TS mit korrekter PCR auszuspielen? Ich habe keine Erfahrung damit, weil wir diese Dateien, jetzt lasse ich mir mal überlegen, MP4 sagst du? Ja, MP2 oder MP4 spielt aber das ist gar nicht das Problem. Also welches Medium dann drin ist, ist gar nicht das Problem. Also es gibt ein Play-out, der liegt in G-Streamer-Bad allerdings schon. Der macht quasi ein Play-out auf, ja, dann eben Transportstrom in RTP verpackt. Der hat ein ganz schlechtes PCR-Händling, sag ich mal. Der nimmt einfach irgendwie so die DTS plus ein bisschen was, was ja schon das MPEG-Puffermodell im Prinzip einfach kaputt macht an der Stelle. Und CBR kann das sowieso schon mal gar nicht. Und ich habe nämlich das Problem, dass ich sowas brauchte oder ich hatte das Problem vor kurzem, dass ich sowas brauchte und ich habe auch angefangen, es zu schreiben. Und es hat auch funktioniert jetzt auch soweit, dass zumindest das mal dem Anwendungsfall genügt, aber es ist halt bei Weitem nicht so gut, wie es eigentlich sein sollte. Zum Beispiel hat es nur eine Source gleichzeitig. Und es wäre natürlich schön, wenn man in so einem MPEG-TS auch mehrere Services haben könnte. Und dann stellt sich noch die ganzen Fragen, wie SI-Generierung und sozeug, was dann alles dazu kommt. Deswegen wäre jetzt meine Frage, weißt du, ob andere Leute, ob es Leute gibt, die an ähnlichen Dingen arbeiten oder habt ihr an sowas mal gearbeitet bei Dream? Also wir haben diese ganzen tatsächlich MPEG-TS-spezifischen Sachen alle selber gemacht. Dafür haben wir nicht G-Streamer benutzt. Das wegen... Hatte vielleicht gute Gründe. Ja, genau. Also die MPEG-TS-Elemente sind tatsächlich nicht sonderlich gut. Aber wir können uns gerne hinterher nochmal zusammensetzen. Ja, ich komme mal vorbei. Gut, danke für deine Frage. Ja, dann ansonsten danke ich noch dem Satan für sein Tutorial, was er auf der LinuxCon Australia gehalten hat. Da habe ich nämlich ein paar Barspiele rausgenommen. Und hier ist meine E-Mail-Adresse. Wenn was ist, ich bin ja auch Fraxinas im EasterHack 18-Channel oder in G-Streamer auf Renote ISE. Und dann danke ich für eure Aufmerksamkeit. Und wie gesagt, wer möchte, bleibt nochmal da und dann können wir noch ein bisschen rum basteln. Gut.