【nginx】Nginx視頻流模塊nginx-rtmp-module

nginx-rtmp-module:https://github.com/arut/nginx-rtmp-modulehtml

源碼地址:https://github.com/Tinywan/PHP_Experience

說明:node

  rtmp的延遲主要取決於播放器設置,但流式傳輸軟件,流的比特率和網絡速度(以及響應時間「ping」)可能會對延遲產生影響,具備播放器的本地rtmp服務器 使用「否」緩衝區(如0.1-0.2秒緩衝區等)可能會在0.8-1.2秒之間老是延遲,當事情正好工做時python

 nginx配置文件nginx

rtmp { server { listen 1935; chunk_size 4096; application live { live on; record off;         exec ffmpeg -i rtmp://localhost/live/$name -threads 1 -c:v libx264 -profile:v baseline -b:v 350K -s 640x360 -f flv -c:a aac -ac 1 -strict -2 -b:a 56k rtmp://localhost/live360p/$name;
 } application live360p { live on; record off; allow publish 127.0.0.1; allow publish 0.0.0.0; deny publish all; } } }

 

以上爲vlc播放測試結果:分別爲720 和 360git

 

命令詳解

RTMPgithub

語法:rtmp {...}
上下文:root
保存全部RTMP設置的塊ubuntu

 

server瀏覽器

語法:server {...}
上下文:rtmp
聲明RTMP服務器實例服務器

rtmp { server { } }

 

listen網絡

語法:listen(addr [:port] | port | unix:path)[bind] [ipv6only = on | off] [so_keepalive = on | off | keepidle:keepintvl:keepcnt | proxy_protocol]
上下文:服務器

將監聽套接字添加到NGINX以接受RTMP鏈接

server {
    listen 1935;
}

 

application

語法:應用程序名稱{...}
上下文:服務器

建立RTMP應用程序。 不像http位置應用程序名稱不能是一個模式(正則?)。

server {
    listen 1935;
    application myapp {
    }
}

 

timeout

語法:超時值
上下文:rtmp,服務器

套接字超時。 這個值主要用於寫做。 大多數狀況下,RTMP模塊不會指望除發佈者套接字之外的全部套接字上的任何活動。 若是你想斷開套接字快速斷開鏈接,可使用keepalive或RTMP ping等有效工具。 默認值是1分鐘。

timeout 60s;

 

ping

語法:ping 值
上下文:rtmp,服務器

RTMP ping時間間隔。 零點關閉。 RTMP ping是用於活動鏈接檢查的協議功能。 一個特殊的數據包被髮送到遠程對等體,而且在一個由ping_timeout指令指定的超時期限內獲得應答。 若是在這段時間內沒有收到ping應答,則鏈接關閉。 ping的默認值是1分鐘。 默認的ping超時時間是30秒。

ping 3m;
ping_timeout 30s;

 

chunk_size

語法:chunk_size value
上下文:rtmp,服務器

流複用的最大塊大小。默認值是4096.這個值越大,CPU開銷就越低。這個值不能小於128。

 

max_queue

max_message

語法:max_queue value
上下文:rtmp,服務器

輸入數據信息的最大尺寸。全部的輸入數據都被拆分紅消息(還有塊)。部分消息在等待完成時保存在內存中。理論上來講,傳入的消息可能很是大,這多是服務器穩定性的一個問題。在許多狀況下,默認值1M就足夠了。

 

on_publish

語法:on_publish url
上下文:rtmp, server, application
描述:這個能夠設置爲一個API接口(GET方式接受全部參數),會給這個API接口返回8個參數:

注意:nginx-rtmp-module-1.1.11 中的on_publish 回調的請求爲post請求方式:

       $app = $_GET['app']; $swfurl = $_GET['swfurl']; $tcurl = $_GET['tcurl']; $pageurl = $_GET['pageurl']; $addr = $_GET['addr']; $clientid = $_GET['clientid']; $call = $_GET['call']; $name = $_GET['name'];

 

 

on_publish_done

語法:on_publish_done url
上下文:rtmp, server, application
描述:等同於 on_done 的表現,但只適用於發佈結束事件。

$app = $_GET['app']; $swfurl = $_GET['swfurl']; $tcurl = $_GET['tcurl']; $pageurl = $_GET['pageurl']; $addr = $_GET['addr']; $clientid = $_GET['clientid']; $call = $_GET['call']; $name = $_GET['name'];

 

