・・・レイアウトした 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フォルダ
を移動、配信ユーザー名に変更してある。 
また、usersフォルダ直下のフォルダ名が配信URLとなる。
ソレを踏まえた上で このフォルダレイアウトを基準に
以下サンプルソース群を参照して欲しい。| 
nginxで Webサーバを構成してある場合は サイトフ
ォルダとして usersフォルダが使用されているケース
もあるので、利用環境によっては この構成も一考が
必要になる。
ただ、Windowsであれば WindowsServerでなく
ても、IIS7.x以降を導入でき、Webサイトを立ち上げ
るコトは出来る。 因ってnginxをWebサーバとして
構成する必要はナイだろう。 |  | 
ユーザーフォルダ 
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 と なっている箇所を 任意に変更したユーザーフォルダ名に置換するだけで使用可能。
 
このサンプルは 参考構成中の users\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);
            }
        }
    });
}
 |  | 
■ index.html
| ・・・各ユーザーフォルダに納まっている 各配信のWebページを処理するHTMLファイル。
 
因みに、見た目の変更が必要ナイ場合は、配布されたままの状態で使用出来るファイルである。| 上述 nginx.conf内 [rtmp]-[server] 各[application] で hls を無効にしている場合は機能しない。 |  
このサンプルでは配布版に対し、bobyへクラスを割り当て、外部CSSへのアクセスを行う行を準備している。| <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> |  | 
■ その他重要なポイント
| ・上記3つ以外のファイルは 配布されているまま 変更する事無く利用出来る。
・nginxフォルダ内の構成は、稼動する上で重要な要素であり、理解していないうちは変更を推奨しない。
・hlsを有効にし、配信ページも機能させ、その装飾を任意に構成したい場合は 各ユーザーフォルダ配下の default.css へ定義を列挙する。
・IISへは、取得したドメインをバインドさせるよう新規Webサイトを追加し、ソコへ仮想フォルダとして nginx配下の各ユーザーフォルダを設置する。
 | 
■ ひまストで配信するだけなら ココまでで設定は完了となるのだが・・・
| ・・・他の配信サイトへも同時配信したい場合は、その分 nginx.confへ 追記事項が増える。
 
■ 具体的には、nginx.conf内 [rtmp]-[server] 各[application] 配下に| ただ、ひまストと異なり、外部配信サーバからの配信を受け付ける機能の無いサービスが殆どだ。
その場合、nginxを用いたマルチキャストを実行するには、配信データを対象サービスへpushしてやる必要がある。
要は、ひまスト鯖とOBSを直接接続する配信と同じ状態を、他の配信サービスへ 平行して実行するよう
nginxに指定するコトになると思えば判り易いだろう。 |  
・・の様な形式で追記する。
その他のライブ配信サービスを対象にする場合の書式は、コチラを参考にすると良いだろう。
■ 上述のTwitchを例に抜粋すると、コンなカンジ ▼| push rtmp://live-tyo.twitch.tv/app/{Twitchから配布されたユーザーキー}; |  
複数対象を追記し、多数のサービスへ同時配信させるコトも可能。
但し いずれの場合も、回線のトラフィックは増大する、利用しているISPの規約や性能を考慮すべきだ。| 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から配布されたユーザーキー};
        } |  | 
 
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。