Robustes H264 Streaming von Pi -> HTML5

Krautmaster

Fleet Admiral
Registriert
Feb. 2007
Beiträge
24.238
Hallo liebe Community,
ich weiß das Netz ist brutal voll von PI und Streaming Zeug, aber ich würde gerne hier in meiner Home Base meine Möglichkeiten zusammentragen und die beste Lösung umsetzen.

Dabei sollte etwas wie das hier rumkommen,
das ich letzten Sommer auf YT gestreamed habe - aber gerne auf eigenem Server. Domain und Server hab ich eh...

Ziel wäre einen möglichst schlanken (Bandbreite) und zugleich robusten Stream zu bekommen, der universell an quasi jedem modernen Browser läuft ohne YT oder sowas.

Hardware:
Pi Zero (präferierte Plattform)
Pi 3a (könnte als Backend Webserver zum Kapseln fungieren)
Xeon D Server mit Hyper V für VMs jeder Art

Wenn es der Pi nicht direkt gut schafft und die Sache robuster mit Hilfe einer VM ist dann kann ich mir vorstellen dass der Pi nur mit Raspivid einen Stream an einem Port bereitstellt oder an eine VM sendet und diese das raw h264 mit Musik unterlegt und auf Nginx oder Apache ne einfache HTML 5 Seite bereitstellt.

Wie würdet ihr das umsetzen? Ich denke Ziel müsste wohl eher h264 statt mjpeg sein oder?

Würde morgen Mal die Commandlines posten die ich für den YT Stream einsetzte. Gstreamer zu HTML5 hat bisher nicht hingehauen.

Vielen Dank für eure Hilfe.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: madmax2010
Meine Meinung: Ich würde meine private Internetleitung nicht für so etwas verschwenden...

Aber rein Interesse halber: Wie viel Upload hast du denn?
 
40 aber der Stream braucht ~3 Mbit, das fällt nicht ins Gewicht und je nach Umsetzung fällst es nur an wenn ich drauf schauen weil ich zB wissen will in welcher Zone der Kleine unterwegs ist. Außerdem geht's nicht ums wollen sondern und wie ;)
 
Also vielleicht habe ich dich falsch verstanden.
Es geht dir nur um das "Tracking" bei dir? Okay... das ist dann wieder was anderes.
 
Beides. Der kleine hat nen GPS Sender am Pi Zero, 2 Boxen für den Raspotify und die Cam. Ich hab vor mir ne kleine HP zu basteln die mir quasi ne Heatmap des Geländes ausgibt wo er wie oft wie lange gemäht hat und gleichzeitig soll diese auch nen Livestream einbinden. Postion usw wird bereits gesendet. Raspotify geht auch. Wenn er steht will ich uU da er eh die Haustüre im Blick hat noch nen Motion Detect machen, da gibt's ja fixe Sachen dazu.

Wenn er unterwegs ist soll aber der Livestream starten und es geht mir in erster Linie darum diesen in die HP einzubinden - ohne eine Umweg über YouTube oÄ.

Der Worx hängt schon an ioBroker, ich bekomme also auch schon Nachrichten über Telegramm. Es ist mehr oder minder der x264/h264 Stream der nicht so will. Wenn ich es richtig verstanden habe muss ich den raw Datenstrom von der Cam ja noch kapseln, nicht zwingend encodieren aber eben Webtauglich machen.
 
Zuletzt bearbeitet:
Am einfachsten wäre es wohl mit dem offiziellen Kameramodul. Das auf den 3 A pappen und eine der drölfzig Anleitungen aus dem Netz nehmen.
 
Jep und bisher führte da keine Anleitung so wirklich ans Ziel.

Was bisher problemlos lief war der Stream Richtung Youtube:

