Verzögerungs freies Streamen (lowest streaming latency)

  • Ich bin auf der Suche nach einer funktionierenden Anleitung/Möglichkeit um so wenig wie möglich Verzögerung beim Streamen der RaspiCam zu haben.


    Die meisten Lösungen verursachen leider eine Verzögerung von 5 bis 60 Sekunden, was für mein Vorhaben inakzeptabel ist.


    Ich hatte gestern bereits > hier < etwas zu diesem Thema geschrieben, allerdings hat das compilieren der ganzen Sachen bis heute Morgen gedauert woraufhin ich dann leider feststellen musste dass das noch immer zu viel Verzögerung hat :@


    Habe bereits Lösungen mithilfe gstreamer1.2 (bzw hier) gefunden, bei dem man aber weitere 8 Stunden Wartezeit fürs Kompilieren aufbringen muss.


    Man kann diese besagte Verzögerung, und auch die Problematik die dahinter steckt, in folgendem Video bzw dessen Beschreibung stehen:

    External Content www.youtube.com
    Content embedded from external sources will not be displayed without your consent.
    Through the activation of external content, you agree that personal data may be transferred to third party platforms. We have provided more information on this in our privacy policy.


    Dabei geht es nicht um WLAN oder LAN - mein PI ist Kabelgebunden angeschlossen und das Netzwerk ist 1A.
    Mir geht es auch nicht darum unbedingt 1080p zu streamen, aber es sollte schon was zu erkennen sein, also kleiner als 640x480 möchte ich bei der Auflösung eigentlich nicht gehen und weniger als 10fps sollten es wenn möglich auch nicht werden.



    Leider verbraucht das suchen/ausprobieren nach einer brauchbaren Lösung mehr Zeit als das entwickeln des dazugehörigen Webinterfaces für meinen Roboter :wallbash:


    :helpnew:



    [hr]
    [hr]



    //EDIT: Mittlerweile haben wir in diesem Thread einige brauchbare Lösungen herausgefunden oder entwickelt, die ich hier direkt im ersten Beitrag einpflege bevor sie untergehen.
    Die hier gezeigte Reihenfolge ist nicht von wegen "erste ist die Beste" oder so. Welche für Euch die beste ist müsst ihr selber herausfinden :rolleyes:


  • https://github.com/waveform80/pistreaming


    edit:


    Probier sonst mal folgendes (sofern du Zeit und Lust hast)


    Code
    pip install bottle
    pip install picamera


    Neue Datei zB app.py


    oder

  • Hallo zusammen,
    meigrafd,
    vorab:
    ich habe kein Kamera-Modul und kenne mich mit Streamen überhaupt nicht aus! Ich bin aber Theoretiker und lese viel ...


    benutzt du für dein Anliegen in irgendeiner Weise das Programm 'raspistill' ?


    wenn ja, könnte folgendes hilfreich sein:
    das Programm 'raspistill' ist sehr langsam. Niklas Rother hat eine schnellere Version geschrieben. Bei BitBucket als ausführbare Binärdatei herunterzuladen (nach 'RaspiFastCamD' suchen) ...


    Viel Glück !


    so long
    Perlchamp

    --- wer lesen kann, ist klar im Vorteil ---

    --- Freude entsteht aus Mangel an Information ---

    --- Scheiße ist, wenn der Furz etwas wiegt ---


  • Ja ... unser Tüftler ;) ...


    welchen Datendurchsatz hast Du auf der verwendeten Verbindung?
    Das ist schon mal deshalb interessant, weil Du Dir dann ausrechnen kannst, bei wieviel Mbit/s Schicht ist.
    Bei 640x480 kommst Du auf 307200 Bildpunkte. Bei 16 Bit Farbtiefe bist Du schon bei 4.915.200 Bits und das dann bei 10 fps = 49.152.000, also gut 49 Mbit/s.
    Das läppert sich ;) ...


    BTW: ich dachte zunächst, mit 2.4GHz Funk käme man auf eine höhere Übertragungsrate (wegen der höheren Frequenz ... da haben halt mehr Bits Platz). Pustekuchen. Das Maximum sind lt. meiner Recherchen 2 Mbit/s ... also leider auch keine Option :(


    //EDIT:
    Ich denke das wird wohl auf einen Kompromiss zwischen Bildqualität/Framerate rauslaufen. Evtl. ist es sogar schneller, eine Kompression wie H264 zu verwenden. Ich kann mich erinnern mal eine MPEG4 Komprimierung getuned zu haben, dass der Datenstrom als Videokonferenz-Lösung über eine einzelne ISDN-Leitung (Latenzzeit max. 0.5 sec) zu verwenden war. Allerdings war das Maximum 320x240 Pixel ... Farbtiefe weiss ich leider nicht mehr.



    cu,
    -ds-

  • Ich hab jetzt erst mal einen Tip von Perlchamp versucht der auf RaspiFastCamD basiert - ein umgeschriebenes raspistill. Problem daran ist nur dass das auf einer alten Version basiert (aber Teile von der Anpassung wurden anscheint auch schon in die offizielle übernommen)



    Das kompilieren dauert ca. 30min. Mithilfe eines Scripts wird der Umgang erleichtert, da das veränderte Programm auf ein USR1 Signal wartet bevor ein Bild geschossen wird....
    Und an dieser Stelle beginnt das Problem: Das ist kein Streaming wenn ich erst jedesmal ein Bild anfordern muss :(
    Also fällt dieser Ansatz flach.



    picamera bzw pistreaming basiert auf Python, was aber meines Erachtens von Grund auf bereits langsam ist bzw langsamer als in C/C++ kompilierte Programme.
    Schade nur das ich das auch nicht ans laufen gekriegt hab - naja..
    Fällt also eigentlich auch flach, auch wenn sich der Umfang recht gut liest aber leider fehlen mir auch Beispiele wie man das in eine Webseite einbaut.



    Aber dadurch bin ich auf ein anderes Paket aufmerksam geworden: ws4py. Ob ich damit vielleicht mein tornado Problem lösen kann :huh: :fies:


    [hr]



    dreamshader: Laut RaspberryPI Foundation schafft das Camera Module bei 1080p -> 15fps. Frag mich aber bitte nicht wie viel MBit/s das entspricht :D


    [hr]


    Habt ihr noch weitere Vorschläge? :(

  • Hi,


    ...
    dreamshader: Laut RaspberryPI Foundation schafft das Camera Module bei 1080p -> 15fps. Frag mich ...


    ich red' nicht vom Kamera-Modul sondern von Deiner Netz-Anbindung ...


    //Nachtrag: Ich fürchte, Du verwechselst da was. Eine "normale" DVD hat, wenn ich mich recht erinnere, eine Bitrate von ca. 4 bis 10 Mbit/s.
    Also weniger als ein Fünftel von der Datenmenge, die Du da herumschaufelst ;) ... Da kommt nämlich MPEG2 bzw. die Kompression ins Spiel.


    cu,
    -ds-

  • Ne, ich will ja die RaspiCam an den lokal laufenden Webserver streamen, nicht das HDMI Signal des RaspberryPIs..



    Hab bestimmt 20 verschiedene Anleitungen gefunden die alle verschiedene Wege beschreiben, aber mehr als die Hälfte hat entweder gar nicht funktioniert oder hatten eine heftigere Verzögerung von >20 Sekunden...


    Ich hab jetzt nach 4 Tage werkeln endlich mal etwas zum laufen gekriegt was beinahe zufriedenstellend sein könnte - allerdings muss ich ffmpeg noch mal mit --disable-librtmp recompilieren damit der ffmpeg-internal RTMP support verwendet wird. Das soll nochmals ca. 500ms Verzögerung ausmachen.


    Leider dauert das kompilieren von ffmpeg gut 5 Stunden (trotz Übertaktung) :(


    Aktuell habe ich allerdings eine Verzögerung von ca. 2 Sekunden.
    Dabei verwende ich folgenden Code:


    Wie das schon vermuten lässt verwende ich auf dem PI nginx mit dem rtmp Module und zum abspielen/anzeigen den Strobe Media Player.


    Aber wie gesagt - 2 Sekunden Verzögerung ist immer noch für mein Vorhaben inakzeptabel - aber bevor der ein oder andere denkt das läge an zu wenig Power: CPU Last liegt wärend des abspielens bei nur 7% inkl. nginx und Ram wird insg. nur 56MB verwendet..






    //EDIT: Die Verzögerung scheint sich erstaunlicherweise zu verringern sobald ich die -g Option raus nehme und das ganze ne Zeitlang laufen lasse und nun ist echt schon beinahe perfekt ;)
    Deshalb poste ich hier mal was ich insg. gemacht habe:



    Code
    apt-get update
    apt-get install -y curl build-essential libpcre3-dev libpcre++-dev zlib1g-dev libcurl4-openssl-dev libssl-dev git-core screen


    Benötigte Pakete fürs spätere Kompilieren usw.


    Code
    apt-get -y install nginx
    apt-get -y remove nginx
    apt-get clean

    Sieht komisch aus, wird aber gemacht damit die /etc/init.d/ Scripts vorhanden sind - denn ich kompilier mir den nginx lieber selber (aktuellste Version)


    Code
    cd /usr/src
    git clone git://source.ffmpeg.org/ffmpeg.git
    cd ffmpeg
    screen
    ./configure --disable-librtmp && make && make install

    Da dies am längsten dauert machen wir das lieber sofort. Schließt dann das Terminal Fenster damit screen es auffängt. In ca. 5 Stunden könnt ihr dann mit dem Befehl screen -r wieder in den screen wechseln und gucken ob er fertig ist :)


    Code
    cd /usr/src
    git clone https://github.com/nginx/nginx
    cd nginx
    git clone https://github.com/arut/nginx-rtmp-module.git
    ./configure --prefix=/var/www --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --pid-path=/var/run/nginx.pid --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-http_ssl_module --without-http_proxy_module --add-module=/usr/src/nginx/nginx-rtmp-module
    mkdir -p /var/www && chown www-data:www-data /var/www && chmod 775 /var/www
    make && make install

    Das dauert ca. 15 Minuten.


    Nun die Konfiguration anpassen: nano /etc/nginx/nginx.conf


    Die default Seite anpassen: nano /etc/nginx/sites-enabled/default


    Pakete für nginx installieren:

    Code
    apt-get install php5-fpm


    Optional:

    Code
    apt-get install php5-cgi php5-mysql php5-curl php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-mhash php5-ming php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl


    Script zum starten des Streams anlegen: nano /usr/local/bin/rtmp-nginx.sh && chmod a+x /usr/local/bin/rtmp-nginx.sh

    Die Zeile mit FFREPORT sorgt dafür das ein Logfile angelegt wird was ihr kontrollieren solltet. Wenn es aussieht als würde es funktionieren würde ich diese Zeile im Script auskommentieren da das Log nach ner Zeit ziemlich groß wird!


    Nun zu dem WWW Teil.
    Ihr braucht 3 Dateien:

    • Eine HTML Datei, ich verwende hier stream.html
    • StrobeMediaPlayback.swf
    • swfobject.js

    stream.html


    StrobeMediaPlayback.swf und swfobject.js könnt ihr hier laden: https://github.com/denivip/osm…aster/StrobeMediaPlayback
    (swfobject.js liegt im lib Ordner)



    Dem www-data Benutzer erlauben auf die video Gruppe zuzugreifen:

    Code
    usermod -G video -a www-data


    Dienste starten:

    Code
    /etc/init.d/nginx restart
    /etc/init.d/php5-fpm restart



    Nun hatte ich leider Zeitweise das Problem dass nginx nicht das /usr/local/bin/rtmp-nginx.sh Script selber gestartet hat, also muss man das teilweise selber machen.. da bietet sich zB nohup /usr/local/bin/rtmp-nginx.sh & für an.


    Wenn man jetzt die stream.html aufruft sollte es nach ca. 2 Minuten einen fast Verzögerungsfreien Stream geben - ich schätze zZt auf knapp 1 Sekunde und nachdem ich ffmpeg neu kompiliert hab wird das hoffentlich auch noch weniger :D

  • Also ich verwende ja nginx und da das Script /usr/local/bin/rtmp-nginx.sh leider nicht mit nginx gestartet wird (obwohl so eingestellt), hab ich ein screen dafür laufen..


    Öffne ich mein Web Interface wo der Stream mit so gut wie keiner Verzögerung angezeigt wird, sieht die Auslastung wie folgt aus:


    Laut top (1sek update Intervall) verbraucht ein "nginx: worker process" ca. 3 bis 4,8% CPU Leistung, von insg. 4 worker processes aber die anderen verbrauchen zZt nix. 0,5% RAM verbraucht der eine worker.
    ffmpeg verbraucht 1,3 bis 2,9% CPU Leistung. RAM Auslastung liegt bei 1,5%.
    raspivid verbraucht 1 bis 2% CPU Leistung. RAM Auslastung liegt bei 0,3%.


    Das deckt sich auch mit meiner cpu.php die mir das anzeigt: The average CPU load is: 8.819%


    Geht man nach > diesem Beitrag < um die GPU-RAM-Auslastung anzuzeigen, stehen von 128MB zugewiesenem RAM insg. 108MB zur Verfügung und 89MB sind noch Frei.


    Mein PI ist aber auch übertaktet:

    Code
    root@raspberrypi:~# cat /boot/config.txt 
    arm_freq=950
    core_freq=250
    sdram_freq=500
    over_voltage=6
    gpu_mem=128
    start_x=1


    Wie man sieht verwende ich aber kein force_turbo, er ist also nicht die ganze Zeit übertaktet sondern arm_freq liegt aktuell bei 700MHz


    Bekanntlich ist die RaspiCam aber direkt an die GPU angeschlossen und die macht die meiste Arbeit - mir ist aber zZt leider keine Möglichkeit bekannt die GPU Auslastung anzuzeigen :(

  • Hey meigrafd,


    ich hab' eine Picam schon seit ca. 1/2 Jahr hier rumliegen und bastle gerade an einer Kipp-/Schwenk-/Drehvorrichtung und würde das Ding dann gerne mal in Betrieb nehmen.


    Kann ich Deine Auflistung ab


    //EDIT: Die Verzögerung scheint sich erstaunlicherweise zu verringern sobald ich die -g Option raus nehme und das ganze ne Zeitlang laufen lasse und nun ist echt schon beinahe perfekt Icon_wink
    Deshalb poste ich hier mal was ich insg. gemacht habe:


    in Posting #8 als Grundlage für einigermassen brauchbares streaming verwenden oder hat sich da noch was Neues ergeben?
    Wie sieht es mit der Konfiguration aus? Ich hab' jetzt nicht noch mal alles von Anfang an durchgelesen ... muss da evtl. was mit der Speicherzuordnung geändert werden, was in o.g. Beschreibung nicht erwähnt ist?
    Wär vielleicht wert die Anleitung mal in die Tuts zu übernehmen ... das geht sonst unter und wäre schade drum. Hätte ich nicht zufällig gewusst, dass Du das mal was verfasst hattest, hätte ich den Beitrag nur über die Suche gefunden.
    cheers,
    -ds-

  • Hm ne ich glaub ab dem EDIT steht alles was beachtet werden muss ;)
    Hab aber ehrlich gesagt nicht weiter geschaut obs noch was besseres/einfacheres gäbe, war mit dem Ergebnis dann eigentlich recht zu frieden - wie gesagt war die Verzögerung an geringsten wenn das ein paar Minuten lief :)

  • Na danke jedenfalls ... ich fahr' das grad mal nach.
    Wird sich zeigen, wie es dann läuft ... :)
    Ich hatte eh schon überlegt, ob ich mir nicht schnell noch einen eigenen Stream-Server über udp bastle ... aber ich glaube, die Arbeit schenk' ich mir erst mal.
    Das heb' ich mir für eine andere Cam auf ... ich hab' da mal wieder was beim Chinamann entdeckt: eine Cam mit 640x480 für ca. 4,- Euronen ... die kann evtl. sogar über CSI angesprochen werden. Eine zweite mit 640x480 und SPI hab' ich auch noch hier ... na mal sehen ... :s


    cheers,
    -ds-

  • So ... ich habe das mal alles nach Deiner Anleitung durchlaufen lassen ...
    hat alles wunderbar und ohne Fehler funktioniert.
    Sieht auch erstmal alles recht vielversprechend aus und beim Starten von nginx geht auch brav das Kamera-Lämpi an.


    Aber: das streamen funktioniert nicht ...
    ich hab's auf dem RPi mit midori probiert, mit Firefox unter Ubuntu, mit Chromium unter Ubuntu und von meinem Tablet aus ... nix ...


    In Midori passiert gar nix,
    Firefox scheint in den fallback zu laufen

    Code
    <!-- fallback for devices without Flash is HLS streaming -->
      <video src=/hls/live.m3u8 width=1280 height=720 autoplay controls></video>


    und erzählt was davon, dass der MIME Typ nicht unterstützt wird.
    Chromium sieht noch am besten aus: Der Hintergrund ist schwarz, wie bei einem Video erwartet, unten ist eine Leiste mit play/pause Button und einer Zeitleiste.
    Das war's aber auch schon ... die Zeit unten rechts steht bei 0:00 und bleibt da auch.


    naja ... werde ich mir wohl mal bei Gelegenheit eine Alternative suchen.
    Cheers,
    -ds-

  • Aaaalso ...


    ich hab' da was im Netz ausgegraben, das funktionierte auf Anhieb ziemlich überzeugend.
    Allerdings war der Delay auch etwa fünf Sekunden.
    Ich habe dann einfach mal die Bildgröße auf 640x480 beschränkt und siehe da, es gibt fast keine Verzögerung. Und das Ganze mehr oder weniger mit Bordmitteln :) ...


    Zunächst auf einem Linux-Rechner folgendes Kommando eingeben:

    Code
    nc.traditional -l -p 5000 | mplayer -fps 60 -cache 1024 -


    Damit wird ein netcat-Listener auf Port 5000 gestartet, der seine Daten an mplayer weitergibt ...
    nc.traditional ist der netcat. Möglicherweise muss der erst noch installiert werden:

    Code
    sudo apt-get install netcat-traditional


    Auf dem RPi dann folgendes Kommando eingeben:

    Code
    raspivid  -w 640 -h 480 -o - -t 10000000 | nc.traditional 192.168.1.109 5000


    läuft bei mir erstaunlich gut :) ...
    cu,
    -ds-

  • Hey,


    ich habe dein Tutorial im Beitrag 8 durchgezogen. Irgendwie spinnt etwas beim nginx restart. Es kommt folgende Fehlermeldung


    "Restarting nginx: nginx: [emerg] unknown directive "rtmp_stat" in /etc/nginx/sites-enabled/default:21"


    Jemand ne Idee? Habe das Tutorial einfach blind durchgezogen und die conf per copy-paste eingefügt.


    Hoffentlich kann mir jemand helfen und erspart mir somit stundenlanges googlen;)


    danke.


    grüße pipirasp

  • Hallo,


    Ich habe mich mit diesem Thema vor einiger Zeit auch mal befasst. Mein Ergebnis war für meine Anwendung absolut zufriedenstellend. (ca. 30FPS, gute Auflösung, kein Delay) einziger kleiner Nachteil, ich brauche auf dem Zielrechner recht viel Arbeitspeicher(ca. 1GB).


    So funktionierts:


    raspivid --->Netcat----> Socket zu JavaProgramm(TCP Socket server ist das Java Programm) ---> Java Xugglerlib ---> Stream als Bild zeichnen.

  • Hallo zu diesem Thema habe ich folgendes gefunden und es funktioniert


    Hast du das von dir gepostete Tutorial durchgeführt und ausprobiert wie viel Verzögerung es gibt?


    Weil es gibt viele Wege die "funktionieren" .. Allerdings nicht wirklich Verzögerungsfrei.
    Wie ich eingangs schon erwähnte habe ich ca. 20 verschiedene Möglichkeiten selber ausprobiert, aber keine davon (bzw nur eine) hatte eine Verzögerung von weniger als 1ner Sekunde. Da war auch motion bei (wie es von deinem erwähnten Tutorial verwendet wird), aber nicht nur das motion schon ziemlich alt ist, war das auch nicht wirklich akzeptabel.


    Also: "funktionieren" bedeutet nicht automatisch 'lowest latency'