crtmpserverでAXISカメラの映像を中継する

前回の crtmpserverでAXISカメラの映像を配信する に引き続き、「配信」ではなく、「中継」して見ることにする。

処理フロー:[AXIS M3045-WV] → RTSP → [crtmpserver] → RTSP → [VLCメディアプレーヤー]

【crtmpserverの設定】

/etc/crtmpserver/applications/flvplayback.lua の acceptors に以下の設定を追加する。

    acceptors =
    {
        {
            ip="0.0.0.0",
            port=554,
            protocol="inboundRtsp"
        }
    }

設定を追加した後は service crtmpserver restart で再起動すること。

VLCメディアプレーヤーで再生】

以下からVLCメディアプレーヤーをダウンロードしてインストールする。

Download official VLC media player for Windows - VideoLAN

VLCメディアプレーヤーを起動して、「メディア」メニュー → 「ネットワークストリームを開く」を選択し、ネットワークURLに以下を入力して「再生」ボタンをクリックする。

rtsp://サーバーのIPアドレス/M3045-WV

 

crtmpserverでAXISカメラの映像を配信する

前回の Ubuntuでcrtmpserverを試す(その3) に引き続き、Ubuntuにインストールしたcrtmpserverパッケージを使用して、以下を参考にAXIS社製の監視カメラの映像を配信して見た。

www.computerglitch.net

処理フロー:[AXIS M3045-WV] → RTSP/RTP → [crtmpserver] → RTMP → [flowplayer]

【AXIS M3045-WVについて】

以下に記載の通り、有線LANと無線LANに対応したカメラで、今回は無線LAN設定を行った上で有線LANを接続した。

www.axis.com

【crtmpserverの設定】

/etc/crtmpserver/applications/flvplayback.lua の externalStreams に以下の設定を追加する。

    externalStreams =
    {
        {
            uri="rtsp://uername:password@address/axis-media/media.amp",
            localStreamName="M3045-WV",
            forceTcp=true
        }
    }

上記username、password、addressには実際のユーザー名、パスワード、カメラのIPアドレス(またはホスト名)を入れること。
設定を追加した後は service crtmpserver restart で再起動すること。

 【sample4.htmlの作成】

前回の Ubuntuでcrtmpserverを試す(その3) で作成したsample3.htmlと同じディレクトリに以下の内容でsample4.htmlを作成する。

<html>
    <head>
        <title>Play RTMP via crtmpserver</title>
        <script src="../flowplayer-3.2.13.min.js"></script>
    </head>
    <body>
        <a style="display:block;width:854px;height:480px;" id="player"></a>
        <script>
            $f("player", "../flowplayer-3.2.18.swf", {

                clip: {
                    url: 'M3045-WV',
                    live: true,
                    provider: 'rtmp'
                },

                plugins: {
                    rtmp: {
                        url: '../flowplayer.rtmp/flowplayer.rtmp-3.2.13.swf',
                        netConnectionUrl: 'rtmp://192.168.1.28/flvplayback'
                    }
                }
            });
        </script>
    </body>
</html>

上記 192.168.1.28 はサーバーのIPアドレスなので、インストール環境に合わせて適宜変更して欲しい。

【ブラウザで再生】

ブラウザで http://サーバーのIPアドレス/flowplayer/example/sample4.html にアクセスしてRTMPを再生する。

【動作確認】

  • FlowPlayerでの再生では遅延が3秒程度だったが、AndroidiOSのプレーヤーではもっと大きな遅延が発生した。
  • 3つのプレーヤーで同時に接続しても、crtmpserverのCPU使用率は1%に満たなかった。
  • カメラのLANケーブルを取り外すと一度映像が停止し、カメラの無線LANが自動的に有効になると映像が開始された。次にLANケーブルを取り付けると再び映像が停止し、カメラの有線LANが自動的に有効になると映像が開始された。

【まとめ】

crtmpserverがカメラへの接続リトライを行ってくれるので実用性が高いと思う。
サービスを停止せずにexternalStreamsをダイナミックに設定できないものか。

 

