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


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

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

說明:

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

 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 和 360

 

命令詳解

RTMP

語法:rtmp {...}
上下文:root
保存所有RTMP設置的塊

 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM