FFMPEG to potężne narzędzie umożliwiające przetwarzanie multimediów, w tym transmisje strumieniowe na żywo. W tym wpisie pokaże jak skonfigurować FFMPEG do strumieniowania wideo na żywo z kamery IP i stworzyć transmisję na żywo w formacie HLS (HTTP Live Streaming), który jest szeroko wspierany przez przeglądarki internetowe i odtwarzacze multimedialne.
Przykładowa konfiguracja kamery IP
Zanim przejdziemy do FFMPEG, warto poznać szczegóły techniczne kamery, z której będziemy pobierać obraz. Poniżej przykładowa specyfikacja kamery IP:
- Rozdzielczość: 4MP (2688×1520)
- Obiektyw: f = 2.8 ~ 12 mm
- Kąt widzenia:
- Poziomy: 33° ~ 105°
- Pionowy: 18° ~ 54°
- Przekątny: 38° ~ 125°
- Zasięg IR: 30m (idealny do monitoringu nocnego)
- Funkcje dodatkowe: WDR Pro, kompresja H.264
Pobranie strumienia RTSP z kamery IP
Większość kamer IP dostarcza strumień wideo za pośrednictwem protokołu RTSP (Real-Time Streaming Protocol). Możesz pobrać ten strumień za pomocą FFMPEG. W tym przykładzie zakładamy, że strumień kamery jest dostępny pod adresem:
rtsp://admin:admin@192.168.1.176/onvif2
Konfiguracja FFMPEG do streamowania na żywo
Do rozpoczęcia transmisji na żywo z kamery IP, musimy skonfigurować FFMPEG. W tym przykładzie wykorzystujemy kodek H.264, aby zoptymalizować jakość obrazu oraz przepustowość. Strumień zostanie przekonwertowany na format HLS, który umożliwia łatwe dostarczenie wideo do przeglądarek i odtwarzaczy.
Przykładowa komenda FFMPEG, którą możesz uruchomić w terminalu:
ffmpeg -i "rtsp://admin:admin@192.168.1.176/onvif2" \
-c:v libx264 \
-preset faster \
-crf 20 \
-maxrate 3M \
-bufsize 6M \
-r 30 \
-g 120 \
-c:a copy \
-hls_time 10 \
-hls_list_size 10 \
-hls_flags delete_segments \
-start_number 1 \
camera-001.m3u8 \
1> camera-001.log1 \
2> camera-001.log2 &
-i „rtsp://…”: Ścieżka do strumienia RTSP z kamery IP. W tym przykładzie adres RTSP zawiera dane logowania do kamery
-c libx264: stawienie kodeka wideo na H.264, co pozwala na efektywną kompresję strumienia
-preset faster: Ustawia szybkość kodowania wideo. Możesz wybrać inne ustawienia, takie jak „medium” lub „slow”, zależnie od dostępnych zasobów
-crf 20: Określa jakość wideo, gdzie niższa wartość oznacza lepszą jakość (0 to bezstratna jakość)
-maxrate 3M: Maksymalna przepustowość strumienia (3 megabity na sekundę).
-bufsize 6M: Bufor dla przepustowości strumienia
-r 30: Liczba klatek na sekundę (30 FPS)
-g 120: Odstęp między klatkami kluczowymi (Keyframes). Wartość 120 oznacza, że klatka kluczowa jest ustawiana co 4 sekundy (30 FPS * 4 sekundy)
-c copy: Kopiowanie ścieżki audio bez transkodowania
-hls_time 10: Długość segmentu HLS w sekundach (10 sekund)
-hls_list_size 10: Liczba segmentów w pliku listy odtwarzania (m3u8).
-hls_flags delete_segments: Automatyczne usuwanie starszych segmentów, aby zmniejszyć obciążenie dysku
camera-001.m3u8: Nazwa wygenerowanego pliku listy odtwarzania HLS.
1> camera-001.log1 2> camera-001.log2: Zapisuje logi do plików tekstowych (osobno dla standardowego wyjścia i błędów)
&: Uruchamia proces w tle
Odtwarzanie strumienia HLS
Po uruchomieniu powyższej komendy, FFMPEG rozpocznie przesyłanie strumienia na żywo i zapisze go w formacie HLS. Plik camera-001.m3u8
będzie dostępny do odtwarzania np. za pomocą odtwarzacza wideo VLC lub bezpośrednio w przeglądarce (np. za pomocą HTML5 video tag).
Do odtworzenia strumienia na żywo w przeglądarce, wystarczy stworzyć prostą stronę HTML:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stream na żywo</title>
</head>
<body>
<video controls autoplay>
<source src="camera-001.m3u8" type="application/x-mpegURL">
Twój odtwarzacz nie obsługuje HLS!
</video>
</body>
</html>
Umieść plik camera-001.m3u8
w katalogu dostępnym publicznie, aby można było go odtworzyć w przeglądarce.
Testowy serwer node js do wyświetlania kamer online
const http = require('http');
const fs = require('fs');
const path = require('path');
const hostname = '127.0.0.1';
const port = 9000;
const server = http.createServer((req, res) => {
if(req.url === '/') {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(`
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<style>
#videoPlayer {
width: 650px; /* Szerokość odtwarzacza */
height: 310px; /* Wysokość odtwarzacza */
}
</style>
</head>
<body>
<h4>Kamera 1</h4>
<video id="videoPlayer" controls></video>
<script>
if(Hls.isSupported()) {
var video = document.getElementById('videoPlayer');
var hls = new Hls();
hls.loadSource('camera-001.m3u8');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
}
</script>
</body>
</html>
`);
} else if(req.url.endsWith('.m3u8') || req.url.endsWith('.ts')) {
const filePath = path.join(__dirname, req.url);
const ext = path.extname(req.url);
const contentType = ext === '.m3u8' ? 'application/x-mpegURL' : 'video/MP2T';
fs.readFile(filePath, (error, content) => {
if(error) {
if(error.code == 'ENOENT'){
res.writeHead(404);
res.end('Not Found');
} else {
res.writeHead(500);
res.end('Internal Server Error');
}
} else {
res.writeHead(200, {'Content-Type': contentType});
res.end(content, 'utf-8');
}
});
} else {
res.writeHead(404);
res.end("Not Found");
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
FFMPEG zapisuje logi procesu streamowania do plików camera-001.log1
oraz camera-001.log2
. Możesz regularnie sprawdzać te logi, aby monitorować, czy strumień działa prawidłowo, oraz diagnozować ewentualne błędy.
Dzięki FFMPEG możesz łatwo przekształcić strumień RTSP z kamery IP na format HLS, co umożliwia jego oglądanie na żywo w przeglądarkach internetowych i odtwarzaczach multimedialnych. Użycie kodeka H.264 zapewnia efektywne kodowanie, a format HLS sprawia, że transmisja jest zoptymalizowana dla różnych urządzeń.