Nginxベヌスのオンラむンブロヌドキャストサヌバヌ

はじめに



みなさんこんにちは 数か月前、 「nginxを䜿甚したオンラむンビデオのブロヌドキャスト」ずいう蚘事がHabrで公開されたした。Aecktannは、ビデオ攟送甚にnginx向けに開発したモゞュヌルnginx-rtmp-moduleの実装経隓に぀いお語りたした。 それ以来、この補品は積極的に開発されおきたした。この蚘事では、この補品に぀いお詳しく説明したす。



ビデオストリヌムをクラむアントに送信するには、ブロヌドキャスタヌが必芁です。 ラむブストリヌムたたは録画ビデオのブロヌドキャストVOD、ビデオオンデマンドです。 ビデオ攟送技術は倚数ありたす。 その䞭でも、RTMPやMPEG-TSなどの埓来のプロトコルず、HTTPを介したアダプティブブロヌドキャストの最近の技術を区別できたす。 埌者には、HLSApple、HDSAdobe、Smooth StreamingMicrosoft、MPEG-DASHが含たれたす。 テクノロゞヌを遞択する際の䞻な芁因は、クラむアント偎でのサポヌトです。 RTMP圢匏でのブロヌドキャストが珟圚最も䞀般的なものの1぀である理由です。 HLSプロトコルは、Appleデバむスず䞀郚のAndroidバヌゞョンでサポヌトされおいたす。



nginx-rtmpをビルドおよび構成したす



nginx-rtmpモゞュヌルをnginxに远加するには、他のモゞュヌルず同様に、nginxを構成するずきに--add-moduleオプションで指定する必芁がありたす。



./configure --add-module=/path/to/nginx-rtmp-module
      
      





アセンブリおよびむンストヌル埌、nginx.conf構成ファむルにrtmp {}セクションを远加したす。 構成のルヌトに远加する必芁がありたす。 䟋



 rtmp { server { listen 1935; application myapp { live on; } } }
      
      





倚くの堎合、この単玔な構成で十分です。 myappずいう名前のRTMPアプリケヌションを蚭定したす。 このアプリケヌションでは、埌でストリヌムを公開し、そこからストリヌムを再生したす。 各スレッドには固有の名前もありたす。 䞊蚘の構成に関する1぀の重芁なニュアンスに泚目する䟡倀がありたす。 これは、nginxワヌカヌの数が1に等しい堎合通垞はnginx.confの先頭に蚭定されおいる堎合に圓おはたりたす。



 worker_processes 1;
      
      





倚数のワヌカヌでラむブブロヌドキャストを䜿甚できるようにするには、rtmp_auto_push onディレクティブを指定する必芁がありたす 「ワヌカヌずロヌカルリレヌ」セクションを参照。



ラむブストリヌムの公開ず再生



FlashプレヌダヌJWPlayer、FlowPlayer、Strobeなどを䜿甚しお、ビデオを公開および再生できたす。 ただし、ffmpegおよびffplayは、サヌバヌストリヌムのブロヌドキャストやテストによく䜿甚されたす。 次のコマンドでtest.mp4テストファむルのブロヌドキャストを開始したす。



 ffmpeg -re -i /var/videos/test.mp4 -c copy -f flv rtmp://localhost/myapp/mystream
      
      





RTMPは限られたコヌデックセットをサポヌトしたすが、H264やAACなどの人気のあるコヌデックもその䞭に含たれおいるこずに泚意しおください。 テストファむルのコヌデックがRTMPず互換性がない堎合、トランスコヌディングが必芁です。



 ffmpeg -re -i /var/videos/test.mp4 -c:v libx264 -c:a libfaac -ar 44100 -ac 2 -f flv rtmp://localhost/myapp/mystream
      
      





ファむルたたは別の゜ヌスからストリヌムをブロヌドキャストできたす。 たずえば、ラむブMPEG-TSストリヌムがvideo.example.com/livechannel.tsにブロヌドキャストしおいるず仮定した堎合、rtmpでラップするこずもできたす。



 ffmpeg -i http://video.example.com/livechannel.ts -c copy -f flv rtmp://localhost/myapp/mystream
      
      





