RaspberryPiとTapoでWebカメラ映像(RTSP)をブラウザにリアルタイム配信する(HLS)
概要
RaspberryPiを用いてWebカメラ(TP-Link Tapo C200)のリアルタイム映像(RTSP)をストリーミング形式動画(HLS)にリアルタイムに変換しつつ、ブラウザに表示する方法を紹介します。
この手順によって、通常アプリでしか閲覧できないTapoカメラの映像を、家庭内のPCやスマホのブラウザでリアルタイムに表示してみます。
通常、ブラウザへリアルタイム配信するときは、WebRTCなど高度な技術が必要になります。
しかし、今回はそれらは使用せずに、FFmpegを使ってRTSPをHLSに直接変換しながら配信することで、シンプルな仕組みでリアルタイム配信を実現します。全体の構成図は以下の通りです。
さらに、配信サーバー(RaspberryPi)は2つの機能を持っています。FFmpegでHLSを変換してローカルディスクに保存する機能と、次にそれらの保存されたファイルを読み込んでWebサーバーで配信する機能です。
必要機材
配信サーバー: 今回はRaspberryPi5 8GBモデルを使いましたが、それ以外のシリーズ(3, 4, Zero)、またはUbuntuを搭載したPCなど何でも構いません。
Webカメラ: 同様に代用可能で、ほかのTapoシリーズなどRTSP配信に対応しているモデルであれば何でも代用できます。
事前準備
配信サーバー(RaspberryPi)
Raspberry Pi OSをインストールする
"sudo apt update", "sudo apt upgrade" コマンドをターミナルで実行して、パッケージ類を最新状態に更新する
"sudo apt -y install ffmpeg" コマンドをターミナルで実行して、FFmpegをインストールする
(任意) IPアドレスの固定する
頻繫に配信サーバーのIPアドレスが変わってしまうと不便なので、IPアドレスを固定することをおすすめします。
以上でRaspberryPiの事前準備は完了です。
参考ですがVNC, VSCodeを利用するとリモートデスクトップ環境での開発がしやすいので、これらもセットアップすることをおすすめします。
Webカメラ(Tapo)の設定
こちらの記事に沿ってカメラアカウントを作成する。(TapoシリーズのWebカメラを使用する場合のみ対象。)
(任意)IPアドレスを固定する
頻繫にカメラのIPアドレスが変わってしまうと不便なので、カメラのIPアドレスを固定することをおすすめします。Tapoシリーズはカメラ側でIPアドレスの固定ができないので、カメラのIPアドレスを調べてルーター側でIPアドレスを固定する必要があります。
RTSP受信テスト(任意)
ここまで完了したらいったんVLC Media Playerを使って、カメラのRTSP配信に接続できるかテストすることをおすすめします。(任意)
Tapoシリーズの場合、URLは
"rtsp://(ユーザー名):(パスワード)@(IPアドレス)/stream1"です。例えば、"rtsp://username:password@192.168.1.20/stream1"のように入力します。ユーザー名、パスワードは前の手順で作成したカメラアカウントのものです。
もし他社のWebカメラを使っている場合は配信URLが異なりますので、各メーカーのRTSP配信URLを調べる必要があります。
(本題)ライブ配信の構築
FFmpegでRTSPをHLSにリアルタイム変換
適当なフォルダを作成してその中で以下のコマンドを実行します(username, password, ipアドレスは自分のものに置き換えてください)
"ffmpeg -i rtsp://username:password@192.168.1.20/stream1 -c:v copy -c:a aac -hls_time 2 -hls_list_size 10 -hls_flags delete_segments -start_number 1 live.m3u8"
するとコマンドを実行したフォルダに、2秒ごとに分割された最新の映像がHLSファイルとして保存され、自動で更新保存されていきます。
ブラウザで表示するページを作成する
次にこれらのHLSファイルをブラウザで表示するためのページを作成します。HLSが保存されているフォルダ内で、index.htmlという空のファイルを新規作成して、以下のコードを記述して保存してください。
<!doctype html>
<html>
<head>
<title>Live</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
<video id="video" width="640" height="360" controls></video>
<script>
document.addEventListener('DOMContentLoaded', function() {
const video = document.getElementById('video');
const hlsUrl = 'live.m3u8';
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(hlsUrl);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
video.play();
});
} else {
console.error('HLS is not supported in this browser');
}
});
</script>
</body>
</html>
Webサーバーを立ててファイルを配信する
あとは保存されていくHLSファイルと、作成したhtmlをクライアントに配信するだけです。Pythonを使えばコマンドひとつでWebサーバーを実行することができます。
新しいコマンドラインを開き、HLSファイルとhtmlを保存したフォルダ内で以下のコマンドを実行します。
"python -m http.server 8000"
クライアントからアクセスする
あとはクライアント(同ネットワーク内の別のPCやスマホなど)のブラウザで、"http://192.168.1.10:8000/"へアクセスすれば、カメラの映像を確認できます。ただし、”192.168.1.10”の部分は、配信サーバー(RaspberryPi)のIPアドレスに置き換えてください。
最後に
消費リソース
配信中の配信サーバーのCPU使用率はRaspberryPi5で5~10%, メモリ使用量はGUI環境でも合計560MBほどでした。したがって、廉価モデルであるRaspberry Pi Zeroでも十分実行可能と思います。