コアダンプの数だけ強くなれるよ

見習いエンジニアの備忘log

Linux PCのデスクトップ画面をブラウザから監視する

やりたいこと

こんな感じでブラウザから外部のPC(Linux)のモニターに表示している内容をできる限りリアルタイムで表示したい。

f:id:segmentation-fault:20200226211949p:plain


HLS(HTTP Live Streaming)

HLS(HTTP Live Streaming)を使えば、多少遅延はあるがほぼリアルタイムの映像をみることができるようです。Youtubeとかで良くあるLive配信的なやつですね。

具体的には、ffmpegを使ってLinux PCのモニターの表示内容(X11)を録画 + HLS用ファイルとして出力 + Nginx等のWebサーバを立てて、HLS用ファイルにアクセス可能にします。

ただ、HLSはAppleが開発した仕組みであり、現時点で標準サポートしているブラウザSafariだけっぽいです。

が、世の中には優秀な素晴らしい方々がおり、Video.jsを使えば他のブラウザでもLive Stremingの動画再生が可能になります(感謝)。

実施例

ここでは、Virtual-BOXにCentOS7(GUIモード) + WEBサーバ + HLSファイルの出力処理を構築 --> ホスト側のブラウザからCentOSのWEBサーバにアクセスし、CentOSのGUI画面を表示してみます。


事前準備

まずは必要なパッケージを取得します。

nginxのインストール

$ sudo vim /etc/yum.repos.conf.d/nginx.repo
$ cat /etc/yum.repos.conf.d/nginx.repo
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
$ sudo yum -y install nginx 

ffmpegのインストール

$ sudo yum -y install epel-release http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
$ sudo yum -y install ffmpeg

WEBサーバの設定

今回の例ではhttp://<IPアドレス>/hlsにアクセスした際に動画が見えるようにします。

必要なDirectoryを掘ります。

$ sudo mkdir /var/www/html/hls
$ sudo mkdir /var/www/html/hls/static/js
$ sudo mkdir /var/www/html/hls/static/css


VideoJsを配置します。

$ cd /var/www/html/hls
$ tree
└── static
    ├── css
    │   └── video-js.min.css
    └── js
        ├── video.min.js
        ├── videojs-contrib-hls.min.js
        └── videojs-contrib-media-sources.min.js


index.htmlを作成します。

$ sudo vim /var/www/html/hls/index.html
$ cat /var/www/html/hls/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Video.jsのお試し</title>
  <link href="http://192.168.56.103/hls/static/css/video-js.min.css" rel="stylesheet">
  <script src="./static/js/video.min.js"></script>
  <script src="./static/js/videojs-contrib-media-sources.min.js"></script>
  <script src="./static/js/videojs-contrib-hls.min.js"></script> 
</head>
<body>
<h2>ffmpeg + HLSでデクストップ画面をモニタリング</h2>
<video id="test" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto"
 width="640" height="360" data-setup="{}">
  <source src="./output.m3u8" type="application/x-mpegURL">
</video>
</body>
</html>


nginxのconfigを編集します。

$ sudo vim /etc/nginx/conf/default.conf
$ cat /etc/nginx/conf/default.conf
...(途中略)...
        location / {
            root   /var/www/html;
            index index.html;
        }
...(途中略)...


ポート80番号を開放します。

$ sudo firewall-cmd --add-service=http --zone=public --permanent
$ sudo firewall-cmd --reload


nginxを起動します。

$ sudo systemctl start nginx


HLS開始

下記のコマンドでCentOSのGUI画面を録画しHLS形式のファイルで出力します。

$ cd /var/www/html/hls
$ sudo ffmpeg -f x11grab -r 60 -s 800x600 -i :0.0+0,0 -vcodec h264 -b:v 250K -pix_fmt yuv420p -segment_format mpegts  -hls_time 5 -hls_list_size 5 -hls_flags delete_segments output.m3u8


実行結果

ChromeからHLS配信用サーバ(Virtual-BOX上のCentOS)にアクセスしてみます。
20秒〜30秒の遅延はありますが、いい感じに監視できていますね。
※動画は面倒なのでgif画像です。

f:id:segmentation-fault:20200226212522g:plain


その他の方法

遅延を避けるには、WebRTCといった技術を駆使すればできるらしいです。
ビデオチャットとかのイメージですね。

◆構成
仮想Webカメラ(v4l2loopback) + シグナリングサーバ

◆内容
監視対象のPCに仮想的なWebカメラ(v4l2loopback)導入する、そしてWebカメラにffmpegで映像を流し込み、Webカメラで撮影している内容をシグナリングサーバに送信する。
監視を行うクライアントはブラウザからシグナリングサーバにアクセスして映像を見る。

...みたいな構成を組めばできるようです。Node.JsやWebSocket等の知識が必要になります
ちょっとばかり調べてみましたが、何言ってるか良く分からなかったので断念しました...

参考
https://medium.com/@alexcambose/webcam-live-streaming-with-websockets-and-base64-64b1b4992db8
https://github.com/umlaeute/v4l2loopback


リンク

https://tools.ietf.org/html/rfc8216
https://videojs.com