Ubuntuでcrtmpserverを試す(その3)

前回の Ubuntuでcrtmpserverを試す(その2) に引き続き、今回は以下を参考にして動画を配信して見た。

idinor.hatenablog.com

処理フロー: [配信アプリ] → RTMP → [crtmpserver] → RTMP → [プレーヤー]
配信アプリ:PCではOBS Studio、Android/iOSではOS Broadcaster
プレーヤー:PCではFlowPlayer、AndroidではWondershare Player、iOSではLive Player

【OBS Studioで配信】

次を参考に以下の手順でOBS StudioからRTMPデーターを配信する。

www18.atwiki.jp

  • Open Broadcaster Software | Home から「Download OBS Studio」ボタン → 「Windows 7+」ボタンをクリックし、OBS Studioインストーラーをダウンロードしてインストールする。
  • インストール完了後、スタートメニューから「OBS Studio」→「OBS Studio (64bit)」を実行する。
  • OBS Studioのソースを追加する。
    今回はMP4ファイルを配信対象とする「メディアソース」とWebCamを配信対象とする「映像キャプチャデバイス」を使用した。
  •  「設定」ボタンをクリックして設定画面を開く。
  • サイドメニューから「配信」を選択して、「配信種別」で「カスタムストリーミングサーバー」を選択し、「URL」に「rtmp://<サーバーのIPアドレス>/live」、「ストリームキー」に「broadcast」と入力する。
    この「broadcast」は受信時に指定するストリームの名前である。
  • サイドメニューから「映像」を選択して、「基本(キャンバス)解像度」と「出力(スケーリング)解像度」に適切な映像サイズを指定する。
    ※FlowPlayerでは映像サイズとディスプレイサイズの縦横比が合わない場合、縦長や横長で表示された。
    ※PCのスペックを超える映像サイズを指定すると、処理遅延によりフレームが落ちる事象が発生する。
  • 設定画面で「OK」ボタンをクリックして設定を反映する。
  • 「配信開始」ボタンをクリックして映像データーを配信する。
  • crtmpserverのログファイルに以下のようなログが出力されることを確認する。
    1485073731:3:/build/buildd/crtmpserver-1.0~dfsg/thelib/src/application/baseclientapplication.cpp:227:SignalStreamRegistered:Stream INR(100) with name `broadcast` registered to application `flvplayback` from protocol IR(95)

 【sample3.htmlの作成】

前回の Ubuntuでcrtmpserverを試す(その2) で作成したsample2.htmlと同じディレクトリに以下の内容でsample3.htmlを作成する。

<html>
    <head>
        <title>Play RTMP via crtmpserver</title>
        <script src="../flowplayer-3.2.13.min.js"></script>
    </head>
    <body>
        <a style="display:block;width:854px;height:480px;" id="player"></a>
        <script>
            $f("player", "../flowplayer-3.2.18.swf", {

                clip: {
                    url: 'broadcast',
                    live: true,
                    provider: 'rtmp'
                },

                plugins: {
                    rtmp: {
                        url: '../flowplayer.rtmp/flowplayer.rtmp-3.2.13.swf',
                        netConnectionUrl: 'rtmp://192.168.1.28/flvplayback'
                    }
                }
            });
        </script>
    </body>
</html>

上記 192.168.1.28 はサーバーのIPアドレスなので、インストール環境に合わせて適宜変更して欲しい。

【ブラウザで再生】

OBS StudioでRTMPデーターの配信を開始してから、PCのブラウザで http://サーバーのIPアドレス/flowplayer/example/sample3.html にアクセスしてRTMPを再生する。

Androidで配信】

以下の手順で「OS Broadcaster」からRTMPデーターを配信する。

  • GooglePlayから「OS Broadcaster」をインストールして開く。
  • 以下の通り、配信サーバーの設定を行う。f:id:pochy9n:20170122191656j:plain上記 192.168.1.28 はサーバーのIPアドレスなので、インストール環境に合わせて適宜変更して欲しい。
    Streamにbroadcastを指定することで、前述のsample3.htmlがそのまま使用できる。
  • 赤いボタンをタップすることでRTMPデーターの配信が開始される。
  • 前述の「ブラウザで再生」の通り、PCのブラウザで再生できることを確認する。

