「自己開(kāi)發(fā)直播」實(shí)現(xiàn)nginx-rtmp-module多頻道輸入輸出與權(quán)限控制

之前寫(xiě)了一篇文章,利用nginx和nginx-rtmp-module實(shí)現(xiàn)直播。

不過(guò),之前只是做到了能夠直播而已,只能一個(gè)人推流,并沒(méi)有實(shí)現(xiàn)多人多頻道輸入輸出,也沒(méi)有權(quán)限控制,只要知道rtmp的URL就能夠推送。

本文是在之前文章的基礎(chǔ)上繼續(xù)的。

原文地址:通過(guò)Nginx-rtmp-module搭建直播服務(wù)器并實(shí)現(xiàn)直播

一、權(quán)限控制方面

說(shuō)實(shí)話,我查這個(gè)查了很久,也沒(méi)查出個(gè)所以然,最后還是花了半天的時(shí)間,研究了一下nginx-rtmp-module的文檔,最后搞了半天才弄明白。

文檔中主要有兩個(gè)部分需要注意:

live配置的publish_notify部分

https://github.com/arut/nginx-rtmp-module/wiki/Directives#publish_notify

publish_notify中Notify的配置部分

https://github.com/arut/nginx-rtmp-module/wiki/Directives#notify

1、live的publish_notify

所謂的publish_notify是涉及publish_notify默認(rèn)是off的,主要涉及推送的過(guò)程中一些事件。

開(kāi)啟publish_notify即可進(jìn)行Notify的配置操作。

publish_notify on;

2、Notify的配置

Notify的配置相關(guān)是涉及直播的事件并執(zhí)行回調(diào)代碼。

比如:推流鏈接、直播開(kāi)啟、直播結(jié)束狀態(tài),然后異步調(diào)用http的鏈接,進(jìn)行一些邏輯的處理。

主要的配置參數(shù)有下面這些:

on_connect

on_play

on_publish

on_done

on_play_done

on_publish_done

on_record_done

on_update

......

從上面的配置參數(shù)可以看出,能夠觸發(fā)連接、直播、輸出、直播結(jié)束等等,從而能夠進(jìn)行權(quán)限驗(yàn)證、

比如,當(dāng)觸發(fā)推流的時(shí)候,通過(guò) on_publish?http://www.example.com/uri?進(jìn)行權(quán)限控制,接收相關(guān)參數(shù)并進(jìn)行控制,如果用戶不存在,則不允許推流。

二、多頻道輸入輸出

這里的多頻道輸入輸出意思是:多個(gè)人直播,每個(gè)人有不同的輸出地址。

1、直播推流端

多個(gè)人有不同的推流和直播地址,就涉及了直播參數(shù),而實(shí)際上,各大平臺(tái)直播的時(shí)候,除了地址,都有一個(gè)直播密鑰或者是直播碼。

以O(shè)BS舉例,串流類型選擇自定義流媒體服務(wù)器,然后會(huì)出現(xiàn)一個(gè)URL和流密鑰。

而流密鑰就是實(shí)現(xiàn)多頻道輸入輸出的重點(diǎn)。

2、rtmp Publish配置

既然需要進(jìn)行權(quán)限控制,就要使用publish,首先進(jìn)行權(quán)限的驗(yàn)證,證明有推流權(quán)限。

所以rtmp的配置如下(最后會(huì)給出一個(gè)完整的配置示例):

因?yàn)橹皇翘接憴?quán)限控制,因此hls之類的不需要關(guān)心,我也注釋了。

? ? #設(shè)置直播的application名稱是 myapp

? ? application myapp{

? ? ? ? live on; #live on表示開(kāi)啟直播模式? ? ? ?

? ? ? ? publish_notify on;

? ? ? ? on_publish http://tp5.ptbird-ubuntu/on_publish.html;

? ? ? ? #hls on;

? ? ? ? #hls_path /tmp/hls;

? ? ? ? #hls_fragment 2s;

? ? ? ? #hls_playlist_length 6s;

? ? }

關(guān)鍵配置是:on_publish?http://tp5.ptbird-ubuntu/on_publish.html;

后面的?http://tp5.ptbird-ubuntu/on_publish.html?是假設(shè)在web服務(wù)器上的處理程序,網(wǎng)上有的將這個(gè)邏輯假設(shè)在本機(jī)nginx,我是建議不要混在一起,直接在別的能夠連接的web服務(wù)器上部署即可。

我是架設(shè)在我的另一臺(tái)ubuntu kylin的web服務(wù)器上。

反正能訪問(wèn)的php處理就可以了,別的說(shuō)多了也沒(méi)用。

3、權(quán)限驗(yàn)證URL

一個(gè)示例的配置如下所示,這是一個(gè)模板配置示例。

流密鑰的格式是:test?pass=123456,可以看出這個(gè)非常像url的get參數(shù)配置,test就是用戶的name,而pass就是密碼。

為什么沒(méi)有name=test

因?yàn)閚ame是rtmp on_publish的默認(rèn)參數(shù),name是不能更改的。

絕對(duì)不能使用GET['name'],而應(yīng)該使用POST

