Live streaming Serverを構築します。動的コンテンツを自分のブログに掲載したり、スマホで配信するなど色々用途は考えられます。Oracle Linux 8にインストールします。スペックはCPU4つ、メモリ24GBの仮想マシンです。
それでは作業をしていきましょう。
まずはSELinuxを無効にします。これが不要というわけではなく、作業途中で原因不明のエラーに悩まされたことが多々あったからです。
仮想マシンは作成したばかりの状態ですがSELinuxの状態を確認します。
getenforce
どうやら有効なので一時的に無効にします。
setenforce 0
再起動後も無効にしたいときは次のファイルを編集します。
vi /etc/selinux/config
SELINUX=enforcingをSELINUX=disableに変更します。
ここからは、NGINX公式ブログを参考にしてNGINXをソースからインストールします。
NGINXをコンパイルする前に、autoconf、gcc、git、makeなどの基本的なビルドツールをインストールする必要があります。
dnf groupinstall "Development Tools"
dnf install git
依存関係をダウンロードしてインストールする簡単な方法は、パッケージマネージャーを使用することです。
dnf groupinstall pcre-devel zlib-devel openssl-devel
Module or Group ‘pcre-devel’ is not available.
Module or Group ‘zlib-devel’ is not available.
Module or Group ‘openssl-devel’ is not available.
記述通りおこなったが、エラーでインストール出来ないので、通常のインストールに変更します。
dnf install pcre-devel zlib-devel openssl-devel
RTMP Module付きでNGINXをコンパイルします。ビルドを完了するには、RTMPとNGINXのGitHubリポジトリのクローンを作成します。
cd /tmp
git clone https://github.com/arut/nginx-rtmp-module.git
git clone https://github.com/nginx/nginx.git
cd nginx
./auto/configure --add-module=../nginx-rtmp-module
make
make install
インストール状況を見ると/usr/local/nginxが重要なディレクトリということがわかります。
[root@instance-20220107-1707 nginx]# ./auto/configure –add-module=../nginx-rtmp-module
checking for OS
- Linux 5.4.17-2136.301.1.3.el8uek.aarch64 aarch64
checking for C compiler … found - using GNU C compiler
- gcc version: 8.5.0 20210514 (Red Hat 8.5.0-4.0.1) (GCC)
checking for gcc -pipe switch … found
checking for -Wl,-E switch … found
checking for gcc builtin atomic operations … found
checking for C99 variadic macros … found
checking for gcc variadic macros … found
checking for gcc builtin 64 bit byteswap … found
checking for unistd.h … found
checking for inttypes.h … found
checking for limits.h … found
checking for sys/filio.h … not found
checking for sys/param.h … found
checking for sys/mount.h … found
checking for sys/statvfs.h … found
checking for crypt.h … found
checking for Linux specific features
checking for epoll … found
checking for EPOLLRDHUP … found
checking for EPOLLEXCLUSIVE … found
checking for eventfd() … found
checking for O_PATH … found
checking for sendfile() … found
checking for sendfile64() … found
checking for sys/prctl.h … found
checking for prctl(PR_SET_DUMPABLE) … found
checking for prctl(PR_SET_KEEPCAPS) … found
checking for capabilities … found
checking for crypt_r() … found
checking for sys/vfs.h … found
checking for nobody group … found
checking for poll() … found
checking for /dev/poll … not found
checking for kqueue … not found
checking for crypt() … not found
checking for crypt() in libcrypt … found
checking for F_READAHEAD … not found
checking for posix_fadvise() … found
checking for O_DIRECT … found
checking for F_NOCACHE … not found
checking for directio() … not found
checking for statfs() … found
checking for statvfs() … found
checking for dlopen() … not found
checking for dlopen() in libdl … found
checking for sched_yield() … found
checking for sched_setaffinity() … found
checking for SO_SETFIB … not found
checking for SO_REUSEPORT … found
checking for SO_ACCEPTFILTER … not found
checking for SO_BINDANY … not found
checking for IP_TRANSPARENT … found
checking for IP_BINDANY … not found
checking for IP_BIND_ADDRESS_NO_PORT … found
checking for IP_RECVDSTADDR … not found
checking for IP_SENDSRCADDR … not found
checking for IP_PKTINFO … found
checking for IPV6_RECVPKTINFO … found
checking for TCP_DEFER_ACCEPT … found
checking for TCP_KEEPIDLE … found
checking for TCP_FASTOPEN … found
checking for TCP_INFO … found
checking for accept4() … found
checking for int size … 4 bytes
checking for long size … 8 bytes
checking for long long size … 8 bytes
checking for void * size … 8 bytes
checking for uint32_t … found
checking for uint64_t … found
checking for sig_atomic_t … found
checking for sig_atomic_t size … 4 bytes
checking for socklen_t … found
checking for in_addr_t … found
checking for in_port_t … found
checking for rlim_t … found
checking for uintptr_t … uintptr_t found
checking for system byte ordering … little endian
checking for size_t size … 8 bytes
checking for off_t size … 8 bytes
checking for time_t size … 8 bytes
checking for AF_INET6 … found
checking for setproctitle() … not found
checking for pread() … found
checking for pwrite() … found
checking for pwritev() … found
checking for strerrordesc_np() … not found
checking for sys_nerr … found
checking for localtime_r() … found
checking for clock_gettime(CLOCK_MONOTONIC) … found
checking for posix_memalign() … found
checking for memalign() … found
checking for mmap(MAP_ANON|MAP_SHARED) … found
checking for mmap(“/dev/zero”, MAP_SHARED) … found
checking for System V shared memory … found
checking for POSIX semaphores … not found
checking for POSIX semaphores in libpthread … found
checking for struct msghdr.msg_control … found
checking for ioctl(FIONBIO) … found
checking for ioctl(FIONREAD) … found
checking for struct tm.tm_gmtoff … found
checking for struct dirent.d_namlen … not found
checking for struct dirent.d_type … found
checking for sysconf(_SC_NPROCESSORS_ONLN) … found
checking for sysconf(_SC_LEVEL1_DCACHE_LINESIZE) … found
checking for openat(), fstatat() … found
checking for getaddrinfo() … found
configuring additional modules
adding module in ../nginx-rtmp-module - ngx_rtmp_module was configured
checking for PCRE2 library … found
checking for OpenSSL library … found
checking for zlib library … found
creating objs/Makefile
Configuration summary
- using system PCRE2 library
- using system OpenSSL library
- using system zlib library nginx path prefix: “/usr/local/nginx”
nginx binary file: “/usr/local/nginx/sbin/nginx”
nginx modules path: “/usr/local/nginx/modules”
nginx configuration prefix: “/usr/local/nginx/conf”
nginx configuration file: “/usr/local/nginx/conf/nginx.conf”
nginx pid file: “/usr/local/nginx/logs/nginx.pid”
nginx error log file: “/usr/local/nginx/logs/error.log”
nginx http access log file: “/usr/local/nginx/logs/access.log”
nginx http client request body temporary files: “client_body_temp”
nginx http proxy temporary files: “proxy_temp”
nginx http fastcgi temporary files: “fastcgi_temp”
nginx http uwsgi temporary files: “uwsgi_temp”
nginx http scgi temporary files: “scgi_temp”
ファイアウォールの状態を確認すると有効になっているので停止するか、ポート開放をします。nginxが使用するポートは80にする予定なので追加しておきます。SSLもあとから必要になるかもしれないので追加しておきました。また、oracle cloudのイングレスルールにも記述しておきます。
systemctl status firewalld
firewall-cmd --list-all --zone=public
firewall-cmd --add-port=80/tcp --zone=public --permanent
firewall-cmd --add-port=443/tcp --zone=public --permanent
systemctl restart firewalld
yumやdnfによるインストールと違いnginxのサービスは無いのでコマンド入力で起動します。
/usr/local/nginx/sbin/nginx
一度ブラウザでサンプルページが表示されるか確認します。
停止する時は次のコマンドを入力します。
/usr/local/nginx/sbin/nginx -s quit
次はnginx.confを編集します。とはいえ何を記述すべきかわからなかったので下記のサイトの記述例を使用させていただきました。ソースからインストールするとconfファイルは下記のディレクトリにあります。
/usr/local/nginx/conf
cd /usr/local/nginx/conf
vi nginx.conf
[記述内容]
#user nobody;
worker_processes auto;
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
rtmp_auto_push on;
rtmp {
server {
listen 1935;
access_log logs/rtmp_access.log ;
chunk_size 4096;
application live1 {
live on;
wait_video on;
hls on;
hls_cleanup on;
hls_path /usr/local/nginx/html/hls;
#遅延対策
hls_fragment 500ms;
hls_playlist_length 1s;
hls_type live;
hls_nested on;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
}
root html;
index index.html index.htm;
}
location /dash {
types {
application/vnd.apple.mpegurl mpd;
}
root html;
index index.html index.htm;
}
}
}
ここまででサーバーの設定は完了しました。今度は配信するPCの設定をします。使用するソフトはOBS studioを利用して設定していきます。
OBSの設定をクリックし、配信項目でサーバーとストリームキーを入力するだけです。
入力完了後に配信開始ボタンをクリックします。しかし、接続できないエラーが発生しました。
どうやら、rtmpで使用するポートの開放が必要なようですのでサーバーに戻り、ファイアウォールにポート番号1935の受信を許可します。さらにOracle Cloudのイングレスルールにも記述します。
firewall-cmd --add-port=1935/tcp --zone=public --permanent
systemctl restart firewalld
再度配信します。今度は接続ができました。配信を開始すると下記のディレクトリの下の階層にストリームキーと同じ名前のディレクトリが作成され、数個の.tsファイルとindex.m3u8が作成されています。配信を停止するとディレクトリとファイルは消えるみたいです。
cd /usr/local/nginx/html/hls
ls
この配信の状況をリアルタイムにみれるサンプルのHTMLファイルを作成して動作確認します。
cd /usr/local/nginx/html
vi index.html
[記述内容]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MediaElement</title>
<!-- MediaElement style -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mediaelement/5.0.4/mediaelementplayer.css" />
</head>
<body>
<!-- MediaElement -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mediaelement/5.0.4/mediaelement-and-player.js"></script>
<video id="player" />
</body>
<script type="text/javascript">
var player = new MediaElementPlayer('player', {
success: function(mediaElement, originalNode) {
console.log("Player initialised");
}
});
player.setSrc("http://129.213.138.187/hls/test/index.m3u8");
</script>
</html>
記述にあるクラウドフレアのURLはCDNというらしく便利なものです。詳しいことはわかりません。
スマホにもOBS mobileというアプリがあったので同じようにサーバーとストリームキーを入力すると配信できました。
ただし、このままでは誰でも配信可能なので制限をかけることもできます。
方法1
nginx.confに次の記述を追加する。IPアドレスが222.222.222.222のみ許可。
allow 222.222.222.222;
deny all;
方法2
Oracle cloudのイングレスルールで特定のIPアドレスからのみ許可する。
方法3
nginx.confでrtmpの設定にあるlive1をわかりにくい文字列にする。