iOSで配信】

以下の手順で「OS Broadcaster」からRTMPデーターを配信する。

  • App Storeから「OS Broadcaster」をインストールして開く。
  • 以下の通り、配信サーバーの設定を行う。

    f:id:pochy9n:20170122232429p:plain

    上記 192.168.1.28 はサーバーのIPアドレスなので、インストール環境に合わせて適宜変更して欲しい。
    Streamにbroadcastを指定することで、前述のsample3.htmlがそのまま使用できる。
  • 赤いボタンをタップすることでRTMPデーターの配信が開始される。
  • 前述の「ブラウザで再生」の通り、PCのブラウザで再生できることを確認する。

Androidで再生】

以下の手順で「Wondershare Player」によりRTMPを再生する。

  • GooglePlayから「Wondershare Player」をインストールして開く。
  • 左上のメニューボタンをタップし、Streamingをタップする。

    f:id:pochy9n:20170123002949j:plain

  • プラスをタップして、任意のストリーム名とStream URLを入力する。

    f:id:pochy9n:20170123003127j:plain

    上記 192.168.1.28 はサーバーのIPアドレスなので、インストール環境に合わせて適宜変更して欲しい。
    URLの最後がストリームの名前である。
  • OBS Studioなどから配信を開始した上で追加されたbroadcastをタップしてRTMPの再生を行う。

    f:id:pochy9n:20170123003415j:plain

iOSで再生】

以下の手順で「Live Player」によりRTMPを再生する。

  • App Storeから「Live Player」をインストールして開く。
  • 画面右端から左へスワイプし、ストリームリストを表示する。

    f:id:pochy9n:20170123000724p:plain

  •  プラスをタップして、Stream URLを入力する。

    f:id:pochy9n:20170123000925p:plain

    上記 192.168.1.28 はサーバーのIPアドレスなので、インストール環境に合わせて適宜変更して欲しい。
    URLの最後がストリームの名前である。
  • OBS Studioなどから配信を開始した上で「Open」をタップしてRTMPの再生を行う。

【まとめ】

配信可能なメディアや再生可能なデバイスが増えてきたところが楽しい。

 

Ubuntuのsudoersを壊してしまったら

visudoを使わずにvimで/etc/sudoersを編集し、その結果、sudoができなくなった。
構文を理解していないくせに危険な行為をするから、そんな羽目に陥るのだと自分を戒めながらも、世の中には同じような状況にハマった人がいるに違いないと思い検索してみたら・・・いたいた!

jinsei1do.com

参考にしたページではrootのパスワードを設定することで復旧しているが、今回は/etc/sudoersを修正することで復旧させた。
以下にその経緯を記載する。
なお、UbuntuVirtualBox上の仮想マシンにインストールしている。

【PCブート】

f:id:pochy9n:20170121160716p:plain

この画面が表示されたら直ぐにESCキーを押下する。

【起動メニュー1】

f:id:pochy9n:20170121160909p:plain

Advanced options for Ubuntuを選択する。

【起動メニュー2】

f:id:pochy9n:20170121184941p:plain

最も新しいカーネルで(recovery mode)を選択する。

【Recovery Menu】

f:id:pochy9n:20170121185300p:plain

recovery modeでUbuntuを起動すると上記メニューが表示される。
rootを選択してシェルを実行する。

【sudoersを開く】

f:id:pochy9n:20170121185639p:plain

ルートファイルシステムが読み込みのみになっているので、 読み書き可能で再マウント(-o rw,remount)する。
sudoersを書き込み可能(chmod +w)に変更してからエディタ(vi)で開く。

【sudoersを修正】

f:id:pochy9n:20170121190330p:plain

sudoersの誤った設定を削除(コメントアウト)して保存し、読み込みのみ(chmod -w)に戻してからシェルを終了する。