一開(kāi)始我總是使用get去獲取參數(shù),但是發(fā)現(xiàn)一直無(wú)法成功,也沒(méi)辦法驗(yàn)證 - -

后來(lái)網(wǎng)上查了查,發(fā)現(xiàn)不能使用get獲取,雖然流密鑰的格式像是get類型,但是必須使用POST獲取參數(shù)。

自定義參數(shù)

除了name不能更改之外,其他的都是可以自定義參數(shù)的

比如pass=123456&check=123456這樣的

三、代碼驗(yàn)證權(quán)限

1、ThinkPHP5版本

這里使用php進(jìn)行驗(yàn)證,我順便將上面?http://tp5.ptbird-ubuntu/on_publish.html?這個(gè)url部署在一個(gè)thinkphp5的框架中。

因此實(shí)際上我是有一個(gè)路由的,才會(huì)使用html后綴的URL。

// 配置直播推送的url

Route::rule('on_publish','index/Publish/index');

實(shí)際的邏輯很簡(jiǎn)單:

接收兩個(gè)參數(shù)

通過(guò)數(shù)據(jù)庫(kù)進(jìn)行驗(yàn)證

返回驗(yàn)證信息

必須返回http頭,返回2xx表示成功,3xx表示跳轉(zhuǎn),4xx表示失敗

一般驗(yàn)證失敗都是返回404就可以,一定返回標(biāo)準(zhǔn)的404頭(一開(kāi)始我一直驗(yàn)證失敗,后面發(fā)現(xiàn),就是返回的頭的問(wèn)題)

而處理的代碼如下:

下面代碼是基于thinkphp5來(lái)處理的,其中沒(méi)有涉及數(shù)據(jù)庫(kù)的操作,只是有兩個(gè)參數(shù)test和test2兩個(gè)用戶,兩個(gè)密碼

而返回http頭的狀態(tài)也是用的thinkphp5的返回方式,下面會(huì)有第二種普通的處理方式。

<?php

/**

* Author: root

* Date? : 17-3-19

* time? : 下午4:58

* Site? : www.ptbird.cn

* There I am , in the world more exciting!

*/

namespace app\index\controller;

use think\Request;

class Publish {

? ? // index

? ? public function index(Request $request){

? ? ? ? // 接受name和pass param可以自動(dòng)選擇get或者是post

? ? ? ? $name=$request->param('name');

? ? ? ? $pass=$request->param('pass');

? ? ? ? // 設(shè)置用戶名和密碼

? ? ? ? $savename= "test";

? ? ? ? $savepass = "123456";

? ? ? ? if(empty($name) || empty($pass)){

? ? ? ? ? ? echo "串碼流不正確";

? ? ? ? ? ? // 這個(gè)是thinkphp5的返回頭信息的函數(shù)

? ? ? ? ? ? return json('')->code(404)->header(['Not Found']);

? ? ? ? }else{

? ? ? ? ? ? if(strcmp($name,$savename)==0 && strcmp($pass,$savepass)==0){

? ? ? ? ? ? ? ? // 默認(rèn)是返回2xx的頭,因此不需要進(jìn)行控制

? ? ? ? ? ? ? ? echo "串碼流正確";

? ? ? ? ? ? ? ? // 我在這里添加了另一個(gè)test2 和 123456的用戶

? ? ? ? ? ? }else if(strcmp($name,'test2')==0 && strcmp($pass,'123456')==0){

? ? ? ? ? ? ? ? echo "串碼流正確";

? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? echo "串碼流不正確";

? ? ? ? ? ? ? ? return json('')->code(404)->header(['Not Found']);

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

2、普通的php驗(yàn)證

下面的代碼,是網(wǎng)上的代碼,一個(gè)道理,就不多說(shuō)了。

// ?user=user&pass=pass

@$name = $_POST['name'];

@$pass = $_POST['pass'];

$savename= test;

$savepass = password;

if(empty($name) || empty($pass)){

? ? echo "串碼流不正確!";

? ? header('HTTP/1.0 404 Not Found');

}else{

? ? if (strcmp($name, $savename) == 0 && strcmp($pass, $savepass) == 0) {

? ? ? ? echo "串碼流正確!";

? ? } else {

? ? ? ? echo "串碼流不正確!";

? ? ? ? header('HTTP/1.0 404 Not Found');

? ? }

}

四、直播與觀看直播

經(jīng)過(guò)上面的配置,現(xiàn)在可以進(jìn)行多人直播。

上面的操作中我有兩個(gè)用戶,一個(gè)是test,另一個(gè)是test2,現(xiàn)在分別使用這兩個(gè)用戶進(jìn)行直播。

1、test用戶的直播 使用OBS 18

2、test2用戶的直播 使用obs 0.65

3、test3用戶的直播(失敗)

將用戶名設(shè)置成test3

因?yàn)榉祷亓?04,因此直播失敗。

五、總結(jié)

on_publish可以實(shí)現(xiàn)權(quán)限控制,而其他的notify參數(shù),比如on_connect可以設(shè)置當(dāng)用戶進(jìn)行推流之后,就可以設(shè)置用戶的直播狀態(tài)為進(jìn)行直播等等。

之后再繼續(xù)研究....

文章已經(jīng)結(jié)束啦

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容