Code:
raspivid -o - -t 0 -w 1296 -h 972 -b 3000000 -md 4 -pf high -lev 4.2 -vs -awb auto -drc high -mm backlit -ev 3 -fps 25 -g 50 | ffmpeg -filter_complex "amovie=mex.mp3:loop=1000,asetpts=N/SR/TB,apad,aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=mono" -f h264 -i - -vcodec copy -acodec aac -g 50 -strict experimental -bufsize 2000k -f flv rtmp://a.rtmp.youtube.com/live2/XXXXXXXXXXXXX

Ich habe bei einem Fehler auch den Stream erneut gestartet, z.B. wenn das Wifi unterbrochen war. Das läuft aber nur begrenzt und ich hätte es gerne auf eigener Subdomain am laufen.

Dann hab ich es nach folgender Anleitung versucht:
https://blog.ronnyvdb.net/2019/01/2...mp4-from-the-raspberry-pi-to-any-web-browser/

Wenn ich das richtig verstehe wird dabei mittels gstreamer der raspivid Stream in ein HTML5 taugliches Format gepackt und dann mittels kleinem python webserver bereitgestellt.

Kommt allerdings beim Zugriff über den Browser das:
Code:
running command: (echo "--video boundary--"; raspivid -w 1920 -h 1080 -fps 30 -pf high -n -t 0 -o -;) | gst-launch-1.0 -e -q fdsrc fd=0 ! video/x-h264,width=1920,height=1080,framerate=30/1,stream-format=byte-stream ! h264parse ! mp4mux streamable=true fragment-duration=10 presentation-time=true ! filesink location=/dev/stdout
starting polling loop.
looping...
ERROR: from element /GstPipeline:pipeline0/GstMP4Mux:mp4mux0: Could not multiplex stream.
Additional debug info:
gstqtmux.c(4559): gst_qt_mux_add_buffer (): /GstPipeline:pipeline0/GstMP4Mux:mp4mux0:
Buffer has no PTS.
ERROR: from element /GstPipeline:pipeline0/GstFdSrc:fdsrc0: Internal data stream error.
Additional debug info:
gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:pipeline0/GstFdSrc:fdsrc0:
streaming stopped, reason error (-5)
ERROR: from element /GstPipeline:pipeline0/GstMP4Mux:mp4mux0: Could not multiplex stream.
Additional debug info:
gstqtmux.c(4559): gst_qt_mux_add_buffer (): /GstPipeline:pipeline0/GstMP4Mux:mp4mux0:
Buffer has no PTS.
ERROR: from element /GstPipeline:pipeline0/GstMP4Mux:mp4mux0: Could not multiplex stream.
Additional debug info:
gstqtmux.c(4559): gst_qt_mux_add_buffer (): /GstPipeline:pipeline0/GstMP4Mux:mp4mux0:
Buffer has no PTS.

jemand ne Idee?

Kann man statt gstreamer ggf auch ffmpeg nehmen?

Weitere Fragen:
  • wie bekomm ich bei der Variante Audio dazu
  • in wie fern kann ich ggf am Webserver mit speziellen "Playern" arbeiten die dann den Stream auf ner Seite präsentieren?
Pi -> RAW Video (UDP? RSP?) -> Webserver (+ Audio + h264 Container?) -> Anwender

Ich meine dass es mit MJPEG ziemlich einfach geht aber da das Cameramodule 2 ja direkt h264 mit niedrigerer Bandbreite kann sollte das ja das Mittel der Wahl ein, gerade da der Pi Zero mit 2.4 Ghz Wifi im Garten öfters mit diesen Bandbreiten auskommen muss.
 
Zuletzt bearbeitet:
kann ich ggf mit jwplayer die Sache umsetzen?

Auf meiner Webserver VM also sowas wie:

Code:
  GNU nano 4.8                                                                                                                                    index.html                                                                                                                                     Verändert 
<!DOCTYPE html>
<html lang="de">
<head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <title>Demo Title</title>