【通常起動】

f:id:pochy9n:20170121191107p:plain

resumeを選択してUbuntuを通常起動する。

【最終確認】

f:id:pochy9n:20170121191226p:plain

OKを選択して復旧を完了する。

 

Ubuntuでcrtmpserverをビルドして見る

crtmpserverからinboundRtmfpがなくなった件を解決したいと思い、先ずは現時点のcrtmpserverがビルド可能かを確認した。

【ビルド環境】

【パッケージインストール

ビルドに必要なパッケージをLinuxとフリーソフトでライブ動画配信サーバーを構築する - idinorの日記の「2. 必須パッケージのインストール」を参考にapt-get installでインストールした(と言うか、インストールされていた)。
( [ ] 内にインストールしたときのバージョンを記した。)

  • openssl [1.0.1f-1ubuntu2.21]
  • gcc [4:4.8.2-1ubuntu6]
  • g++ [4:4.8.2-1ubuntu6]
  • cmake [2.8.12.2-0ubuntu3]

ソースコードダウンロード】

GitHub - shiretu/crtmpserverの右側「Clone or download」ボタンをクリックし、「Download ZIP」をクリックして最新のソースコードをダウンロードした。
現時点の最終コミットは-- removed some old cleanup files · shiretu/crtmpserver@b866fff · GitHubである。

【ビルド実行】

ダウンロードしたZIPファイルの中身を便宜上 ~/github/crtmpserver に展開し、以下のコマンドでビルドを実行した。

$ cd ~/github/crtmpserver/builders/cmake
$ sudo ./run

【ビルド結果】

問題なくビルドが完了し、crtmpserverが起動されて、以下のログが画面に出力された。

/crtmpserver/src/crtmpserver.cpp:217 C++ RTMP Media Server (www.rtmpd.com) version 1.1_rc1 build Unversioned directory - Gladiator - (built on 2017-01-15T05:54:15.000)
/crtmpserver/src/crtmpserver.cpp:220 OS files descriptors count limits: 4096/4096
/crtmpserver/src/crtmpserver.cpp:222 Initialize I/O handlers manager: epoll without timerfd_XXXX support
/crtmpserver/src/crtmpserver.cpp:225 Configure modules
/crtmpserver/src/crtmpserver.cpp:231 Plug in the default protocol factory
/crtmpserver/src/crtmpserver.cpp:238 Configure factories
/thelib/src/configuration/module.cpp:97 Loaded factory from application samplefactory
/crtmpserver/src/crtmpserver.cpp:244 Configure acceptors
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 0->1 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 1->2 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 2->3 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 3->4 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 4->5 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 5->6 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 6->7 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 7->8 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 8->9 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 9->10 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 10->11 IOHT_ACCEPTOR
/crtmpserver/src/crtmpserver.cpp:250 Configure instances
/crtmpserver/src/crtmpserver.cpp:256 Start I/O handlers manager: epoll without timerfd_XXXX support
/crtmpserver/src/crtmpserver.cpp:259 Configure applications
/thelib/src/configuration/module.cpp:177 Application admin instantiated
/thelib/src/configuration/module.cpp:177 Application appselector instantiated
/thelib/src/configuration/module.cpp:177 Application flvplayback instantiated
/thelib/src/mediaformats/readers/streammetadataresolver.cpp:143 mediaFolder not found: /Volumes/Storage/media/mp3
/thelib/src/mediaformats/readers/streammetadataresolver.cpp:119 Storage failed to initialize storage 0x00000001
/thelib/src/mediaformats/readers/streammetadataresolver.cpp:143 mediaFolder not found: /Volumes/Storage/media/
/thelib/src/mediaformats/readers/streammetadataresolver.cpp:119 Storage failed to initialize storage namedStorage1
/thelib/src/mediaformats/readers/streammetadataresolver.cpp:143 mediaFolder not found: /Volumes/Storage/media/mp4
/thelib/src/mediaformats/readers/streammetadataresolver.cpp:119 Storage failed to initialize storage namedStorage2
/thelib/src/mediaformats/readers/streammetadataresolver.cpp:143 mediaFolder not found: /Volumes/Storage/media/flv
/thelib/src/mediaformats/readers/streammetadataresolver.cpp:119 Storage failed to initialize storage namedStorage3
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 11->12 IOHT_TIMER
/thelib/src/configuration/module.cpp:177 Application proxypublish instantiated
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 12->13 IOHT_TIMER
/thelib/src/configuration/module.cpp:177 Application samplefactory instantiated
/thelib/src/configuration/module.cpp:177 Application stresstest instantiated
/thelib/src/configuration/module.cpp:177 Application vptests instantiated
/crtmpserver/src/crtmpserver.cpp:265 Install the quit signal
/crtmpserver/src/crtmpserver.cpp:276 
+-----------------------------------------------------------------------------+
|                                                                     Services|
+---+---------------+-----+-------------------------+-------------------------+
| c |      ip       | port|   protocol stack name   |     application name    |
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 1112|           inboundJsonCli|                    admin|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 1935|              inboundRtmp|              appselector|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 8081|             inboundRtmps|              appselector|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 8080|             inboundRtmpt|              appselector|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 6666|           inboundLiveFlv|              flvplayback|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 9999|             inboundTcpTs|              flvplayback|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 5544|              inboundRtsp|              flvplayback|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 6665|           inboundLiveFlv|             proxypublish|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 8989|         httpEchoProtocol|            samplefactory|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 8988|             echoProtocol|            samplefactory|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 1111|    inboundHttpXmlVariant|                  vptests|
+---+---------------+-----+-------------------------+-------------------------+
/crtmpserver/src/crtmpserver.cpp:277 GO! GO! GO! (3228)

