Tuesday, July 8, 2025

How to Stream RTSP / Webcam / IP Camera Over the Web

I had a Hikvision IPC-B120 that provides a simple RTSP stream, which I could view in VLC. I also wanted to see my Logitech BRIO’s feed in a browser—without having to start a Video Call session.


To do this, I pull the RTSP (video/audio) feed from each camera, pipe it through FFmpeg to convert it into an MPEG-TS stream, and then serve it over WebSocket using JSMpeg. On my Raspberry Pi 5, I run two systemd services (one per camera) that use websocat to listen for WebSocket connections. When a client connects, websocat launches FFmpeg to start the conversion and forwards the stream; when the client disconnects, FFmpeg automatically stops.




# /etc/systemd/system/rtsp-ws.service

[Unit]

Description=On-demand WebSocket→FFmpeg bridge for JSMpeg

After=network.target

[Service]

User=pi

Group=pi

ExecStart=/usr/local/bin/websocat \

  --binary \

  --exit-on-eof \

  -s 127.0.0.1:10000 \

  sh-c:'/usr/bin/ffmpeg -hide_banner -loglevel error -rtsp_transport tcp -i "rtsp://user:pass@Local.IP.Camera:Localport/URI/channels/101" -f mpegts -codec:v mpeg1video -bf 0 -r 25 pipe:1'

Restart=on-failure

[Install]

WantedBy=multi-user.target


# /etc/systemd/system/webcam-ws.service

[Unit]

Description=On-demand WebSocket→FFmpeg bridge for Brio webcam

After=network.target

[Service]

User=pi

ExecStart=/usr/local/bin/websocat \

  --binary \

  --exit-on-eof \

  -s 127.0.0.1:10001 \

sh-c:'WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000 /usr/bin/ffmpeg -hide_banner -loglevel error \

  -f v4l2 -framerate 30 -video_size 1920x1080 -i /dev/video0 \

  -f alsa -ac 2 -ar 44100 -i default \

  -f mpegts \

  -codec:v mpeg1video -bf 0 -r 30 \

  -codec:a mp2 \

  pipe:1'

Restart=on-failure

[Install]

WantedBy=multi-user.target



You can then create the related websocket proxy in apache and create a player file in html:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Live Camera (JSMpeg)</title>
<style>
/* fullscreen black background, centered content */
html, body {
margin: 0; padding: 0;
width: 100vw; height: 100vh;
background: #000;
display: flex;
align-items: center;
justify-content: center;
}

/* wrapper to constrain size, max 90% of viewport */
.player-container {
width: 90vw;
max-width: 1280px; /* or whatever max you like */
max-height: 90vh;
}

/* canvas will fill the container but keep its own aspect‐ratio */
.player-container canvas {
width: 100%;
height: auto;
display: block;
}
</style>
</head>
<body>
<div class="player-container">
<canvas id="videoCanvas"></canvas>
</div>

<script src="/jsmpeg.min.js"></script>
<script>
const url = (location.protocol==='https:'?'wss://':'ws://')
+ location.host + '/my-ws-prefix';

new JSMpeg.Player(url, {
canvas: document.getElementById('videoCanvas'),
autoplay: true,
audio: false
});
</script>
</body>
</html>

5 comments:

  1. This guide made streaming so simple! I finally got my IP camera working live on my website thanks to the clear steps. Hosting Mastery Hub is a real game-changer for beginners like me!

    ReplyDelete
  2. Mos’s Blog in Technology shares insights, tutorials, and innovations shaping the future of the tech world. With switch free game , readers can explore interactive content that makes learning about technology more engaging and practical.

    ReplyDelete
  3. Fast internet powers modern lifestyles. page

    ReplyDelete
  4. This was an enjoyable and educational read. link

    ReplyDelete

How to Stream RTSP / Webcam / IP Camera Over the Web

I had a Hikvision IPC-B120 that provides a simple RTSP stream, which I could view in VLC. I also wanted to see my Logitech BRIO’s feed in a ...