【2022年度版】今でも動くライブ配信システムの構築(rtmp、hls対応)とブラウザ視聴対応について
ここ1ヶ月は忙しくし過ぎていて、noteに投稿出来ていなかったが、ある出来事がきっかけで個人的な使用でライブ配信する方法を調べた。中々時間が掛かったが有意義な内容だと思うためnoteに投稿する。
前提
本件は、さくらのクラウドでubuntuサーバーに、nginx-rtmp-moduleをインストールして試した。
要件
自宅からの配信だけではなく外出先から配信して友達に見てもらって楽しみたい。そのためにはLANではなくインターネット越しで配信サーバにアクセスする形にしないといけないだろう。家ならLANの中に配信サーバを立てる手はあるが、ZOOMとかで共有するなら結局ネットには出ているからだ。
なぜ、配信システムを自前で組むのか
正直、ZOOMやLINE等で友達と画面共有した方が明らかに手軽だ。数時間程度であればスマホのカメラをかざして完了だろう。期待するのは今後の拡張性についてだ。配信システムは下記のメリットがあると思う。
配信は自由に見ることができる(参加を強制しない)からだ。例えば、自由に制限なく見れることや、例えば今後、定点カメラのような使い方もしたいと考えたら、決まった時間で会話する前提のミーティングを無制限に開くことはあまりツールとしては向いていない。可用性を踏まえると配信システムの方が向いていると思われる。
配信サービスといえば、YoutubeやFaceBook, Vimeoなどもあるが、それぞれ問題がある。RTMPに対応はしているとうたっているが、実際はRTMPSで配信できないとサポートしなかったり、配信に公式アプリを使用する必要があったり、Webサービスにログインしないと見れないという問題が出てくる。配信するために有料となるサービスもある。これでは、自由ではないと感じたため不採用とした。
そこで、Youtubeで非公開にしたりして必要な人に画面共有する手も考えた。(決まった時間だけでも画面共有したり、遠隔操作が出来れば画面をそれで見るという手もある。)Youtubeは便利なのではということで候補に上がったが、モバイルで配信する際に下記の制限があるので、すぐに使えないということで不採用にした。
最終的に配信サービスは自前で作成するのが良いだろうという結論に達した。もちろん、お金を掛ければ外部サービスは使用できるが、個人でそこまでして配信するモチベーションはなく、手軽にするために敢えて回り道をすることを選択した。出来るだけオープンソース(既存)を活用して配信システムを構築することにした。
選定と理由
さくらのインターネットは定額で利用できるため採用した。
ビューワーは調査と試行をする中でvlcを選んだが、そもそも、相手にvlcをインストールして見てくれというのは無理があるのではないかと思い、ブラウザで視聴できるようにした。
配信ソフトは下記の2つが試したら使えた。他のアプリもひとつ試したが、映像がiPhoneのvlcから見た時に動かない事象を確認した。ここは各自がよく確認して頂きたい。
配信に利用したスマホは、xiaomi mi 11 lite 5g、ここではスマホの機種が大事ではなく、スマホにはカメラがあるから配信に使えると判断しただけである。
RTMPとHLS
定義まわりを記載(引用)する。RTMPがブラウザによる視聴はできない。httpをサポートしているHLSを使用することで解決する
調べる前の注意点
flashのサポートは切れているためか、rtmpの配信をブラウザで見ることが出来ないことが分かった。ご自身で調査するときには、Googleでヒットした記事の日付を確認すること。もし、2022年度より古い記事は書いてあるコードで動かないと思われる。少なくても、記載されているソースコードでブラウザを作成したが動かなかった。
<source src="rtmp://〜〜〜 type='rtmp/mp4'>
もし、調べた記事にこのような記述があったらそのコードは動かない。こちらはiPhone、MacからブラウザのSafariとChromeで動作しないことを確認している。
また、ブラウザで視聴できるとされるhlsの説明記事でも動作が見込めなかった。ここで提案したいのはGoogleで検索するよりとYoutubeで調べた方が答えに辿り着くための有益な情報(ヒント)が埋まっている可能性が高い。動画ではblogと違って誤魔化せないからだ。書いたコードが動いている映像が何よりの証拠となり信頼を寄せられるからだ。
ただし、スライドとしゃべるだけの動画はヒントにならないので、コードを書いていて説明があり、かつ実行結果のある動画をみるとよい。大して再生数はないかもしれないが、実装に重きを置いているので、コードを書く前に考えるときに参考になる。実装する立場としては、口だけ動かす意識高い系の実装したことがあるのか疑わしいYoutuberよりはよっぽどいい。
実装
ここでは、記事通りには解決しなくて、自分なりに考えて解決した点(特に時間が掛かった点)も踏まえて、掻い摘んで話していく
インストール
公式では別な方法でインストールしているが、これが一番簡単であった。
$ sudo apt install nginx libnginx-mod-rtmp
nginx.confの編集
何かしらのエディタで編集をする。編集方法はオフィシャルのページを参照すること。
$ sudo vi /etc/nginx/nginx.conf
RTMPを利用した配信アドレス
nginx.confを下記のように編集(追加)したとすれば
rtmp {
server {
listen 1935;
application app {
live on;
}
}
}
rtmpの配信アドレスを下記のように設定する。サーバのグローバルIPアドレスはさくらのクラウドの画面より確認できる。ストリームキーは自由に設定できる。"livestream"でも"hoge"でも何でも良い。
rtmp://サーバのグローバルIPアドレス/app/ストリームキー
ポートの解放
この時点で、RTMPの配信テストは試せる。しかし、LANで別なツールを使用して構築した時は問題なかったのだが、外部からアクセスするためか配信を受け付けなかった。こちらからサーバーへのアクセスがはじかれているのだろうと想像してポートの解放をおこなったら解決した。
$ sudo ufw allow 1935/tcp
Nginxの起動
sudo systemctl start nginx
Nginxを起動できないとき
下記のコマンドを打ってみよう。何行目にエラーがあるか教えてくれる。自分の場合はタグの構造上、記載してはいけないところに記載してエラーを吐いたことがある。
$ sudo nginx -t
もちろん、別な発想でここが間違っているのではないかと考えて試したらエラーの行数が直接の原因とはいえないこともある。
一旦、配信を試す
(RTMPのみを利用して確認)一旦、配信側の携帯のアプリから上記のアドレスを利用して配信をしてみる。また、受信側の携帯またはPCよりVLCアプリをインストールして同じようにアドレスを指定してみよう。そうすると、配信側の携帯のカメラの映像や音が、受信側のVLCに表示されるはずだ。ちょっとした感動がある。
これで完了としても問題ないのだが、現実的なことを考えれば受信者にVLCをインストールしてもらわないといけないので、この配信形式はユーザーライクとは言い難い。もし、ブラウザで見られるように出来れば、LINEからアドレスを送ってクリックしてもらえれば済ませられる。例えば、自分達がYoutubeをブラウザ以外のアプリから見ることはあるか想像すればいい。ブラウザ以外で見ることはまずないはずだ。それと同じように考えればいい。
hlsの記述
nginx.confに編集(追加)する。ここで気をつけないといけないのはパスに関してだ。ブラウザで公開する時にはどこに何のファイルがあるかを考える必要がある。それを無視してコードを書いたら配信を受信できなかったので注意すること
http {
server {
listen 8080;
location /app {
# Serve HLS fragments
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /var/www/html;
add_header Cache-Control no-cache;
}
}
rtmp {
server {
listen 1935;
chunk_size 4096;
application app {
live on;
record all;
record_path /tmp/av;
record_max_size 1K;
record_unique on;
hls on;
hls_path /var/www/html/hls;
}
}
}
フォルダを作る
hlsというフォルダは自分で作った覚えがないが、作らなくていいかを考えてみよう。下手に期待すると上手くいかなくなる。実際にも上手くいかなかった場面に遭遇した。
$ sudo mkdir /var/www/html/hls
ちなみに、下記のアドレスはnginxのルートディレクトリであるので存在する。nginxがリクエストを受けた時にユーザーに返す画面のディレクトリだ。
/var/www/html
配信を確認するHTMLページを作る
配信ページ(HTML)を作る。下記のディレクトリに作成すれば、後述するブラウザのアドレスに合わせてファイルを配置したことになるからだ。
$ sudo vi /var/www/html/player.html
hlsフォルダには、RTMPの内容をHLSに変換したデータが保管されると見越して、参照する内容を作成する。
<html>
<head>
<title>Live Streaming</title>
<link href="https://vjs.zencdn.net/7.0/video-js.min.css" rel="stylesheet">
<script src="https://vjs.zencdn.net/7.0/video.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.14.1/videojs-contrib-hls.min.js"></script>
</head>
<body>
<video id="live_streaming" width="1280" height="720"
class="video-js vjs-default-skin" controls>
<source
src="サーバのグローバルIPアドレス/hls/ストリームキー.m3u8"
type="application/x-mpegURL">
</video>
<script>
var player = videojs("live_streaming");
player.play();
</script>
</body>
</html>
参考にしたコードを見ているとなぜ、このようにしているのか理解できない時がある。理解できるまでやるのはいいが、もし理解できないコードであれば自分が理解できるコードに落とし込む(方針転換)のも一つの手だろう。少なくても納得いかない状態で書くコードは自分の意志(考え)が不安定になるのでよくない。
nginxの停止
一旦、設定を反映させるためにnginxを停止させる。
その後、起動すること
$ sudo systemctl stop nginx
ブラウザによるRTMP配信の確認
RTMPによる配信が見れるか確認するためにブラウザを立ち上げて、下記のアドレスを入力して実行結果(ブラウザで配信が見られるか)を確認する
http://サーバのグローバルIPアドレス/player.html
評価
実装した配信システムに対して課題は上げたらきりはないが
当初の目的は満たすことはできた。
まとめ
今までサーバ(インフラ)を構築したことのない自分が、はじめて1から調べてサーバを使用して配信システム(サービス)を構築したことは我ながらよくやったと思う。さくらのクラウドが仮想サーバという形でユーザライクに作成できることは大きかった。またサービス面ではnginx-rtmp-module
を活用できたのでゼロから作る時間がかなり短縮されたと思う。そもそも、セキュリティが大きく影響しない限り、ゼロから調査するモチベーションはこちらにはないし、そもそも、目的を何かしらの形で満たせればそれでよかったからだ。今後はこれを使って友達同士で風景を共有できたりしたらいいなと思う。
おまけ
Windowsでローカル(LAN)で配信システムを組むなら、"Live-stream server portable. Windows+Nginx+RTMP+HLS+Dash"を使用すると簡単であると思う。Windowsサーバにインストールしたことがなく外部サーバで機能するかは分からないが、お手軽に構築することができる。詳しくはリンク内にあるYoutubeの動画を見ると良い。
補足
コメントを頂戴したので補足事項を追加する。
さくらのクラウドで編集したファイルをダウンロードする方法が分からなかったのでキャプチャを追加する。(もし、こちらが編集したファイルだけダウンロード出来たら添付する。また、構成図も記載する。ApplePencilどこいったw)
おわり!