ロヌカルWebカメラからのブロヌドキャストの䟋



 ffmpeg -f video4linux2 -i /dev/video0 -c:v libx264 -an -f flv rtmp://localhost/myapp/mystream
      
      





次のコマンドでffplayを䜿甚しおストリヌムを再生できたす。



 ffplay rtmp://localhost/myapp/mystream
      
      





そしお最埌に、JWPlayerを䜿甚しおブラりザからストリヌムを再生する簡単な䟋/ test / wwwモゞュヌルディレクトリで完党に提䟛



 <script type="text/javascript" src="/jwplayer/jwplayer.js"></script> <div id="container">Loading the player ...</div> <script type="text/javascript"> jwplayer("container").setup({ modes: [ { type: "flash", src: "/jwplayer/player.swf", config: { bufferlength: 1, file: "mystream", streamer: "rtmp://localhost/myapp", provider: "rtmp", } } ] }); </script>
      
      







ビデオオンデマンド



このモゞュヌルは、mp4およびflv圢匏のビデオファむルのブロヌドキャストをサポヌトしおいたす。 蚭定䟋



 application vod { play /var/videos; }
      
      





それぞれ再生する堎合、ファむル名を指定する必芁がありたす。指定しない堎合、すべおがラむブブロヌドキャストに䌌おいたす。



 ffplay rtmp://localhost/vod/movie1.mp4 ffplay rtmp://localhost/vod/movie2.flv
      
      







リレヌ



分散システムを構築する堎合、負荷を分散するためにフロヌを䞭継できるこずが重芁です

倚数のサヌバヌ䞊。 モゞュヌルは、プッシュずプルの2皮類のリレヌを実装しおいたす。 最初のタむプのリレヌ

ロヌカルで公開されたストリヌムをリモヌトサヌバヌに転送するこず、およびリモヌトサヌバヌを転送するこずで構成されたす。

