1

I'm trying to stream a live input to a web page, hosted locally.
I guess it should be pretty easy but I can't get where I'm wrong.

Here's my setup:

  • a DSLR camera with decent video capabilities
  • a Rpi running an up-to-date Raspbian

On the software side:

  • Gphoto2 (works perfectly) to grab the video and pipe it to...
  • ffmpeg, with v4l2 to get it as /dev/video0
  • Gstreamer to actually stream it (after several unsuccessful attempts with ffserver)

The following command line captures the video. It works:

gphoto2 --stdout --capture-movie | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -threads 0 -f v4l2 /dev/video0
This works quite well enough (with 2sec latency, but I could live with that, especially if I can downgrade the video quality later).

I have a http server running on port 8080 (I have several installed for test purposes: Apache, lighttpd, or even the python3 -m http.server 8080 command), this does not seem to have any influence on my problem.

Now the interesting part.

I tried a method using m3u8 file and multiple small video snips loaded and played sequentially in a js player.
Here's the test1.html

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>My live video</title>
  <link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
</head>
<body>
  <h1>My live video - simple HLS player</h1>

  <video-js id="video_id" class="vjs-default-skin" controls preload="auto" width="640" height="360">
    <source src="http://192.168.1.179:8080/playlist.m3u8" type="application/x-mpegURL">
  </video-js>
  <script src="https://unpkg.com/video.js/dist/video.js"></script>
  <script src="https://unpkg.com/@videojs/http-streaming/dist/videojs-http-streaming.js"></script>
  <script>
    var player = videojs('video_id');
  </script>
  
</body>
</html>

and the gstreamer invocation:

gst-launch-1.0 v4l2src device="/dev/video0" ! queue leaky=1 ! \
videoconvert ! clockoverlay ! \
x264enc tune=zerolatency ! mpegtsmux ! \
hlssink playlist-location /home/pi/test/ 
playlist-root=http://192.168.1.179:8080 location=/home/pi/test/segment_%05d.ts target-duration=5 max-files=5

This actually "works" but the load and latency becomes unbearable (about 30+ seconds delay).

Now, I thought it would be better to keep things simple, so I tried to simply use a HTTP stream.

So I wrote a test2.html with a <video> tag pointing to the stream I'll pass on port 9090:

<!DOCTYPE html>
<html>
        <head>
                <meta http-equiv="content-type" content="text/html; charset=utf-8">
                <title>gst-stream</title>
        </head>
        <body>
                <video width=320 height=240 autoplay>
                        <source src="http://192.168.1.179:9090">
                </video>
        </body>
</html>

And the Gstreamer invocation (I also tried the `udpsink` option, without success):
gst-launch-1.0 v4l2src device="/dev/video0" ! queue leaky=1 ! \
videoconvert ! videoscale ! video/x-raw,width=320,height=240 \
! clockoverlay shaded-background=true font-desc="Sans 38" \
! theoraenc ! oggmux ! tcpserversink host=127.0.0.1 port=9090

This only brings a blank page (the video embed space is there, just blank). Tried to open it through VLC, but this fails miserably with nothing but a "cannot open media" message. The page is actually loaded, according to the HTTP server log.
I guess nothing is actually streamed on port 9090, but Gstreamer keeps going like it was doing its job flawlessly...

What am I doing wrong?

Pylou
  • 11
  • 1
  • 3
  • You may try shorter segments: `... target-duration=1 max-files=15` – SeB Feb 27 '22 at 13:30
  • I tried, but even when watching through VLC the lowest delay I can get is over 7 secs (and this is over a gigabit ethernet connection with <2m cable length). That's why I'm now attempting to figure out how to work it with streams instead of files. – Pylou Feb 27 '22 at 15:03

0 Answers0