Real‑Time RTSP Camera Streaming with FFmpeg, Nginx, and HLS for Web Integration
This article walks through the complete process of capturing a Hikvision RTSP camera stream, converting it with FFmpeg, serving it via Nginx (including RTMP/HLS modules), and finally playing the HLS stream in a Vue 3 web page using video.js, while also providing installation scripts and performance tips.
The author needed a real‑time preview of a Hikvision surveillance camera for a competition project and decided to build a custom pipeline despite being a front‑end developer.
Necessary knowledge : common streaming protocols (RTSP, RTMP, HLS, HTTP‑FLV) and the fact that the camera provides an RTSP URL.
Tools for debugging : VLC and potPlayer can directly play RTSP streams; the author recommends VLC for its lightweight nature.
Installing FFmpeg : Two methods are shown – using the Baota (宝塔) panel or manual installation. The manual steps include installing nasm first, then compiling FFmpeg from source. Example commands:
tar -xvf /www/server/mypack/nasm-2.16.01.tar.gz
./configure --prefix=[your_install_path]
make && make install ./configure --prefix=[your_ffmpeg_path]
make && make installAfter installation a symbolic link is created for easy global access, e.g.:
ln -s /usr/local/nasm/sbin /usr/local/sbin/nasmInstalling Nginx with streaming modules : The author clones the nginx-rtmp-module and nginx-http-flv-module repositories, then compiles Nginx from source with the required modules:
git clone https://github.com/arut/nginx-rtmp-module.git
git clone https://gitcode.com/winshining/nginx-http-flv-module.git
./configure \
--prefix=/usr/local/nginx \
--add-module=/path/to/nginx-http-flv-module
make && make installThe final nginx.conf includes an HTTP server on port 80, a second server on port 8888 for HLS and statistics, and an rtmp block that defines live and hls applications. The HLS application writes fragments to /www/tmp/hls and cleans up old segments automatically.
Pull‑and‑push with FFmpeg : The RTSP stream is captured and re‑packaged as HLS using a single command:
ffmpeg -re -rtsp_transport tcp -i rtsp://admin:123456@ip:port/h264/ch1/main/av_stream \
-c copy -f hls -hls_time 10 -hls_list_size 0 /www/tmp/hls/test.m3u8Running this command produces an HLS playlist that can be opened in VLC (e.g., http://ip:8888/hls/test.m3u8 ) and later embedded in a web page.
Vue 3 integration : Using the video.js player, the author creates a component that loads the HLS URL:
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue';
import 'video.js/dist/video-js.css';
import videojs from 'video.js';
const src = ref('http://ip:8888/hls/test.m3u8');
const player = ref(null);
const videoRef = ref('');
const videoInit = () => {
if (player.value) return;
player.value = videojs(videoRef.value, {
autoplay: false,
controls: true,
fluid: true,
sources: [{ src: src.value, type: 'application/x-mpegURL' }]
}, () => console.log('player init success'));
};
onMounted(() => videoInit());
onUnmounted(() => { if (player.value) { player.value.dispose(); console.log('player dispose success'); } });
</script>
<template>
<video ref="videoRef" id="my-video" class="video-js vjs-default-skin vjs-big-play-centered vjs-16-9" controls>
<source :src="src"/>
</video>
</template>Performance notes : On a low‑end machine the FFmpeg process consumes noticeable CPU and I/O, and the HLS pipeline adds roughly 10 seconds of latency. The author suggests monitoring load and possibly optimizing the pipeline.
Automation : To keep FFmpeg running 24 hours, a simple restart script is provided, along with a check script that uses pgrep to verify the process and restart it via Baota’s scheduled tasks.
Overall, the guide demonstrates a complete end‑to‑end solution for turning an RTSP camera feed into a web‑playable HLS stream, covering protocol basics, software installation, configuration, testing, front‑end integration, and operational considerations.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.