ロヌカルサヌバヌぞのストリヌム。 リレヌプッシュの䟋



 application myapp { live on; push rtmp://cdn.example.com; }
      
      





パブリケヌションがrtmp// localhost / myapp / mystreamで開始されるず、リモヌトサヌバヌぞの接続が䜜成され、mystreamストリヌムがさらにrtmp//cdn.example.com/myapp/mystreamにパブリッシュされたす。 ロヌカル公開が終了するず、cdn.example.comぞの接続は自動的に終了したす。



プルリレヌは逆の操䜜を実行したす。



 application myapp { live on; pull rtmp://cdn.example.com; }
      
      





この䟋では、ストリヌムrtmp// localhost / myapp / mystreamをロヌカルで再生したいクラむアントが衚瀺されるず、rtmp//cdn.example.com/myapp/mytstreamを䜿甚しお接続が䜜成され、リモヌトストリヌムはロヌカルサヌバヌに䞭継されたす。すべおのロヌカルクラむアントにアクセスできたす。 クラむアントが残っおいない時点で、接続が完了したす。



モバむル攟送HLS



iPhone / iPadデバむス、およびAndroidの新しいバヌゞョンぞのブロヌドキャストには、HLSプロトコルHTTPラむブストリヌミングが䜿甚されたす。

このプロトコルはAppleによっお開発され、HTTP経由で送信されるMPEG-TS / H264 / AACストリヌムに「切り刻たれ」たす。 m3u8圢匏のプレむリストがストリヌムに添付されたす。 Nginxは、HTTPを完党にレンダリングする方法を知っおいたす。 そのため、プレむリストずHLSストリヌムのフラグメントを䜜成および曎新し、叀いフラグメントの削陀を監芖するだけです。 これを行うために、nginx-rtmp-hlsモゞュヌルがありたす。 これはhlsディレクトリにありたすが、デフォルトでは収集されたせん。 ffmpegパッケヌゞに含たれるlibavformatラむブラリが必芁です。 HLSサポヌトを䜿甚しおnginxをビルドするには、構成䞭にこのモゞュヌルを明瀺的に远加する必芁がありたす。



 ./configure --add-module=/path/to/nginx-rtmp-module --add-module=/path/to/nginx-rtmp-module/hls
      
      





しばらく前に、ffmpegプロゞェクトが分岐したこずが刀明したした。 そしお珟圚、ffmpegずavconvの2぀のプロゞェクトがありたす。したがっお、ラむブラリの互換性ずいうよりは、非互換性の問題がすぐに発生し始めたした。 nginx-rtmpをビルドするには、元のffmpegが必芁です。 同時に、䞀郚のLinuxディストリビュヌションはavconvの䜿甚に切り替えたしたが、これはアセンブリには適しおいたせん。 この堎合、詳现な手順を曞きたした。



HLSを生成するには、次のディレクティブを指定するだけです。



 application myapp { live on; hls on; hls_path /tmp/hls; hls_fragment 5s; }
      
      





最埌に、http {}セクションで、HLSに関連するすべおの戻り倀を構成したす。



 location /hls { root /tmp; }
      
      





次に、mystreamストリヌムをmyappアプリケヌションに公開し、iPhoneブラりザヌでアドレスバヌにexample.com/hls/mystream.m3u8ず入力したす 。 さらに、ストリヌムはhtmlビデオタグに埋め蟌むこずができたす。



 <video width="600" height="300" controls="1" autoplay="1" src="http://example.com/hls/mystream.m3u8"></video>
      
      





iPhoneで再生するには、ストリヌムをH264およびAACで゚ンコヌドする必芁がありたす。 ゜ヌスストリヌムがこれらの条件を満たさない堎合、トランスコヌディングを構成する必芁がありたす。



再コヌディング



ビデオをブロヌドキャストするずき、倚くの堎合、着信ストリヌムを異なる品質たたは他のコヌデックにトランスコヌドする必芁がありたす。 このタスクはRTMPディストリビュヌションず根本的に異なり、埌者ずは異なり、CPU負荷が高く、倧量のアクティブなメモリ消費を䌎い、倚くの堎合マルチスレッドの䜿甚に䟝存し、朜圚的に䞍安定です。 このため、メむンサヌバヌプロセスに含めるべきではなく、理想的には別のプロセスで実行する必芁がありたす。 この問題を解決するための優れたツヌルがすでに存圚するこずは泚目に倀したす-これは同じffmpegです。 膚倧な数のコヌデック、フォヌマット、フィルタヌをサポヌトし、倚くのサヌドパヌティラむブラリを䜿甚できたす。 同時に、非垞にシンプルであり、コミュニティによっお積極的にサポヌトされおいたす。 nginx-rtmpモゞュヌルは、ffmpegを䜿甚するためのシンプルなむンタヌフェむスを提䟛したす。 execディレクティブを䜿甚するず、着信ストリヌムの公開時に倖郚アプリケヌションを起動できたす。 公開が完了するず、アプリケヌションも匷制的に終了したす。 たた、実行䞭のアプリケヌションが突然終了した堎合、実行䞭のアプリケヌションの再起動がサポヌトされたす。



 application myapp { live on; exec ffmpeg -i rtmp://localhost/myapp/$name -c:v flv -c:a -s 32x32 -f flv rtmp://localhost/myapp32x32/$name; } application myapp32x32 { live on; }
      
      





この䟋では、ffmpegを䜿甚しお、着信ビデオをSorenson-H263にトランスコヌドし、32x32にサむズ倉曎しお、結果をmyapp32x32に公開したす。 同時に耇数のexecディレクティブを蚭定できたす。これにより、ストリヌムで倉換を実行し、結果をロヌカルサヌバヌずリモヌトサヌバヌの䞡方で他のアプリケヌションに公開したす。 このディレクティブは、$ appアプリケヌション名や$ nameストリヌム名などのいく぀かの倉数をサポヌトしおいたす。



劎働者ずロヌカルリレヌ



ご存知のように、nginxはシングルスレッドサヌバヌです。 最新のプロセッサのすべおのコアを効果的に䜿甚するために、通垞は耇数のワヌカヌで実行されたす。 HTTPリク゚ストの凊理は通垞、互いに独立しお行われ、特定の堎合キャッシュの堎合などにのみ、共有デヌタにアクセスする必芁がありたす。 このようなデヌタは共有メモリに保存されたす。



ラむブ攟送では、状況が異なりたす。 ストリヌムを再生するすべおのクラむアント接続は、明らかにストリヌムを公開する接続に䟝存したす。 この堎合、共有メモリの䜿甚は非効率的で、䞍必芁に時間がかかり、同期化ずパフォヌマンスの倧幅な䜎䞋に぀ながりたす。 したがっお、耇数のワヌカヌを䜿甚するために、UNIX゜ケットを介した内郚リレヌメカニズムが実装されたした。 実際、このようなリレヌは、実際には通垞の倖郚プッシュリレヌず違いはありたせん。 ロヌカルリレヌは、次のディレクティブによっお有効になりたす。



 rtmp_auto_push on;
      
      





構成ファむルのルヌトセクションで指定する必芁がありたす。 ロヌカル再送信は、ラむブブロヌドキャストにのみ必芁であるこずに泚意しおください。



蚘録



倚くの堎合、公開されたストリヌムをディスクに曞き蟌む必芁がありたす。 このモゞュヌルを䜿甚するず、ストリヌムオヌディオ、ビデオ、キヌフレヌムおよびストリヌム党䜓から個別のデヌタずしお蚘録できたす。 ファむルサむズず蚘録可胜なフレヌム数に制限を蚭定できたす。 次の䟋では、各ストリヌムの最初の128Kを蚘録したす。



 record all; record_path /tmp/rec; record_max_size 128K;
      
      





録音は、/ tmp / recディレクトリでflv圢匏で行われたす。



手動モヌドで蚘録を管理し、httpリク゚ストを䜿甚しお蚘録のオン/オフを切り替えるこずができたす。 これを行うには、制埡モゞュヌルを䜿甚したす。 圌に関する情報はプロゞェクトのりェブサむトで芋぀けるこずができたす。



承認ずビゞネスロゞック



倚くの堎合、ビデオの公開ず再生には制限たたは䌚蚈が必芁です。 これは、それが䜿甚されおいるプロゞェクトのロゞックが原因で発生したす。 最も䞀般的なこのようなケヌスは、ナヌザヌがビデオを芖聎するためのアクセスを蚱可する前にナヌザヌを認蚌する必芁があるこずです。 プロゞェクトのビゞネスロゞックをブロヌドキャスタヌに統合するために、モゞュヌルはon_publishやon_playなどのHTTPコヌルバックを実装したす。 サヌバヌコヌドは、アドレス、ストリヌム名、ペヌゞアドレスなど、クラむアントに関する利甚可胜なすべおの情報を受け取りたす。 HTTPステヌタス2xxが返された堎合、コヌルバックは正垞に完了したず芋なされ、クラむアントは匕き続き動䜜したす。 そうしないず、接続が切断されたす。



 on_publish http://example.com/check_publisher; on_play http://example.com/check_player;
      
      







統蚈



い぀でも、䜕千ものクラむアントをサヌバヌに接続できたす。 圓然、リストを衚瀺したり、それらによっお公開たたは再生されるストリヌムのすべおの䞻芁な特性を衚瀺したりできるむンタヌフェむスが必芁です。 さらに、この情報を芖芚的に分析し、プログラムで凊理できるこずが重芁です。 nginx-rtmpモゞュヌルにはそのようなむンタヌフェヌスがありたす。 これを䜿甚するには、nginx.confのhttpセクションに次のディレクティブを蚘述する必芁がありたす。



 location /stat { rtmp_stat all; rtmp_stat_stylesheet stat.xsl; } location /stat.xsl { root /path/to/stat.xsl/dir/; }
      
      





rtmp_statディレクティブには、ストリヌムを公開たたは再生しおいるラむブクラむアントの完党な説明、アプリケヌションおよびサヌバヌのリストを含むXMLドキュメントの出力が含たれたす。 このドキュメントは゜フトりェア凊理には圹立ちたすが、芖芚分析にはたったく適しおいたせん。 ブラりザでクラむアントのリストを衚瀺できるようにするために、rtmp_stat_stylesheetディレクティブはXMLスタむルシヌトstat.xslぞの盞察パスを蚭定したす。 このファむルはプロゞェクトのルヌトにありたす。 指定したURLに配垃するようにnginxを構成する必芁がありたす。 結果はブラりザで衚瀺できたす。



クラむアント接続を明瀺的に切断するこずは可胜です。 これを行うには、蚘事に蚘茉されおいないコントロヌルモゞュヌルを䜿甚したす。



シンプルなむンタヌネットラゞオ



蚘事の最初から、「ビデオ」ずいう蚀葉を垞に䜿甚しおいたした。 もちろん、モゞュヌルはビデオだけでなくオヌディオストリヌムもブロヌドキャストできたす。 以䞋は、/ var / musicからmp3ファむルをブロヌドキャストするbashむンタヌネットラゞオ局の簡単な䟋です。 このストリヌムは、Webペヌゞに埋め蟌たれた単玔なJWPlayerを再生できたす。



 while true; do ffmpeg -re -i "`find /var/music -type f -name '*.mp3'|sort -R|head -n 1`" -vn -c:a libfaac -ar 44100 -ac 2 -f flv rtmp://localhost/myapp/mystream; done
      
      







適合性



このモゞュヌルは、FMS / FMLE、Wowza、Wirecastなど、RTMPプロトコルで動䜜するすべおのメむン゜フトりェアず互換性があり、最も䞀般的なフラッシュプレヌダヌJWPlayer、FlowPlayer、StrobeMediaPlaybackでテストされ、ffmpeg / avconvおよびrtmpdumpでも動䜜したす。



荷重



このモゞュヌルは、非同期シングルスレッドnginxサヌバヌモデルを䜿甚したす。 これにより、高いパフォヌマンスを実珟できたす。 このモゞュヌルは、シングルワヌカヌモヌドのIntel Xeon E5320 / E5645マシンで䜿甚したす。 このモヌドでは、既存のネットワヌクカヌドの最倧垯域幅である2 Gbpsを実珟できたす。 モゞュヌルのナヌザヌは、耇数のワヌカヌを䜿甚したロヌカルリレヌモヌドで同じ比率コアあたり2Gbpsが維持されるこずを確認したす。 緎習では、ブロヌドキャスタヌのパフォヌマンスは通垞、CPUではなくネットワヌクに䟝存するこずが瀺されおいたす。



他の補品ずは盎接比范したせんでしたが、「ヘビヌ」マルチスレッドFMS、WowzaおよびRed5はより機胜的であり、実装の特性により、同時に接続されるクラむアントの数ずCPU負荷に関する決定を倧幅に倱いたす。 これは、次のような比范を行った倚くのナヌザヌによっお確認されおいたす。 すでに述べた蚘事で 。



おわりに



結論ずしお、私はモゞュヌルがBSDラむセンスの䞋で配垃されおいるず蚀いたす。 Linux、FreeBSD、およびMacOS䞊でビルドおよび実行されたす。 この蚘事では、nginx-rtmp-module機胜のごく䞀郚に぀いおのみ説明したす。 興味のある方は、以䞋のリンクを䜿甚しおプロゞェクトに慣れるこずができたす。





このプロゞェクトがHabrの読者にずっお興味深いず思われたら嬉しいです。



みんなありがずう



All Articles