</head>
<body>
<script type="text/javascript" src="https://cdn.jwplayer.com/libraries/I2d75JUG.js"></script>
<div id="myElement">Loading the player...</div>
<script type="text/javascript">
jwplayer("myElement").setup({
file: "rtmp://alfonso/live/streamname",
    });
</script>

</body>
</html>

und an meinem Pi die entsprechende FFMPEG line

Wie müsste man das geschickterweise aufbauen?

Der Pi heißt alfonso. Der Webserver ist von extern erreichbar. Ich will ja dass die Sache Robust ist. Muss dann der Pi an den Webserver (im Lan) senden und dieser präsentiert die Sache Stabil nach extern? Wie müssten die Lines aussehen?
 
Vielleicht hilft mir diese Anleitung
https://stackoverflow.com/questions/29674906/play-a-video-from-remote-computer-using-nginx-rtmp

Wenn ich das richtig verstehe müsste mein Pi dann in der FFMPEG Line als Ziel meinen lokalen Webserver angeben der zb mit Nginx auf den rmtp Port hört.

Dieser stellt dann zb den jwplayer bereit. Dennoch muss damit es tut vermutlich der rmtp Port als auch der vom Webserver offen sein.

Prinzipiell hab ich schon nen Reverse Proxy in meiner DMZ, dieser könnte ja den jwplayer hosten (eingebettet von extern) und in der DMZ könnte der PI den FFMPEG Datenstrom an den Reverse Proxy senden oder?
 
Der jwplayer ist wie's scheint nicht für lau... Zu sein. Ich wäre euch für Lösungsansätze dankbar wie ich am besten den h264 Stream der Pi Zero Cam auf eine quasi leere HTML5 Seite in Nginx bekomme oÄ. Ich werde nicht so wirklich schlau aus dem Überangebot im Netz.
VideoJS?
 
okay ich komme der Sache näher.

Basis ist dieses Konstrukt:
https://github.com/benjamin-maynard/Pi-Camera-in-a-box

Ich habe eine VM die als RTPM Server fungiert in die DMZ gepackt und den Port 1935 auch auf diese geroutet.

Code:
 raspivid -o - -t 0 -w 1296 -h 972 -b 3000000 -md 4 -pf high -lev 4.2 -vs -awb auto -drc high -mm backlit -ev 3 -fps 25 -g 50 | ffmpeg -filter_complex "amovie=mex.mp3:loop=1000,asetpts=N/SR/TB,apad,aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=mono" -f h264 -i - -vcodec copy -acodec aac -g 50 -strict experimental -bufsize 2000k -f flv rtmp://rtpmserverIP/show/stream

Auf dem webserver selbst ist NGINX mit rtpm nach diesem Vorbild:

https://github.com/benjamin-maynard...er/containers/nginx-rtsp/resources/nginx.conf
https://github.com/benjamin-maynard...ainers/nginx-rtsp/resources/web-ui/index.html

+ die passenden js files.

Läuft soweit auch mit HTTPS 2.
 
aktuell reißt der Strom ja ab wenn der Pi nicht mehr via FFMPEG an den Server senden kann, dann muss die FFMPEG Sache neugestartet werden.

Kann man das irgendwie auch ich sag mal über UDP oder nen fixen Port am PI robuster aufsetzen dass der Webplayer das quasi fortlaufend anzapft und abgreift und wenn grad nix kommt dann kommt halt nix und wenn wieder was über die Leitung geht spielt es der Player wieder ab?

Außerdem ist die Latenz so brutal hoch. Ggf wäre es smarter das anders aufzudröseln und erst am Webserver mit dem Xeon im Rücken die Sache zu kapseln und auf den Stream zu legen. Also zb AAC dazu packen und nur das Video Stream Bild vom PI an den HTML WebServer zu senden.
 
Schon mal UV4L probiert?
habe mir damals damit ein Babyphone gebaut, Sound habe ich damals separat über mumble laufen lassen hat gut geklappt.
 
Zuletzt bearbeitet:
Zurück
Oben