・・・レイアウトした RTMP鯖としての nginxの状態を参考までに公開。
■ 尚、このTipsは、
サイトの公開準備(ドメイン確保、DDNS設定など)が済んでいる必要はある点に注意。
また、LAN内で DNSサーバ ないし、簡易DNS機能憑きのルータ使用していないと 面倒事が多いが、その点には触れていない。
あくまで "Webサイトくらいは公開出来ている" コトが このログの内容を活用する為の最低条件となる。
ツマり、誰にでも判るようなログにはしていない、察しが悪い向きには この内容では解説になっていないだろう。 |
■ このログの設定サンプルは、
使用しているLANボードのプロパティで、ネットワークアクセスで常用するメインIPアドレスの他に、
RTMP鯖として配信で用いるIPアドレス 192.168.xa.xb を追加設定してあるコトが前提となっている。
xa は メインアドレスと同じに、xb は 未使用の数字を指定する。
また、3つ配信を処理する状態を例としているが、必要の無いユーザーフォルダと application設定は削除していい。 |
■ フォルダ構成
| 配布されている nginx_1.7.4_rtmp_1.1.4 のフォルダレイアウ
トでは、WindowsServerで稼動している おきつね鯖の IISとの
連動に不便である為、usersフォルダを追加し、liveフォルダ
を移動、配信ユーザー名に変更してある。
nginxで Webサーバを構成してある場合は サイトフ
ォルダとして usersフォルダが使用されているケース
もあるので、利用環境によっては この構成も一考が
必要になる。
ただ、Windowsであれば WindowsServerでなく
ても、IIS7.x以降を導入でき、Webサイトを立ち上げ
るコトは出来る。 因ってnginxをWebサーバとして
構成する必要はナイだろう。 |
また、usersフォルダ直下のフォルダ名が配信URLとなる。
ソレを踏まえた上で このフォルダレイアウトを基準に
以下サンプルソース群を参照して欲しい。 |
ユーザーフォルダ
MainUser ExternalUserA ExternalUserB は、任意に名称を変更し、配信のURLとして用いる。
■ nginx.conf
confフォルダ配下に格納されている nginxの基本的な動作を定義する設定が収まるファイル。
以下サンプル中の MainUser ExternalUserA ExternalUserB は、それぞれのユーザーフォルダ名であると同時に、
配信URLとして扱われる。 因って それらを、任意に変更したユーザーフォルダ名に置換するだけで使用が可能となる。
worker_processes 4;
error_log logs/error.log crit;
events {
worker_connections 1024;
}
http {
access_log off;
include mime.types;
types {
application/x-mpegURL m3u8;
video/MP2T ts;
}
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
server_name live.okitsunesama.com;
listen 8888;
location / {
root users;
index index.html index.htm;
}
location /stat.xsl {
root users;
}
location /stat {
allow 127.0.0.1;
allow 192.168.0.0/16;
allow 172.16.0.0/12;
allow 10.0.0.0/8;
deny all;
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /control {
allow 127.0.0.1;
allow 192.168.0.0/16;
allow 172.16.0.0/12;
allow 10.0.0.0/8;
deny all;
rtmp_control all;
}
}
}
rtmp {
server {
listen 1935;
access_log logs/rtmp_access.log;
ping 30s;
ping_timeout 10s;
drop_idle_publisher 15s;
application MainUser {
live on;
wait_video on;
meta copy;
allow publish 192.168.xa.xb;
hls on;
hls_path users/MainUser/ts;
hls_continuous on;
hls_playlist_length 18s;
}
application ExternalUserA {
live on;
wait_video on;
meta copy;
allow publish 192.168.xa.xb;
hls on;
hls_path users/ExternalUserA/ts;
hls_continuous on;
hls_playlist_length 18s;
}
application ExternalUserB {
live on;
wait_video on;
meta copy;
allow publish 192.168.xa.xb;
hls on;
hls_path users/ExternalUserB/ts;
hls_continuous on;
hls_playlist_length 18s;
}
}
|
|
■ utils.js
・・・各ユーザーフォルダに納まっているファイル。
MainUser と なっている箇所を 任意に変更したユーザーフォルダ名に置換するだけで使用可能。
function GetFlashVersion(){var m,f,o;try{o=navigator.plugins["Shockwave Flash"];if(o[0].enabledPlugin!=null){f=o.description.slice(16)}}catch(p){try{m=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");f=m&&m.GetVariable("$version")}catch(n){try{m=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");f=m&&m.GetVariable("$version")}catch(l){}}}f=/(\d+)[^\d]+(\d+)[^\d]*(\d*)/.exec(f);return f?[1*f[1],1*f[(f[1]*1>9?2:3)]*1]:[0,0]}
if (GetFlashVersion()[0] == 0 && !navigator.platform.match("Win")) { location.href = "./index_m.html"; }
var arg = (location.search.substring(1) || "").toLowerCase();
function SetDisplay(element, value) {
document.getElementById(element).style.display = value;
}
function SetOpacity(element, value) {
element.style.opacity = value;
}
function SetOpacityIE(element, value) {
element.style.filter = "alpha(opacity=" + (value * 100) + ")";
}
function OnHlsEnabled(text) {
if (navigator.platform.match("Win")) {
SetDisplay("linkQR", "inline");
} else {
SetDisplay("linkMobile", "inline");
}
}
function OnHlsDisabled(text) {
SetDisplay("linkMobile", "none");
SetDisplay("linkQR", "none");
}
function CheckHLS() {
try {
var xhr = new XMLHttpRequest();
} catch (e) {
return false;
}
xhr.open("GET", "./ts/MainUser.m3u8", true);
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
xhr.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
OnHlsEnabled(this.responseText);
} else if (this.readyState === 4 && this.status !== 200) {
OnHlsDisabled();
}
}
xhr.send(null);
}
function Body_OnLoad(self) {
if (arg == "window") {
SetDisplay("bottom", "none");
} else {
if (arg == "small") {
SetDisplay("linkSmall", "none");
Bottom_SetTimer();
} else {
SetDisplay("linkNormal", "none");
Bottom_SetTimer(30);
}
}
if (typeof document.getElementById("bottom").style.opacity != "string") {
SetOpacity = SetOpacityIE;
}
CheckHLS();
}
function Bottom_OnMouseover(self) {
SetOpacity(document.getElementById("bottom"), 1.0);
Bottom_SetTimer();
}
function QR_OnClick(self) {
self.style.display = "none";
}
var timerBottom = 0;
function Bottom_Hide() {
if (timerBottom != 0) {
clearTimeout(timerBottom);
}
timerBottom = 0;
Bottom_Fadeout();
}
function Bottom_SetTimer(duration) {
if (timerBottom != 0) { clearTimeout(timerBottom) }
timerBottom = setTimeout(Bottom_Hide, 1000 * (duration || 10));
}
function Bottom_Fadeout() {
var alphaBottom = 1;
var timerFade = setInterval(function(){
if (timerBottom == 0) {
alphaBottom -= 0.09;
if (alphaBottom < 0.15) {
alphaBottom = 0.15;
clearInterval(timerFade);
}
SetOpacity(document.getElementById("bottom"), alphaBottom);
} else {
clearInterval(timerFade);
}
}, 100);
}
function ShowQRCODE() {
var container = document.getElementById("QR");
container.style.display = (container.style.display == "none") ? "block" : "none";
var uri = location.href.match(/(.*\/).*$/)[1];
container.innerHTML = '<img src="http://chart.apis.google.com/chart?\chs=150x150&cht=qr&chl=' + escape(uri) + '"/> ' + uri;
}
function SetupPlayer() {
if (arg) {
var w, h;
if (arg == "window") {
w = "100%"; h = "100%";
with (document.getElementsByTagName("body")[0].style) {
margin = 0;
padding = 0;
}
document.getElementById("container").style.height = h;
} else if (arg == "small") {
w = "640px"; h = "360px";
} else {
w = "864px"; h = "486px";
}
document.getElementById("container").style.width = w;
document.getElementById("player").style.height = h;
}
flowplayer("player", "./flowplayer/flowplayer-3.2.18.swf", {
plugins: { influxis: { url: "./flowplayer/flowplayer.rtmp-3.2.13.swf", netConnectionUrl: 'rtmp://' + location.hostname + '/MainUser/' } },
clip: { url: 'MainUser', live: true, autoPlay: true, scaling: 'fit', provider: 'influxis',
onMetaData: function() {
setTimeout(CheckHLS, 20 * 1000);
},
onMetaDataChange: function() {
setTimeout(CheckHLS, 20 * 1000);
}
}
});
}
|
このサンプルは 参考構成中の users\MainUser にレイアウトする前提として記述されている。 |
■ index.html
・・・各ユーザーフォルダに納まっている 各配信のWebページを処理するHTMLファイル。
上述 nginx.conf内 [rtmp]-[server] 各[application] で hls を無効にしている場合は機能しない。 |
因みに、見た目の変更が必要ナイ場合は、配布されたままの状態で使用出来るファイルである。
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="default.css" type="text/css">
<title>ページタイトル</title>
<script src="./utils.js"></script>
<script src="./flowplayer/flowplayer-3.2.13.min.js"></script>
</head>
<body class="CatalogView" onLoad=Body_OnLoad(this)>
<div id="container">
<div id="player" class="iExp" style="background-color:#5588cc;color:#eeeeee;max-width:1500px !important;"></div>
<script type="text/javascript">SetupPlayer();</script>
</div>
<p id="bottom" onMouseover=Bottom_OnMouseover(this)><a id="linkSmall" href="?small">小</a><a id="linkNormal" href="./">中</a><a href="?window">窓</a><a id="linkMobile" href="./index_m.html">モバイル</a><a id="linkQR" href="javascript:ShowQRCODE();">QRコード</a></p>
<div id="QR" style="display: none;" onClick=QR_OnClick(this)></div>
</body>
</html> |
このサンプルでは配布版に対し、bobyへクラスを割り当て、外部CSSへのアクセスを行う行を準備している。 |
■ その他重要なポイント
・上記3つ以外のファイルは 配布されているまま 変更する事無く利用出来る。
・nginxフォルダ内の構成は、稼動する上で重要な要素であり、理解していないうちは変更を推奨しない。
・hlsを有効にし、配信ページも機能させ、その装飾を任意に構成したい場合は 各ユーザーフォルダ配下の default.css へ定義を列挙する。
・IISへは、取得したドメインをバインドさせるよう新規Webサイトを追加し、ソコへ仮想フォルダとして nginx配下の各ユーザーフォルダを設置する。
|
■ ひまストで配信するだけなら ココまでで設定は完了となるのだが・・・
・・・他の配信サイトへも同時配信したい場合は、その分 nginx.confへ 追記事項が増える。
ただ、ひまストと異なり、外部配信サーバからの配信を受け付ける機能の無いサービスが殆どだ。
その場合、nginxを用いたマルチキャストを実行するには、配信データを対象サービスへpushしてやる必要がある。
要は、ひまスト鯖とOBSを直接接続する配信と同じ状態を、他の配信サービスへ 平行して実行するよう
nginxに指定するコトになると思えば判り易いだろう。 |
■ 具体的には、nginx.conf内 [rtmp]-[server] 各[application] 配下に
push rtmp://live-tyo.twitch.tv/app/{Twitchから配布されたユーザーキー}; |
・・の様な形式で追記する。
その他のライブ配信サービスを対象にする場合の書式は、コチラを参考にすると良いだろう。
■ 上述のTwitchを例に抜粋すると、コンなカンジ ▼
application MainUser {
live on;
wait_video on;
meta copy;
allow publish 192.168.xa.xb;
hls on;
hls_path users/MainUser/ts;
hls_continuous on;
hls_playlist_length 18s;
push rtmp://live-tyo.twitch.tv/app/{witchから配布されたユーザーキー};
}
|
複数対象を追記し、多数のサービスへ同時配信させるコトも可能。
但し いずれの場合も、回線のトラフィックは増大する、利用しているISPの規約や性能を考慮すべきだ。 |
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。