on_publish_done和on_publish的不一樣的區別就是on_publish(call=publish),而on_publish_done(call=publish_done)

 實際案例:

        notify_method get; application live { live on; on_publish http://mworker.baidu.com/Notify/Notify;  }

注意要點要使用on_publish和on_publish_done 必須的添加 notify_method get; 不然的話OBS推流老是推不上去的,服務器不認哦!!!!

on_connect

語法:on_connect url
上下文:rtmp, server

設置HTTP鏈接的回調。當客戶端鏈接問題的命令HTTP請求是異步發出命令和處理被掛起,直到它返回結果代碼。若是返回HTTP 2XX代碼,而後RTMP會話繼續。3XX的代碼使RTMP重定向到另外一個應用程序,其名稱取自LocationHTTP響應頭。不然,鏈接被丟棄。

注意:這個指令不該用範圍容許的,由於應用還處於鏈接階段不明。

HTTP請求接收多個參數。POST方法用於應用程序/ x-WWW的形式了urlencoded MIME類型。下面的參數被傳遞給調用者:

  • 調用=鏈接
  • 地址 - 客戶端IP地址
  • 應用 - 應用名稱
  • flashVer - 客戶端flash版本
  • swfUrl - 客戶端SWF網址
  • tcUrl - tcUrl
  • PAGEURL - 客戶端頁面網址

如何使用,官方都說了要加載

除了上述項目明確地傳遞給connect命令的全部參數也與回調發送。您應當區分鏈接參數從播放/發佈參數。玩家一般具備播放/流發佈名設置鏈接字符串分開的一種特殊方式。做爲一個例子下面是這些參數是如何在JWPlayer設置

object(stdClass)[7] public 'app' => string 'live' (length=4) public 'flashver' => string 'WIN 24,0,0,186' (length=14) public 'swfurl' => string 'http://sewise.amai8.com/lib/jwplayer/jwplayer.flash.swf' (length=55)   //客戶端播放器地址
  public 'tcurl' => string 'rtmp://121.26.206.11/live/' (length=27)  //直播流播放器地址
  public 'pageurl' => string 'http://sewise.amai8.com/player/jw_player' (length=40) public 'addr' => string '218.108.35.150' (length=14)  //客戶端播放地址
  public 'epoch' => string '982956199' (length=9)  //這個每次都會去變得,VLC、手機、瀏覽器、播放器
  public 'call' => string 'connect' (length=7)

 

斷開OBS推送流到服務器(固然了客戶端也會同時斷掉的)

curl http://150.261.11.180/control/drop/publisher?app=live&name=4001482742932

 

斷開當前客戶端播放的連接,可是不會斷開OBS的推流系統

curl http://150.26.11.180/control/drop/client?app=live&name=4001482742932&addr=115.192.190.59&clientid=95
curl http://150.26.11.180/control/drop/client?app=live&name=4001482742932&clientid=116

實踐操做記錄:200 OBS能夠推流。500 OBS 推流不能夠

 

header($this->https(500));   // PHP 服務端設置Http狀態碼的回調

 

功能:

【1】實現推流權限的控制

【2】推流黑白名單

 

 

on_update

語法:on_update url
context:rtmp,server,application

設置更新回調。這個回調用週期調用 notify_update_timeout。若是一個請求返回HTTP結果,而不是2xx鏈接被終止。這能夠用於同步已過時的會話。兩個額外的參數time,並timestamp 傳遞給這個處理程序:

  • time 是播放/發佈呼叫的秒數
  • timestamp 是發送到客戶端的最後一個音頻/視頻數據包的RTMP時間戳

您可使用timestamp參數單獨限制每一個用戶的播放持續時間。

on_update http://example.com/update;

推流地址:rtmp://192.168.18.143/live/880?wsSecret=e2112a78822bf4ea9cdb3989e114344c&wsTime=1479196093

回調返回的全部參數:

'app' => string 'live' (length=4) 'flashver' => string 'LNX 9,0,124,2' (length=13) 'swfurl' => string '' (length=0) 'tcurl' => string 'rtmp://192.168.18.143:1935/live' (length=31) 'pageurl' => string '' (length=0) 'addr' => string '192.168.18.73' (length=13) 'clientid' => string '3321' (length=4) 'call' => string 'update_play' (length=11) 'time' => string '728' (length=3) 'timestamp' => string '716600' (length=6) 'name' => string '880' (length=3) 'wsSecret' => string 'e2112a78822bf4ea9cdb3989e114344c' (length=32) 'wsTime' => string '1479196093' (length=10)

 

播放客戶端IP地址:192.168.18.73

on_record_done

語法:on_record_done url
背景:RTMP,服務器,應用程序,記錄

設置record_done回調。除了常見的HTTP回調變量它接收到如下值

  • 記錄 - 在配置或空字符串內聯錄音機錄像機名
  • 路徑 - 錄製的文件路徑
on_record_done http://example.com/recorded;

該URL地址一GET方式獲取全部的參數以下:

'app' => string 'live' (length=4) 'flashver' => string 'FMLE/3.0 (compatible; FMSc/1.0)' (length=31) 'swfurl' => string 'rtmp://192.168.18.143/live' (length=26) 'tcurl' => string 'rtmp://192.168.18.143/live' (length=26) 'pageurl' => string '' (length=0) 'addr' => string '192.168.18.73' (length=13) 'clientid' => string '334' (length=3) 'call' => string 'record_done' (length=11) 'recorder' => string '' (length=0) 'name' => string 'test123' (length=7) 'path' => string '/home/tinywan/video_recordings/test123-1491375411.flv' (length=53)

 

再次錄像中止返回結果不一樣點

'path' => string '/home/tinywan/video_recordings/test123-1491375411.flv' (length=53)

 RTMP直接錄製成mp4格式:

application live { allow play all;             live on;             record all;             record_path /tmp/flv;             record_unique on;  exec_record_done ffmpeg -y -i $path -acodec libmp3lame -ar 44100 -ac 1 -vcodec libx264 /home/tinywan/video_recordings/$basename.mp4; }

 

record_suffix

語法:record_suffix value
context:rtmp,server,application,recorder

設置記錄文件後綴。默認爲「.flv」。

record_suffix _recorded.flv;

記錄後綴能夠是strftime格式的格式。如下指令

record_suffix %Y%m%d%H%M%S.flv;

生成的flv的格式爲:123-20170406093012.flv  ,123表明推流名稱

 

record_unique

語法:record_unique on|off
context:rtmp,server,application,recorder

若是打開,將當前時間戳附加到錄製文件。不然,每次新錄製發生時,重寫相同的文件。默認關閉。

record_unique on;

  開啓後的案例: 123-1491386267.flv   

沒有開啓的案例: 123.flv

添加這個參數:

record_suffix %Y%m%d%H%M%S.flv;

生成的錄製文件爲:12320170406094409.flv   (123 爲推流名稱)

經驗分享:

record_unique on;

把以上兩個同時開啓,錄製文件爲:123-149144326920170406094749.flv 這樣方便之後錄製文件的處理

 

record_append

語法:record_append on|off
context:rtmp,server,application,recorder

切換文件追加模式。打開錄像機後,將新數據附加到舊文件,或者在缺乏時建立它。舊數據與文件中的新數據之間沒有時間差距。默認關閉。

record_append on;

 

record_lock

語法:record_lock on|off
context:rtmp,server,application,recorder

當打開當前錄製的文件被鎖定fcntl。能夠從別處檢查,以查明正在記錄哪一個文件。默認關閉。

record_lock on;

 

在FreeBSD上,您可使用flock工具來檢查。在Linux flockfcntl 是可有可無的,因此你要寫一個簡單的腳本檢查文件鎖定狀態。這是一個這樣的腳本的例子isunlocked.py

#!/usr/bin/python

import fcntl, sys

sys.stderr.close()
fcntl.lockf(open(sys.argv[1], "a"), fcntl.LOCK_EX|fcntl.LOCK_NB)

 

record_max_size

語法:record_max_size size
context:rtmp,server,application,recorder

設置最大記錄文件大小。

record_max_size 128K;

 

record_max_frames

語法:record_max_frames nframes
context:rtmp,server,application,recorder

設置每一個錄製文件的最大視頻幀數。

record_max_frames 2;

 

record_interval

語法:record_interval time
context:rtmp,server,application,recorder

從新啓動錄音後這個數(毫秒)秒。默認關閉。零表示錄音之間沒有延遲。若是record_unique關閉,則全部記錄片斷都將寫入同一個文件。不然附加時間戳,使文件不一樣(給定record_interval超過1秒)。

record_interval 1s;

record_interval 15m;

 

 

timeout

syntax: timeout value
context: rtmp, server

套接字超時 該值主要用於寫入。大多數時間RTMP模塊不會指望除發佈商套接字以外的全部套接字上都有任何活動。若是想要斷開套接字來快速斷開鏈接,請使用活動工具,如keepalive或RTMP ping。默認爲1分鐘。

timeout 60s;

ping

syntax: ping value
context: rtmp, server

RTMP ping間隔。零點關閉。RTMP ping是用於主動鏈接檢查的協議功能。一個特殊的數據包被髮送到遠程對等體,而且在ping_timeout指令指定的超時期間預期回覆。若是在這段時間內沒有收到ping回覆,則鏈接被關閉。ping的默認值爲1分鐘。默認ping超時爲30秒。

ping 3m;
ping_timeout 30s;

max_streams

語法:max_streams value

背景:RTMP,服務器

設置RTMP流的最大數量。 數據流被複用到單個數據流中。 不一樣的通道用於發送命令,音頻,視頻等。默認值爲32,這在許多狀況下一般是肯定的。

max_streams 32;

ack_window

 設置RTMP確認窗口大小。 它是接收的字節數,在該字節以後,對等體應向遠端發送確認分組。 默認值爲5000000。

ack_window 5000000;

chunk_size

syntax: chunk_size value
context: rtmp, server

流複用的最大塊大小。 默認值爲4096.該值越大,CPU開銷越低。 此值不能小於128。

chunk_size 4096;

max_queue

max_message

語法:max_queue value
context:rtmp,server

輸入數據消息的最大大小。全部輸入數據都分爲消息(還有更多的塊)。等待它完成時,部分消息保存在內存中。在理論上,傳入的消息可能很是大,這多是服務器穩定性的一個問題。默認值1M對於不少狀況都是足夠的。

max_message 1M;

buflen

語法:buflen time
context:rtmp,server

設置默認緩衝區長度。一般客戶端set_buflen在播放以前發送RTMP 命令,並重置此設置。默認是1000 ms

buflen 5s;

 

說明:

 記錄器 - 記錄器名稱

 

path - 記錄文件路徑(recorded file path) (/tmp/rec/mystream-1389499351.flv)
filename - 省略目錄的路徑(path with directory omitted )(mystream-1389499351.flv)
basename - 擴展名省略的文件名(file name with extension omitted )(mystream-1389499351)
dirname - 目錄路徑(directory path) (/tmp/rec)

Nginx RTMP傳遞參數:

exec_record_done /home/www/bin/rtmpRecorded.sh  

path  

basename $dirname;

 

$name   推流名稱  (mystream

 

$path   記錄文件路徑   (/tmp/rec/mystream-1389499351.flv)

 

$filename     省略目錄的路徑  (mystream-1389499351.flv)

 

$basename   擴展名省略的文件名  (mystream-1389499351)

 

$dirname   目錄路徑   (/tmp/rec)

 

基本視頻信息獲取實際案例記錄

 

【1】獲取視頻文件大小:
FILESIZE=`stat -c "%s"basename.mp4`
等同於:FILESIZE=`stat --format "%s"basename.mp4`

 

【2】獲取視頻錄製時間:
ffmpeg -i 4001481608583-1481696526.flv  2>&1 | awk '/Duration/ {split($2,a,":");print a[1]*3600+a[2]*60+a[3]}'
 
【3】自動截取封面圖片
ffmpeg -y -ss 00:00:10 -i $fullname -vframes 1 $VIDEO_PATH/$basename.jpg

【4】轉碼成MP4

ffmpeg -y -i $fullname -vcodec copy -acodec copy $VIDEO_PATH/$basename.mp4

 

下面所有stat命令是可用的選項:

    %a     八進制表示的訪問權限
    %A     可讀格式表示的訪問權限
    %b     分配的塊數(參見 %B)
    %B     %b 參數顯示的每一個塊的字節數
    %d     十進制表示的設備號
    %D     十六進制表示的設備號
    %f     十六進制表示的 Raw 模式
    %F     文件類型
    %g     屬主的組 ID
    %G     屬主的組名
    %h     硬鏈接數
    %i     Inode 號
    %n     文件名
    %N     若是是符號連接,顯示器所連接的文件名
    %o     I/O 塊大小
    %s     所有佔用的字節大小
    %t     十六進制的主設備號
    %T     十六進制的副設備號
    %u     屬主的用戶 ID
    %U     屬主的用戶名
    %x     最後訪問時間
    %X     最後訪問時間,自 Epoch 開始的秒數
    %y     最後修改時間
    %Y     最後修改時間,自 Epoch 開始的秒數 
    %z     最後改變時間
    %Z     最後改變時間,自 Epoch 開始的秒數

 

 

Setup Nginx-RTMP on Ubuntu 14.04:https://www.vultr.com/docs/setup-nginx-rtmp-on-ubuntu-14-04

Ubuntu 14.04 安裝Nginx的RTMP模塊:https://www.vultr.com/docs/setup-nginx-rtmp-on-ubuntu-14-04

 

參考連接:

【視頻直播點播nginx-rtmp開發手冊中文版】

https://www.cnblogs.com/zx-admin/p/5783523.html

https://www.bbsmax.com/A/Vx5MlQLJNr/

https://blog.csdn.net/kevinw9/article/details/52984826

【Nginx-rtmp 直播媒體實時流實現】

https://www.cnblogs.com/wunaozai/p/9427730.html

相關文章
相關標籤/搜索