nginx-rtmp-moduleを使ってスマートフォンへの生放送配信を実験

#はじめに
簡単にニコニコ動画や、USTREAMのようなスマートフォンへの生放送配信を試すために、実験用の環境をnginxベースに構築したのでシェアしたいと思います。

#フロー
全体としては、こんな感じ。一つずつ説明して行きます。

![flow.png](https://qiita-image-store.s3.amazonaws.com/0/43766/6627dfa3-e883-90c4-b123-b3b9e582fdaa.png)


#iPhoneの動画ストリーミングはHLS対応必須
iPhoneでのストリーミング配信はApple独自の再生方法であるHLSへの変換が必須となります。
HLSとは拡張子は.m3u8というテキストファイルで.ts(mpeg-2)へのパスが書かれているtextファイルです。

	#EXTM3U
	#EXT-X-VERSION:3
	#EXT-X-MEDIA-SEQUENCE:0
	#EXT-X-ALLOW-CACHE:YES
	#EXT-X-TARGETDURATION:11
	#EXTINF:10.026700,
	stream000.ts
	#EXTINF:10.010011,
	stream001.ts
	#EXTINF:9.576244,
	stream002.ts
	#EXT-X-ENDLIST

このファイルの場合はstream000.ts〜stream002.tsまで順番に再生した後、EXT-X-ENDLISTで終了しますが、このENDがない場合は、stream003.tsが来る迄、待ち状態になり、何度もクライアント側は.m3u8ファイルにアクセス + 作成されたタイミングで再生します。

#.tsファイルの長さ->遅延 or サーバー負荷
.tsファイルの長さはnginx.confのhls_fragmentで設定し、ここに設定された秒数で動画ファイルを分割していきます。
>hls_fragment 1s;

長い:
ブロードキャスト(放送)からtsファイルに書き出しを行うバッファ時間が長くなるため、遅延大。
短い:
.m3u8へのファイルのアクセス回数の増加によりサーバー負荷が増加。

#nginx-rtmp-moduleを使ってみる

手軽にHLSやRTMPを実験するにあたって、nginx-rtmp-moduleを使い、簡単にrtmp受信〜HLS変換を試す事ができます。
(※インストール方法は別途記載します.)

使い方は通常のnginx.confの下に、下記のようにrtmpの設定を記述します。
下記の記述を行う事で、rtmpプロトコルで受信した動画をHLSファイルに変換することができます。

	vim /etc/nginx/nginx.conf
	rtmp {
	        server {
	                listen 1935;
	                application hls {
	                	live on;
	                	hls  on;
	            		
	            		#HLS playlist & fragment のディレクトリを指定
	            		hls_path /usr/local/nginx/html/hls;

	            		# HLS fragment の長さ(1個のtsファイルの動画の長さ)
	            		hls_fragment 1s;

	            		hls_type live;
	                }
	        }
	}

#動画を配信してみましょう。
動画の配信にはFLashMediaLiveEncoderをインストールして、行います。
1.Formatを .h264を指定
2.FMS URLにnginxのサーバーURLを記述 例) rtmp://192.168.0.1:1935/hls
3.Stream名を記述 例) test
4.スタート
![flash-streaming.png](https://qiita-image-store.s3.amazonaws.com/0/43766/e874b864-f40d-c6f4-4fb4-c58d54187a5a.png)

#hlsファイルが作成される
これだけで/usr/local/nginx/html/hls/配下に .m3u8と 複数の.tsファイルが作成される事が分かります。
(Stream名をtestにしたので、test.m3u8という命名ルールになります.)
![command.png](https://qiita-image-store.s3.amazonaws.com/0/43766/f4918266-6278-7e77-b199-d4c4674e72cc.png)

#プレイヤーを設置
iPhoneで再生するために、html/index.htmlに動画プレイヤーを設置しましょう。
index.htmlを表示させるためにhttpの向き先をnginxに追記します。

	http {
	    include        mime.types;
	    server {
	        listen       80;
	        server_name  localhost;
	        location / {
	            root   /usr/local/nginx/html;
	            index  index.html index.htm;


usr/loca/nginx/html/index.htmlにプレイヤーを設置

	<!DOCTYPE html>
	<html>
	<head>
		<title>HLS Test Player </title>
	</head>
	<body>
	    <video id="example_video_1" class="video-js vjs-default-skin" controls autoplay
	                width="640" height="360" data-setup="{}">
	    	<source src="/hls/test.m3u8" type="application/x-mpegURL" />
	    </video>
	</body>
	</html>


#nginx.confの記述次第で他にもこんなことが..

##rtmpで受信したデータを録画する
この設定で/tmp/record_outputの配下に受信したファイルをmpegで保存することができます。

	rtmp {
	    server {
	        application hls {
				record all;
				record_path /tmp/record_output;
				record_unique on;


##rtmpで受信したデータをUSTREAMにも配信
USTREAMのRTMPの受け先にファイルをストリームすることもできます。
(USTREAM側で録画中にすること)

		application multi {
		     live on;
		     meta copy;
		     wait_video on;
		     push rtmp://xxxxx.fme.ustream.tv/ustreamVideo/11111111/xxxxxxxxxxxxxx;
		}


#おしまい
今回は手軽にnginxのモジュールを使って、rtmp~HLS配信を試す事ができました。
商用の環境を構築するには

> * Red5 : 無償
> * Wowza : 有償
> * Adobe Flash Media Server (FMS) : 有償

などの選択肢があるようですので用途に応じて使ってみるのが良いのではないでしょうか。