Ubuntuでcrtmpserverを試す
メディアサーバーのcrtmpserverが稼働する環境をUbuntu上に構築し、メディア配信に関する知識を増強しようと考えた。
今回は以下を参考にPCのブラウザで動画再生ができる環境を構築して見た。
RTMPストリーミング — pdoc 0.1 documentation
処理フロー:MP4 → [ffmpeg] → FLV → [crtmpserver] → RTMP → [flowplayer]
【動作環境】
- サーバー
- Ubuntu 14.04.3 (x64)
- クライアント
- Windows 10 Home (x64)
【パッケージインストール】
apt-get install でUbuntuに以下のパッケージをインストールする。
( [ ] 内にインストールしたときのバージョンを記した。)
- crtmpserver [1.0~dfsg-5]
- lua5.2 [5.2.3-1]
- apache2 [2.4.7-1ubuntu4.13]
【ffmpegのインストール】
Ubuntuでffmpegをビルドする にしたがってffmpeg(バージョン:git-2017-01-02-aa95292)をインストールする。
【crtmpserver設定の表示】
crtmpserverの設定ファイルは /etc/crtmpserver 以下に存在する。
そのディレクトリにあるインストール直後のcrtmpserver.luaの末尾は
-- print("__________________________") -- table_print(configuration) -- print("__________________________")
となっているので -- を削除してコメントを外す。さらに、以下の不具合を修正する。
if ( app:match("^#.*$") or app:match("^$") or app:match("^\s+$") ) then ↓ if ( app:match("^#.*$") or app:match("^$") or app:match("^%s+$") ) then
そして、 lua crtmpserver.lua を実行すると、以下のように設定内容が表示される。
[applications] => table ( [1] => table ( [name] => applestreamingclient [protocol] => dynamiclinklibrary [description] => Apple Streaming Client [aliases] => table ( [1] => asc ) ) [2] => table ( [validateHandshake] => true [acceptors] => table ( [1] => table ( [port] => 1935 [protocol] => inboundRtmp [ip] => 0.0.0.0 ) [2] => table ( [port] => 8080 [protocol] => inboundRtmpt [ip] => 0.0.0.0 ) ) [name] => appselector [protocol] => dynamiclinklibrary [description] => Application for selecting the rest of the applications [default] => true ) [3] => table ( [externalStreams] => table ( ) [aliases] => table ( [1] => simpleLive [2] => vod [3] => live [4] => WeeklyQuest [5] => SOSample [6] => oflaDemo ) [mediaFolder] => /var/lib/crtmpserver/mediaFolder [protocol] => dynamiclinklibrary [seekGranularity] => 1.5 [keyframeSeek] => true [validateHandshake] => true [name] => flvplayback [clientSideBuffer] => 12 [description] => FLV Playback Sample [acceptors] => table ( [1] => table ( [protocol] => inboundLiveFlv [port] => 6666 [waitForMetadata] => true [ip] => 0.0.0.0 ) [2] => table ( [port] => 9999 [protocol] => inboundTcpTs [ip] => 0.0.0.0 ) ) ) [4] => table ( [targetServers] => table ( [1] => table ( [localStreamName] => stream1 [keepAlive] => true [targetStreamType] => live [targetUri] => rtmp://gigi:spaima@localhost/vod [emulateUserAgent] => My user agent ) ) [abortOnConnectError] => true [name] => proxypublish [protocol] => dynamiclinklibrary [description] => Application for forwarding streams to another RTMP server [acceptors] => table ( [1] => table ( [port] => 6665 [protocol] => inboundLiveFlv [ip] => 0.0.0.0 ) ) ) [5] => table ( [active] => false [protocol] => dynamiclinklibrary [targetServer] => localhost [streams] => table ( [1] => mp4:lg.mp4 ) [randomAccessStreams] => false [name] => stresstest [numberOfConnections] => 10 [description] => Application for stressing a streaming server [targetApp] => vod ) [rootDirectory] => /usr/lib/crtmpserver/applications ) [pathSeparator] => / [logAppenders] => table ( [1] => table ( [name] => console appender [type] => coloredConsole [level] => 6 ) [2] => table ( [name] => file appender [type] => file [fileName] => /var/log/crtmpserver/main.log [level] => 6 ) ) [daemon] => true
crtmpserver.luaで外したコメントは元に戻しておくこと。
【crtmpserverログの確認】
crtmpserverのログファイルは /var/log/crtmpserver に存在するので、Servicesテーブルを確認する。
+-----------------------------------------------------------------------------+ | Services| +---+---------------+-----+-------------------------+-------------------------+ | c | ip | port| protocol stack name | application name | +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 1935| inboundRtmp| 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| 6665| inboundLiveFlv| proxypublish| +---+---------------+-----+-------------------------+-------------------------+
【ffmpegからストリーム送信】
以下のコマンドを実行し、ffmpegからcrtmpserverにストリームを送信する。
ffmpeg -stream_loop -1 -re -i hoge.mp4 -vcodec copy -metadata streamName=ffmpeg -f flv tcp://localhost:6666
各パラメーターの詳細は以下の通り。
参考:最新ffmpegのオプションまとめ - MobileHackerz Knowledgebase Wiki
- -stream_loop -1
入力メディアを永久に繰り返し出力する。 - -re
入力メディアと同じスピードで出力する。このオプションを指定しないと、最初から最後まで再生されない(試して見て欲しい)。 - -i hoge.mp4
入力メディアとして便宜上hoge.mp4を指定する。 - -vcodec copy
入力メディアの映像データーをそのままコピーする(CPU負荷が低い)。 - -metadata streamName=ffmpeg
ffmpegと言う名前でストリームを配信する。その名前は再生対象のメディアを指定するときのキーワードとなる。 - -f flv
FLVフォーマットでメディアを出力する。 - tcp://localhost:6666
crtmpserverのinboundLiveFlvプロトコルスタック、flvplaybackアプリケーションに出力する(現段階では意味を正確に理解していないため、これ以上は説明できないので悪しからず)。
上記のコマンドを実行することで、crtmpserverのログには以下のように出力される。
1483539098:3:/build/buildd/crtmpserver-1.0~dfsg/thelib/src/netio/epoll/tcpacceptor.cpp:154:Accept:Client connected: 127.0.0.1:42042 -> 0.0.0.0:6666 1483539098:6:/build/buildd/crtmpserver-1.0~dfsg/thelib/src/protocols/liveflv/inboundliveflvprotocol.cpp:46:Initialize:parameters: <MAP name="" isArray="false"> <STR name="ip">0.0.0.0</STR> <UINT16 name="port">6666</UINT16> <STR name="protocol">inboundLiveFlv</STR> <STR name="sslCert"></STR> <STR name="sslKey"></STR> <BOOL name="waitForMetadata">true</BOOL> </MAP> 1483539098:6:/build/buildd/crtmpserver-1.0~dfsg/thelib/src/protocols/liveflv/inboundliveflvprotocol.cpp:51:Initialize:_waitForMetadata: 1 1483539098:4:/build/buildd/crtmpserver-1.0~dfsg/thelib/src/netio/epoll/iohandlermanager.cpp:100:RegisterIOHandler:Handlers count changed: 6->7 IOHT_TCP_CARRIER 1483539098:6:/build/buildd/crtmpserver-1.0~dfsg/thelib/src/protocols/liveflv/baseliveflvappprotocolhandler.cpp:45:RegisterProtocol:protocol CTCP(10) <-> TCP(100) <-> [ILFL(101)] registered to app flvplayback 1483539098:3:/build/buildd/crtmpserver-1.0~dfsg/thelib/src/protocols/liveflv/inboundliveflvprotocol.cpp:184:SignalInputData:Stream metadata: <MAP name="" isArray="true"> <MAP name="__index__value__0" isArray="true"> <DOUBLE name="audiocodecid">10.000</DOUBLE> <DOUBLE name="audiodatarate">125.000</DOUBLE> <DOUBLE name="audiosamplerate">44100.000</DOUBLE> <DOUBLE name="audiosamplesize">16.000</DOUBLE> <STR name="compatible_brands">isommp42</STR> <DOUBLE name="duration">0.000</DOUBLE> <STR name="encoder">Lavf57.61.100</STR> <DOUBLE name="filesize">0.000</DOUBLE> <DOUBLE name="framerate">29.970</DOUBLE> <DOUBLE name="height">720.000</DOUBLE> <STR name="major_brand">mp42</STR> <STR name="minor_version">0</STR> <BOOL name="stereo">true</BOOL> <STR name="streamName">ffmpeg</STR> <DOUBLE name="videocodecid">7.000</DOUBLE> <DOUBLE name="videodatarate">2172.205</DOUBLE> <DOUBLE name="width">1280.000</DOUBLE> </MAP> </MAP>
【FlowPlayerのインストール】
FlowPlayerでMP4を再生する にしたがってFlowPlayerをインストールする。
【FlowPlayerにRTMPプラグインを追加】
以下のページからRTMP Streaming Pluginをダウンロードする。
(今回はバージョン 3.2.13をダウンロードした。)
上記ページのDownloadセクションからダウンロードしたZIPファイルをFlowPlayer本体をインストールしたディレクトリ /var/www/html/flowplayer に展開する。
. ├── LICENSE.txt ├── README.txt ├── example │ ├── hoge.mp4 │ ├── index.html │ └── style.css ├── flowplayer-3.2.13.min.js ├── flowplayer-3.2.18.swf ├── flowplayer.controls-3.2.16.swf └── flowplayer.rtmp ├── LICENSE.txt ├── README.txt └── flowplayer.rtmp-3.2.13.swf 2 directories, 11 files
【sample1.htmlの作成】
前述のtree表示内容に記載のexampleディレクトリにsample1.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: 'ffmpeg', 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/sample1.html にアクセスしてRTMPを再生する。