【配信テスト】

前述のログに「mediaFolder not found: /Volumes/Storage/media/」などのエラーが出力されているので、 ./crtmpserver/crtmpserver.lua を適切に変更してから再度crtmpserverを実行し、Ubuntuでcrtmpserverを試す(その2)と同様にFlowPlayerでメディアを再生して、特に問題がないことを確認した。

CentOS 7の場合】2017/02/18追記

CentOS 7でビルドする場合にyum Installでインストールする必要があるのは以下のパッケージである。

  • openssl-devel
  • gcc
  • cmake

crtmpserverからinboundRtmfpがなくなった件

OBS(Open Broadcaster Software) からのRTMPデーターをcrtmpserverで受信したいのだが、inboundRtmfpプロトコルがなくなったために受信できなくなったようだ(予想)。

RTMPストリーミング — pdoc 0.1 documentation を見ると、Ubuntu 10.04が動作環境なので、2013年頃まではinboundRtmpと同じ1935ポートにinboundRtmfpが存在したことが分かる。
また、 GitHub - madhawa/rtmpdplus: Enhanced C++ RTMP Server/builders/cmake/crtmpserver/crtmpserver.lua を見ると、2011/05/23までは確実にinboundRtmfpが存在していたはずである。

しかし、crtmpserverの作者 Gavriloaie Eugen-Andrei さんの GitHub - shiretu/crtmpserver を見ると、inboundRtmfpの影も形もない。

inboundRtmfpをサポートしていないからOBSのRTMPを受信できないのか、inboundRtmfpのサポートを止めたのはなぜか、GitHub経由でGavriloaieさんに問い合わせ中。

【2017/01/15追記】

Ubuntuでcrtmpserverをビルドして見るで起動したcrtmpserverでは、OBSのRTMPデーターを配信できることが判明した。
Ubuntu 14のcrtmpserverパッケージか、その設定に問題があることが考えられるので、引き続き調査を進めることにした。

なお、RTMFPについて調べたところ、RTMPUDPプロトコルだったので、OBSのRTMPをcrtmpserverが受信できないことにはそもそも無関係だった。

【2017/01/22追記】

その後、UbuntuパッケージのcrtmpserverでもOBSのRTMPデーターを配信できた。
OBSの設定が間違っていた可能性が高いが、色々と試したために不明確である。