Posted on

使用ffmpeg濾鏡功能做影片合成

下載ffmpeg

https://ffmpeg.org/download.html

推一個時鐘文字的影片

ffmpeg的指令如下

ffmpeg  -f lavfi -i color=c=0x00ff00:s=800x450 -vf "settb=AVTB, setpts='trunc(PTS/1K)*1K+st(1,trunc(RTCTIME/1K))-1K*trunc(ld(1)/1K)', drawtext=text='STREAM2-%{localtime}.%{eif\:1M*t-1K*trunc(t*1K)\:d}':x=100:y=100:fontsize=32:fontcolor=white" -c:v libx264 -f flv rtmp://192.168.189.11/live/test2
  1. -f lavfi -i color=c=0x00ff00:s=800×450:這部分使用lavfi作為輸入來源,並創建一個顏色填充的視頻流。 c=0x00ff00指定填充的顏色為綠色,s=800×450指定分辨率為 800×450。
  2. -vf “settb=AVTB, setpts=’trunc(PTS/1K)1K+st(1,trunc(RTCTIME/1K))-1Ktrunc(ld(1)/1K)’, drawtext=text=’STREAM2 -%{localtime}.%{eif\:1Mt-1Ktrunc(t*1K)\:d}’:x=100:y=100:fontsize=32:fontcolor=white”:這部分使用- vf標誌來應用視頻過濾器。其中有兩個主要的過濾器:
    • settb=AVTB, setpts=’trunc(PTS/1K)1K+st(1,trunc(RTCTIME/1K))-1Ktrunc(ld(1)/1K)’:這個過濾器設置視頻時間戳。 settb=AVTB設置時間基準,setpts用於計算新的時間戳,其中包括根據PTS(顯示時間戳)和RTCTIME(實時時鐘時間)進行一些計算。
    • drawtext=text=’STREAM2-%{localtime}.%{eif\:1Mt-1Ktrunc(t1K)\:d}’:x=100:y=100:fontsize=32:fontcolor=white “:這個過濾器使用drawtext來在視頻上繪製文本。它在視頻左上角繪製了一個文本,其中包含了時間戳信息。%{localtime}插入本地時間,%{eif\:1Mt-1K* trunc(t*1K)\:d}用於插入一個經過格式化的時間戳。
  3. -c:v libx264:這部分設置視頻編碼器為libx264,用於將視頻編碼為H.264格式。
  4. -f flv rtmp://192.168.189.11/live/test2:這部分設置輸出格式為FLV,並指定RTMP服務器的地址。視頻會通過RTMP流式傳輸到指定的地址。在這裡,rtmp://192.168.189.11/live/test2是RTMP服務器的地址。

使用虛擬鏡頭來推流

ffmpeg -f dshow -rtbufsize 200M -i video=OBS-Camera -pix_fmt yuv420p -c:v libx264 -profile:v baseline -level:v 3.1 -preset:v ultrafast -s 480x270 -g 240 -an -f flv -y rtmp://172.16.46.89/live/0101_dealerPC1 
  1. -f dshow -rtbufsize 200M -i video=OBS-Camera:這部分設置輸入來源為DirectShow,並指定攝像頭的名稱為 “OBS-Camera”。 -rtbufsize 200M 設置了實時緩衝區的大小為 200MB。
  2. -pix_fmt yuv420p:這部分設置輸出視頻的像素格式為YUV 4:2:0,這是常見的視頻格式。
  3. -c:v libx264 -profile:v baseline -level:v 3.1 -preset:v ultrafast:這部分設置視頻編碼器為libx264,使用baseline配置文件,3.1級別,並設置預設(編碼速度)為ultrafast,這意味著編碼速度非常快。
  4. -s 480×270:這部分設置輸出視頻的分辨率為 480×270,即寬度為480,高度為270。
  5. -g 240:這部分設置關鍵幀(I幀)之間的間隔為 240 幀,用於控制視頻的GOP結構。
  6. -an:這部分錶示不捕獲音頻。
  7. -f flv:這部分設置輸出格式為FLV格式。
  8. -y:這部分錶示在輸出文件存在時覆蓋已存在的文件。
  9. rtmp://172.16.46.89/live/0101_dealerPC1:這部分是輸出URL,指定了通過RTMP傳輸的目標地址。視頻將會通過RTMP協議傳輸到 rtmp://172.16.46.89/live/0101_dealerPC1 這個地址。

極低延遲播放串流

ffplay -fflags nobuffer -flags low_delay -rtmp_buffer 0 -rtmp_live live -framedrop -infbuf %desc%
  1. -fflags nobuffer: 禁用緩衝。這意味著ffplay將盡可能地減少緩衝,以減少播放的延遲。
  2. -flags low_delay: 啟用低延遲模式。這將優化播放以減少延遲,適用於實時音視頻流。
  3. -rtmp_buffer 0: 設置 RTMP 緩衝大小為 0。 RTMP 是一種流媒體協議,這個選項設置緩衝大小為 0 表示盡可能地減少緩衝,從而減少延遲。
  4. -rtmp_live live: 表示要播放的是實時流。
  5. -framedrop: 如果幀太多,ffplay 將刪除一些幀以避免播放過慢。這有助於保持播放的實時性。
  6. -infbuf: 禁用緩衝輸入。與 -fflags nobuffer 相似,這有助於減少延遲。
  7. %desc%: 這可能是一個佔位符,用於指定音視頻流的 URL 或描述符。

把虛擬鏡頭和某個線上串流做綠幕合成

ffmpeg -f dshow -rtbufsize 1M -i video="OBS Virtual Camera" -f flv -i rtmp://172.17.22.89/live/test1 -filter_complex "[0:v]colorkey=0x00ff00:0.3:0.2[keyed];[1:v][keyed]overlay[o]" -map "[o]" -c:v h264_nvenc -f flv rtmp://127.0.0.1/live/test3
  1. -f dshow: 指定輸入的多媒體設備類型為 DirectShow(Windows 平台上的多媒體框架)。
  2. -rtbufsize 1M: 設置輸入緩衝區大小為 1MB。這可能有助於減少輸入的延遲。
  3. -i video=”OBS Virtual Camera”: 指定輸入的視頻設備名稱為 “OBS Virtual Camera”。這是一個虛擬攝像頭,通常由 OBS(Open Broadcaster Software)等軟件創建,用於虛擬攝像頭設備的捕獲。
  4. -f flv -i rtmp://172.17.22.89/live/test1: 指定輸入的媒體流為 RTMP 流,其 URL 為 rtmp://172.17.22.89/live/test1。這是從另一個 RTMP 流獲取的視頻。
  5. -filter_complex “[0:v]colorkey=0x00ff00:0.3:0.2[keyed];[1:v][keyed]overlay[o]”: 使用濾鏡複雜處理,這裡進行了以下操作:
  6. [0:v]colorkey=0x00ff00:0.3:0.2[keyed]:應用顏色鍵(chroma key)效果來移除綠色(0x00ff00)背景。生成一個帶有透明背景的圖像。
    [1:v][keyed]overlay[o]:將第一個輸入流(來自虛擬攝像頭)與經過顏色鍵處理的圖像進行疊加,產生混合後的圖像。
    -map “[o]”: 從混合後的圖像中選擇 [o] 這個輸出流。
  7. -c:v h264_nvenc: 使用 NVIDIA GPU 的硬件編碼器 h264_nvenc 進行視頻編碼。這將利用 GPU 進行加速,提高編碼效率。
  8. -f flv rtmp://172.17.22.89/live/test3: 指定輸出為 RTMP 流,其 URL 為 rtmp://172.17.22.89/live/test3。這是輸出混合後的視頻流。

更多詳細設置串流的方式

set ffmpegBin=C:\apps\ffmpeg\
set PATH=%PATH%;%ffmpegBin%

set camName="OBS Virtual Camera"
set camBufferSize=1000
set desc=rtmp://127.0.0.1:1935/live/demo

set codec=libx264
set fps=24
set /a "keyint=%fps%*5"
set x264opts=keyint=120:min-keyint=%fps%:scenecut=0
set preset=medium
set profile=baseline
set level=3.1
set resolution=800x450
set bitrate=700

:: publish stream
ffmpeg -f dshow -rtbufsize %camBufferSize%M -i video=%camName% ^
       -vf format=yuv420p ^
       -vcodec %codec% -x264-params %x264opts% ^
       -preset %preset% -profile:v %profile% -level:v %level% ^
       -tune:v zerolatency ^
       -s %resolution% ^
       -r %fps% ^
       -b:v %bitrate%k -minrate %bitrate%k -maxrate %bitrate%k -bufsize %bitrate%k ^
       -an ^
       -f flv %desc%

`-r` 轉成多少 fps

`-y` (global) Overwrite output files without asking.

`-i` 輸入檔案

`-c:v` video codec

`-profile:v` video profile, streaming 用 baseline

`-level:v` video level, streaming 用 3.1

`-preset:v` 編碼速度 streaming 用 ultrafast

`-b:v` 設定 bitrate, 例如 700k 486k

`-s` 尺寸

`-g` GOP size (-4 24 -g 240 相當於 Keyframe frequency = 10s)

`-an` 不需要 audio

`-f flv` flv 格式

`-f dshow -i video=OBS-Camera` window 使用 direct show來抓 camera

`-rtbufsize 200M` 設定 buffer size 避免 drop frame

`-re` 串流轉碼會變慢 因為要求 encoder 根據 native frame rate 讀檔按維持品值,要做串流轉發不要延遲時要拿掉。

https://www.wowza.com/docs/how-to-restream-using-ffmpeg-with-wowza-streaming-engine

FFREPORT 環境變數設好 ffmpeg 就會根據設定存log

linux format for date
https://www.opencli.com/linux/linux-date-format-shell-script

偵測 video frame 資訊

取得 stream 資訊

ffprobe -v quiet -show_streams -select_streams v:0 input.flv

抓出所有 i-frame

ffprobe -show_frames input.flv | grep pict_type | grep -n I

FME 設定 24fps, keyframe frequency = 10s
在理想狀況,會每 240 frame 插入一個 i-frame

example:

1:pict_type=I
241:pict_type=I
481:pict_type=I
721:pict_type=I
961:pict_type=I
1201:pict_type=I
Posted on

限制ffmpeg初始連接的時間

ffmpeg中的analyzeduration和probesize

在FFmpeg中,-analyzeduration和-probesize是用於設置媒體分析的參數。

-analyzeduration參數用於指定分析媒體文件的持續時間。當你在FFmpeg中打開一個媒體文件時,它需要一些時間來分析文件的內容,以確定其格式、編解碼器和其他相關的信息。這個參數設置了分析的時間長度。較長的-analyzeduration值可能會導致更準確的分析結果,但同時也會增加打開文件的時間。預設值為5,000,000微秒(5秒)。

-probesize參數用於指定分析媒體文件時讀取的數據大小。當FFmpeg分析媒體文件時,它會從文件中讀取一些數據並進行分析。這個參數設置了從媒體文件中讀取的數據大小。較大的-probesize值可能會導致更準確的分析結果,但同時也會增加分析的時間和記憶體使用量。預設值為50,000字節。

前置metadata

播放器在網絡點播場景下去請求MP4 視頻數據,需要先獲取到文件的metadata,解析出該文件的編碼、幀率等信息後才能開始邊下邊播。如果MP4 的metadata 數據塊被編碼在文件尾部,這種情況會導致播放器只有下載完整個文件後才能成功解析並播放這個視頻。對於這種視頻,我們最好能夠在服務端將其重新編碼,將metadata 數據塊轉移到靠近文件頭部的位置,保證播放器在線請求時能較快播放。比如FFmpeg 的下列命令就可以支持這個操作:

ffmpeg -i bad.mp4 -movflags faststart good.mp4

控制讀取的數據量大小

在外部可以通過設置 probesize 和 analyzeduration 兩個參數來控制該函數讀取的數據量大小和分析時長為比較小的值來降低 avformat_find_stream_info 的耗時,從而優化播放器首屏秒開。但是,需要注意的是這兩個參數設置過小時,可能會造成預讀數據不足,無法解析出碼流信息,從而導致播放失敗、無音頻或無視頻的情況。所以,在服務端對視頻格式進行標準化轉碼,從而確定視頻格式,進而再去推算 avformat_find_stream_info 分析碼流信息所兼容的最小的 probesize 和analyzeduration,就能在保證播放成功率的情況下最大限度地區優化首屏秒開。

probesize 和 analyzeduration太短的可能影響


如果將-probesize和-analyzeduration設置得太短,可能會導致以下問題:

  • 不準確的媒體分析:probesize和analyzeduration參數用於指定媒體分析的數據大小和時間長度。如果這兩個值設置得太短,FFmpeg可能無法讀取足夠的數據或分析足夠長的時間,從而導致分析結果的不準確性。這可能會影響到媒體文件的正確解碼、格式識別和相關信息的獲取。
  • 遺漏關鍵信息:媒體文件中的關鍵信息通常在文件的早期部分或特定位置。如果probesize和analyzeduration設置得太短,FFmpeg可能無法讀取到這些關鍵信息,進而影響解碼、播放或處理過程的正確性和完整性。
  • 性能問題:probesize和analyzeduration參數的值也會影響處理媒體文件所需的時間和資源。如果值設置得太短,FFmpeg可能需要更頻繁地從媒體文件中讀取數據或進行分析,增加了I/O操作和CPU負載,進而導致性能下降。
Posted on

Chunked Encoding介紹

甚麼是Chunked Encoding

Chunked encoding(分塊編碼)是一種HTTP/1.1協議中的傳輸編碼方式,用於將HTTP消息主體分成多個塊(chunks),以便在網絡上進行有效傳輸。分塊編碼主要用於動態生成的內容,以及在事先不知道內容大小的情況下傳輸數據。

分塊編碼的工作原理如下:

  1. 服務器將HTTP消息主體分成多個大小可變的塊。每個塊由兩部分組成:塊大小(十六進制表示)和實際數據。
  2. 每個塊都以塊大小開頭,然後是一個回車換行符(CRLF),接著是實際數據。在每個塊的數據之後,還有另一個回車換行符(CRLF)。
  3. 數據傳輸完成後,服務器會發送一個大小為0的塊,表示數據已經全部傳輸完畢。接著,服務器可以選擇性地傳輸附加的HTTP頭部,以提供更多關於已傳輸數據的信息。
  4. 客戶端接收到分塊編碼的數據後,將各個塊重新組合成完整的HTTP消息主體。

要使用分塊編碼,服務器需要在HTTP響應頭中設置Transfer-Encoding字段為chunked。這告訴客戶端,接收到的數據將使用分塊編碼格式。

分塊編碼的主要優點是允許服務器在不知道最終內容大小的情況下開始傳輸數據。這對於動態生成的內容、實時數據流和大文件傳輸非常有用。此外,分塊編碼還可以實現數據的即時壓縮和傳輸,從而提高傳輸效率。

設定nginx以支持Chunked Encoding

以下是一個簡單的nginx.conf範例,用於支持在http://127.0.0.1/live下的文件開啟chunked encoding。此配置檔案會將請求代理到後端應用伺服器(例如:Node.js、Python或其他後端應用)進行處理。請注意,這裡假設後端應用伺服器已經正確配置並支持分塊編碼。

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    gzip  on;
    gzip_min_length 1024;
    gzip_proxied any;
    gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml application/xml+rss;

    server {
        listen       80;
        server_name  127.0.0.1;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }

        location /live {
            proxy_pass http://backend:3000; # 請將 "backend" 替換為您的後端應用伺服器地址(IP 或 域名),並將 "3000" 替換為您的後端應用伺服器的端口

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

            proxy_http_version 1.1;
            proxy_set_header Connection "";
            chunked_transfer_encoding on;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}
events {
    worker_connections  1024;
}

這個配置檔案將Nginx設置為代理位於http://127.0.0.1/live的請求,並將請求轉發到後端應用伺服器。在location /live部分,使用chunked_transfer_encoding on;指令開啟分塊編碼。

觀察你的檔案是否有啟用Chunked Encoding

我們可以從伺服器的回應看到這個伺服器的檔案傳輸是否有支持Chunked Encoding,如下圖

Posted on

CMAF – 媒體封裝格式介紹

CMAF介紹(Common Media Application Format)

CMAF(Common Media Application Format,通用媒體應用格式)是一種專為網絡媒體傳輸設計的標準。CMAF旨在簡化不同裝置和網絡環境之間的媒體流適配和交付,從而提高流媒體的性能和覆蓋範圍。CMAF是一種媒體封裝格式。CMAF被設計為簡化在不同裝置和網絡環境之間的媒體流適配和交付,從而提高流媒體的性能和覆蓋範圍。CMAF檔案通常具有.cmf.mp4擴展名。

CMAF(Common Media Application Format,通用媒體應用格式)是一種媒體封裝格式,類似於FLV(Flash Video)和MP4(MPEG-4 Part 14)。CMAF旨在簡化在不同裝置和網絡環境之間的媒體流適配和交付,以提高流媒體的性能和覆蓋範圍。

與FLV和MP4等其他封裝格式相比,CMAF的一個主要優勢在於它的兼容性和靈活性。CMAF可以應對各種不同的網絡環境和裝置能力,並且可以與多種流媒體協議(如HLS和MPEG-DASH)無縫地配合使用。

CMAF的特點

CMAF的主要特點包括:

  1. 單一檔案格式:CMAF允許使用單一檔案格式來適配多種媒體流協議,例如HLS(HTTP Live Streaming)和MPEG-DASH(Dynamic Adaptive Streaming over HTTP)。這使得內容提供商能夠更容易地在各種裝置和網絡上傳輸和管理媒體內容。
  2. 切片:CMAF將媒體流切成較小的片段(通常稱為chunks),這些片段可以在不同品質層次之間進行無縫切換,以適應不同的網絡條件和裝置能力。這有助於實現更低的延遲和更高的播放質量。
  3. 編碼效率:CMAF支持各種編解碼器,例如H.264(AVC)和H.265(HEVC),以實現高效的媒體編碼。此外,CMAF還支持多種音頻編解碼器,例如AAC和Opus。
  4. 整合DRM(數字版權管理):CMAF允許整合各種DRM技術,如Widevine、PlayReady和FairPlay,以保護內容的版權。

總之,CMAF是一種簡化網絡媒體傳輸的標準,它有助於提高流媒體的性能、覆蓋範圍和兼容性。

CMAF的延遲

CMAF(Common Media Application Format,通用媒體應用格式)主要用於適配和交付HLS(HTTP Live Streaming)和MPEG-DASH(Dynamic Adaptive Streaming over HTTP)等流媒體協議。CMAF的目標是在不同裝置和網絡環境之間提供高效的媒體流適配和交付,而非專注於低延遲。

由於CMAF依賴於HTTP,其延遲通常會比使用基於UDP的協議(如SRT或RTP)高。HTTP協議需要較長的時間來建立連接、請求和接收數據,這導致了較大的延遲。此外,CMAF通常用於分段媒體流,每個分段的持續時間也會增加延遲。

然而,CMAF的延遲性能可以通過使用CMAF的低延遲模式(CMAF-LLC)來改善。CMAF-LLC使用chunked encoding傳輸技術來實現低延遲,這允許客戶端在接收到完整的媒體分段之前開始解碼和播放。這樣可以將延遲降低到可接受的範圍,但仍然可能高於使用基於UDP的協議,如SRT。

總之,儘管使用CMAF的延遲可能較長,但通過使用CMAF-LLC可以改善延遲性能。然而,對於實時應用或低延遲要求非常嚴格的場景,使用基於UDP的協議,如SRT或RTP,可能是更合適的選擇。

Posted on

Publish HEVC live streaming by OBS to SRS via RTMP

After OBS Studio 29.1, they added support for Enhanced RTMP, it is now possible to push HEVC streaming via RTMP, and SRS also support HEVC over RTMP and HTTP-FLV v6.0.2+.

Here is a simple tutorial on how to use OBS to push HEVC streams to SRS.

OBS support H.265 over RTMP v29.1+

The original RTMP protocol cannot support high-compression video formats such as HEVC or AV1. But from OBS Studio 29.1 Beta, OBS adds support for the updated: Enhanced RTMP. For more detail, please refer to: Enable AV1, HEVC via RTMP to YouTube.

Therefore, the first step to push an HEVC stream via RTMP from OBS is to download the latest version of OBS. (Download here: OBS Studio 29.1 Beta Release Page).

SRS support H.265 over RTMP v6.0.42+

  • RTMP: Support enhanced RTMP specification for HEVC, v6.0.42.
  • Player: Upgrade mpegts.js to support it.

Enhanced RTMP specification: https://github.com/veovera/enhanced-rtmp

First, start SRS v6.0.42+ with HTTP-TS support:

./objs/srs -c conf/http.ts.live.conf

Pulish HEVC via RTMP from OBS

  1. Your OBS version should be greater than v29.1, than open File -> Setting
  2. Select Stream -> Service to Custom…
  3. Select Output -> Output Mode to Advanced, than choice Encoder to HEVC
  4. Click Start Streaming
  5. Check your streaming from SRS console
  6. Preview your streaming by SRS Player
Posted on

什麼是WebRTC

文章轉載

這篇文章翻譯自: What is WebRTC and how does it work? Real-time communication with WebRTC

什麼是WebRTC

WebRTC代表網路實時通訊。 它是一種非常令人興奮、強大且具有高度破壞性的尖端技術和流媒體協議。

WebRTC與HTML5相容,您可以使用它直接在瀏覽器和裝置之間新增實時媒體通訊。 最好的部分之一是,您無需在瀏覽器中安裝外掛的任何先決條件即可做到這一點。 Webrtc正逐漸得到所有主要現代瀏覽器供應商的支援,包括Safari、Google Chrome、Firefox、Opera等。

多虧了WebRTC影片流技術,您可以將實時影片直接嵌入到基於瀏覽器的解決方案中,為您的觀眾創造引人入勝的互動式流媒體體驗,而不必擔心延遲。

現在,影片,特別是直播,是我們快速變化的通訊需求不可或缺的一部分。 隨著社交距離的增加,WebRTC幫助我們滿足這些通訊需求,並增加我們與實時通訊的互動。

WebRTC元件

我們將使用客戶端-A和客戶端-B作為示例來解釋WebRTC的以下元件。

SDP(會話描述協議)

SDP是一個簡單的基於字串的協議,它在瀏覽器之間共享支援的程式碼器。

在我們的例子中,

  • 客戶端 A 創建其 SDP(稱為報價)並將其保存為本地 SDP,然後與客戶端 B 共享。
  • Client-B收到Client-A的SDP,保存為遠程SDP。
  • 客戶端 B 創建其 SDP(稱為答案)並將其保存為本地 SDP,然後與客戶端 A 共享。
  • Client-A收到Client-B的SDP,保存為遠程SDP。

信令伺服器(Signaling Server)負責等體之間的這些SDP傳輸。

讓我們假設客戶端A可能支援H264、VP8和VP9編解碼器用於影片、Opus和PCM編解碼器用於音訊。 客戶端-B可能只支援H264用於影片,只支援Opus編碼器用於音訊。

在這種情況下,客戶端-A和客戶端-B將使用H264和Opus作為編解碼器。 如果對等體之間沒有共同的程式碼器,則無法建立對等通訊。

ICE(交互連接建立)

Interactive Connectivity Establishment (ICE) 用於 Internet 上的兩個節點必須盡可能直接通信的問題,但是 NAT 和防火牆的存在使得節點之間難以相互通信。

它是一種網絡技術,利用 STUN(NAT 會話遍歷實用程序)和 TURN(在 NAT 周圍使用中繼遍歷)在兩個節點之間建立盡可能直接的連接。

WebRTC STUN 服務器NAT 的會話遍歷實用程序) 

STUN Server負責獲取一台機器的所有地址。例如,我們的計算機通常在 192.168.0.0 網絡中有一個本地地址,當我們連接到www.whatismyip.com時,我們會看到第二個地址,這個 IP 地址實際上是我們互聯網網關(調製解調器,調製解調器,路由器等),所以讓我們定義 STUN 服務器:STUN 服務器讓對等方知道他們的公共和本地 IP 地址。

順便說一下,Google 還提供了一個免費的 STUN 服務器 (stun.l.google.com:19302)。

 

WebRTC TURN  Server  (繞過NAT使用中繼遍歷)

TURN(Traversal Using Relays around NAT)是一種協議,可幫助 WebRTC 應用程序穿越網絡地址轉換器 (NAT) 或防火牆。TURN Server 允許客戶端通過中間服務器發送和接收數據。

TURN 協議是 STUN 的擴展。 有時,由於 NAT/Firewall,從STUN服務器 獲取的地址不能用於建立對等點之間的對等連接。在這種情況下,數據通過TURN服務器中繼

在我們的例子中,

  • Client-A通過STUN服務器找到自己的本地地址和公網地址,並通過Signaling Server將這些地址發送給Client-B。從 STUN 服務器收到的每個地址都是 ICE 候選地址。
  • Client-B 做同樣的事情,從 STUN 服務器獲取本地和公共 IP 地址,並將這些地址通過 Signaling Server 發送給 Client-A。
  • Client-A 收到 Client-B 的地址並通過發送特殊的 ping 來嘗試每個 IP 地址以創建與 Client-B 的連接。如果客戶端 A 收到來自任何 IP 地址的響應,它會將該地址及其響應時間和其他性能憑證放入列表中。最後,Client-A 根據其性能選擇最佳地址。
  • Client-B 做同樣的事情以連接到 Client-A

RTP(實時協議)

RTP 是在UDP之上傳輸實時數據的成熟協議。在 WebRTC 中,音頻和視頻通過 RTP 傳輸。RTP 有一個姊妹協議,名為 RTCP(實時控制協議),它在 RTP 通信中提供 QoS。RTSP  (實時流協議)在數據通信中也使用 RTP 協議。

WebRTC 信令服務器

最後一部分是Signaling Server,WebRTC 中沒有定義。如上所述,Signaling Server 用於在 Client-A 和 Client-B 之間發送 SDP 字符串和 ICE Candidates。信令服務器還決定哪些對等點相互連接。WebSocket 技術是與信令服務器進行通信的首選方式。

Posted on

使用OBS來推流H265

使用OBS來推流H265

OBS也在v29板之後支持了HEVC推流,支持利用RTMP的封裝方式來推送H265編碼的串流格式,若電腦沒有可支持硬編碼的GPU,其CPU編碼所採取的編碼方案是QuickSync HEVC。

若是電腦有可支持硬編碼的GPU,則下拉選單會增加該硬件編碼的編碼選項

並且可以錄製SVT-AV1、AOM-AV1和HEVC的格式的影片

Posted on

高壓縮比編碼格式的介紹 – AV1

高壓縮比編碼格式AV1介紹

AV1是一種免費、開源的視頻編解碼器,由Alliance for Open Media(AOMedia)聯盟開發。它是H.265(HEVC)的競爭對手,旨在提供更高的壓縮效率和更好的視頻質量。
AV1使用了許多新技術來提高壓縮效率,例如可變帶寬預測、可變塊大小和可變熵編碼等。與H.265相比,AV1在相同的比特率下可以提供更高的視頻質量。同時,AV1還具有更好的自適應流媒體性能,可以更好地適應網絡帶寬的變化。
AV1可以支持多種分辨率和色彩空間,包括8位、10位和12位色彩深度。此外,它還可以支持HDR(高動態範圍)和WCG(廣色域)等高級視頻格式,以提供更真實的圖像質量。
由於AV1是一種開放標準,並且沒有專利費用,因此它被廣泛用於在線視頻流媒體服務和其他應用,例如YouTube、Netflix、Amazon Prime Video等。同時,AV1還適用於各種類型的視頻內容,包括電影、電視節目、動畫和遊戲。

常見的編碼器

SVT-AV1和AOM-AV1

SVT-AV1和AOM-AV1都是AV1編碼器,不過它們有幾個不同之處:

  • 開發者:SVT-AV1是由英特爾開發的,而AOM-AV1是由Alliance for Open Media(AOM)開發的。
  • 編碼質量:SVT-AV1相對於AOM-AV1來說,可以提供更高的編碼質量,尤其是在高比特率下。
  • 編碼速度:AOM-AV1的編碼速度相對於SVT-AV1來說更快,這對於需要實時編碼的場景非常重要。
  • 適用範圍:SVT-AV1更適用於需要高質量視頻編碼的場景,如影片後期製作等;而AOM-AV1更適用於實時編碼的場景,如視頻通話、視頻會議等。

甚麼是AV1 SVC

AV1 SVC中的SVC是指可伸縮視頻編碼(Scalable Video Coding)。可伸縮視頻編碼是一種視頻編碼技術,可以將視頻數據分成多個層級,每個層級可以根據不同的要求進行編碼和解碼。這種編碼技術可以在不同的設備和網絡帶寬上提供不同的視頻質量和分辨率。在AV1 SVC中,視頻數據被分成多個空間和時間層級。空間層級是根據空間分辨率進行編碼的,例如低分辨率圖像和高分辨率圖像。時間層級是根據時間分辨率進行編碼的,例如低幀率和高幀率圖像。這些層級可以按需選擇和合併,以提供適合設備和網絡帶寬的最佳視頻質量。+

AV1 SVC可以提供更高的編碼效率和更好的視頻質量,同時可以適應不同的設備和網絡環境。這使得它非常適合用於實時視頻流傳輸、視頻會議和移動通信等應用場景。AV1是第一個支持SVC的編解碼器。對於那些對關於SVC是如何發揮作用的更多細節感興趣的人,Alex E.博士在2016年寫了一篇很好的解釋性博文。寫的是關於VP9,大多數點對AV1有效的內容。

SVT-AV1和AOM-AV1都支持可伸縮視頻編碼(SVC),但是它們支持的SVC規格略有不同。具體而言:

  • SVT-AV1支持SVC的規格是MPEG-5 Part 2 LCEVC(Low Complexity Enhancement Video Coding),這是一種用於增強現有編碼器的規格,可以提高編碼效率和視頻質量。
  • AOM-AV1支持的SVC規格是AV1 Scalable Video Technology(SVT),這是一種基於AV1的可伸縮視頻編碼技術,可以實現在不同的網絡帶寬和終端設備之間動態調整視頻質量和分辨率。

非常適合用於會議場合

AV1旨在與下一波WebRTC視頻創新集成:端到端加密,SVC和獨立於編解碼器的轉發。因此,這與視頻編解碼器無關,而與下一代架構有關。

1. 隨著WebRTC現在通過可插入流(和SFrame)合併了E2E加密,並且NSA現在推薦E2E安全性,由於有效負載可能是不透明的,因此會議系統需要RTP標頭擴展來轉發數據包。因此,如果瀏覽器和編解碼器不支持可插入流或與下一代編解碼器集成的轉發頭擴展名,則將無法滿足NSA的要求,並且會議供應商將無法提供完整的功能。

2. SVC支持對於會議很重要。AV1內置了SVC;在HEVC中,它是一個擴展。Dependency Descriptor(在AV1 RTP有效負載規範中定義)優於用於空間可伸縮性模式的Framemarking RTP標頭擴展。如果瀏覽器(和下一代編解碼器)不支持帶有轉發頭擴展名的SVC,那麼它就沒有競爭力。

3. AV1包含屏幕編碼工具作為基本功能,而不是像HEVC中的擴展。這是會議的主要競爭優勢。”

屏幕共享

對於文本內容以及超高動態內容,在對屏幕內容進行編碼時,AV1都非常高效。實際上,AV1實時的性能非常優越,以至於像Cisco在Webex中所做的那樣,AV1實時可能只部署在單個使用案例中。

在共享屏幕或應用程序時,如果選擇了“優化運動和視頻”,並且您所在的機器至少有四個內核,則支持傳輸AV1。任何至少有兩個內核的機器都支持接收AV1。只要會議的所有參與者都支持AV1,AV1就會自動用於共享此類屏幕內容,否則它將自動恢復為H.264。

有趣的是,這里分別提到了4和2個內核的約束條件。思科在2019年6月的大蘋果大會上進行現場演示時也發表了同樣的觀點。

我們將在下一個部分中繼續討論性能的問題,但是為了提供相關的背景信息,MacBook Air自2008年以來一直使用具有2個內核的Intel core-2芯片,並且自2011年以來在MacBook Pro中具有4個或更多內核的Intel i7或更高版本。就筆記本電腦和台式機而言,預計擁有4個內核並不是一個大問題。

端到端加密

E2EE是下一件值得關注的問題。也許是因為這是webrtc最初許下的承諾之一。又或許是因為它成為了一個過度使用的營銷術語,而Zoom已經變得遍體鱗傷。也許是因為大多數人仍然聲稱擁有它,實際上卻沒有。

關於E2EE,對這個問題最好的回應之一是Emil Ivov的這篇演講。

雖然許多人認為E2EE加密只是一種視頻會議或聊天應用程序功能,但它在整個媒體行業中都以縮寫“DRM”(數字版權管理)的形式使用。然而,傳統的DRM在瀏覽器和媒體播放器中的實現並不是真正的端到端的,只涵蓋了交付這一模塊。當人們上傳他們的內容到一個平台時仍然需要信任這個平台(以及任何可以合法訪問或不合法訪問該平台的人)與他們的原始內容。

真正的E2EE要求在對媒體進行編碼時在源處對媒體進行加密,並且僅在播放時對其進行解密。它允許內容提供商不信任該平台。

WebRTC可通過插入流API方案來得到了廣泛的應用,因為它可以用於很多方面。它是使您能夠訪問媒體的API,也是啟用E2EE的必要步驟。但是,它本身沒有加密功能或加密密鑰管理功能。

推流端支持AV1的相關資料

SRS在4.0.91開始支持經過WebRTC去推流AV1
RTC: Support av1 for Chrome M90 enabled it. 4.0.91
事實上,這已經是瀏覽器內建就可以做到的了。針對WEBRTC而言,Chrome已經在90版之後支持AV1編碼
Google Chrome 90 正式版發佈,支援 AV1 解碼

另外騰訊雲則可支持使用AV1格式推流
實現直播AV1 編碼

解碼端支持AV1的相關資料

騰訊雲有自己開發出可支援AV1透過FLV格式來解碼
播放AV1格式視頻

播放AV1視頻

通過支持AV1的播放器,按播放步驟3中生成的地址進行播放即可。在播放器的選擇上,可以選擇已支持AV1的播放器,也可以對自有播放器進行改造。

已支持AV1的播放器

App 客戶端

1. ExoPlayer已支持AV1,用的libgav1
2. ijkplayer FFmpeg 版本陳舊,可以升級FFmpeg 並集成dav1d

Web 端

1. dash.js已經支持(解碼取決於瀏覽器,Chrome 支持)
2. shaka-player已經支持(解碼取決於瀏覽器,Chrome 支持)

PC 端

VLC PC 版,支持AV1 in FLV、HEVC in FLV, 可按需下載Windowos 版& MacOS 版

Posted on 1 Comment

OBS在版本29版之後增加的新的編碼支持(H265及AV1)

OBS支持HEVC推流

OBS在v29版本之後支持了HEVC推流,支持利用RTMP的封裝方式來推送H265編碼的串流格式,若電腦沒有可支持硬編碼的GPU,其CPU編碼所採取的編碼方案是QuickSync HEVC。

若是電腦有可支持硬編碼的GPU,則下拉選單會增加該硬件編碼的編碼選項

支持AV1及HEVC的錄影格式

並且可以錄製SVT-AV1、AOM-AV1和HEVC的格式的影片

Posted on

為SRS6編譯支持HTTP-FLV的FFMPEG檔案

SRS介紹

SRS是一個簡單高效的實時視頻服務器,支持RTMP/WebRTC/HLS/HTTP-FLV/SRT/GB28181。
是一個運營級的互聯網直播服務器集群並發7.5k+,支持多種轉碼,RTMP->HLS,RTMP->FLV等,支持HTTP回調,RTMP0.1s延時
在HTTP-FLV的低延遲實踐方案上,可以說是繼FMS之後,非常有用心地在更新、維護的一個開源專案

主要開發者很熱心地回答問題,相關的文件也隨著時間越來越完整,使用的人數也越來越多,是一個高效能且穩定的開源串流服務器。

SRS6.0已支持H.265編碼格式

在SRS 6.0之中,很開心我們終於看到SRS支持H265了,這其中很重要的一個工作就是我們需要在推流端能夠讓RTMP的FLV格式推流能夠支持H265。
但是,若我們使用從FFMPEG官網下載的.EXE檔案,即便我們使用ffmpeg -version顯示支持H265,在實際推H265的流時仍然會發生錯誤。

錯誤訊息如下圖

這個錯誤代表說,官方所提供的版本雖然支持H.265,但是卻不支持使用FLV來封裝H.265的編碼格式。

為FFmpeg增加支持HEVC over RTMP的補丁

對於SRS6.0支持HEVC over RTMP的詳細說明於此: https://github.com/ossrs/srs/issues/465

支持 HEVC over RTMP 或 FLV 的規範和用法。runner365為FFmpeg提供了FFmpeg 4.1/5.1/6.0 的補丁,以支持通過 RTMP 或 FLV 的 HEVC。Intel也有針對此功能的補丁。

這裡面提到說,SRS 6之所以能夠支持H265 over RTMP是因為使用了runner365自己為ffmpeg所增加的補丁功能。官方的版本並不支持HEVC over RTMP,若我們希望使用RTMP來推流H265,則需要重新編譯包含這份補丁的FFMPEG執行檔案。

另外要注意的是,雖然,但是應該是它們採用HEVC支持RTMP的實作方式與SRS6.0使用的FFMPEG方案並不一致,若是使用OBS的v29.0.2推H265的流到SRS伺服器,伺服器並沒有辦法正確的解析串流內容,因此,在推流時,一定要使編譯過的(runner365的補丁版本)、可支援HEVC over RTMP的FFMPEG來推流,才可以正確把H265的流推送到SRS。

這邊是官方如何編譯ffmpeg的教學:
https://github.com/ossrs/srs/issues/465#ffmpeg-tools

使用ffmpeg推流HEVC格式的影片,其重點在於將vcodec指定為libx265

ffmpeg -i sample.mp4 -c:v libx265 -b:v 350k -f flv rtmp://127.0.0.1/live/livestream

以下指令可推送極低延遲的H.265影片

ffmpeg -i sample.mp4 -c:v libx265 -crf 28 -x265-params profile=fast -preset veryfast -tune zerolatency -b:v 300k -minrate 300k -maxrate 300k -f flv rtmp://127.0.0.1/live/livestream

如何在linux裡面編譯支持H265 over rtmp的ffmpeg

支持 HEVC over RTMP 或 FLV 的規範和用法。 runner365 為 FFmpeg 提供了 FFmpeg 4.1/5.1/6.0 的補丁,以支持通過 RTMP 或 FLV 的 HEVC。

在編譯ffmpeg之前,要先編譯libx264

cd ~/git
git clone https://code.videolan.org/videolan/x264.git
cd ~/git/x264
./configure --prefix=$(pwd)/build --disable-asm --disable-cli --disable-shared --enable-static
make -j10
make install


以及libx265

cd ~/git
git clone https://bitbucket.org/multicoreware/x265_git.git
cd ~/git/x265_git/build/linux
cmake -DCMAKE_INSTALL_PREFIX=$(pwd)/build -DENABLE_SHARED=OFF ../../source
make -j10
make install


接著載入HEVC over RTMP/FLV的補丁:

cd ~/git
git clone -b 5.1 https://github.com/runner365/ffmpeg_rtmp_h265.git
cp ~/git/ffmpeg_rtmp_h265/flv.h ~/git/FFmpeg/libavformat/
cp ~/git/ffmpeg_rtmp_h265/flv*.c ~/git/FFmpeg/libavformat


然後編譯ffmpeg

cd ~/git/FFmpeg
env PKG_CONFIG_PATH=~/git/x264/build/lib/pkgconfig:~/git/x265_git/build/linux/build/lib/pkgconfig \
./configure \
  --prefix=$(pwd)/build \
  --enable-gpl --enable-nonfree --enable-pthreads --extra-libs=-lpthread \
  --disable-asm --disable-x86asm --disable-inline-asm \
  --enable-decoder=aac --enable-decoder=aac_fixed --enable-decoder=aac_latm --enable-encoder=aac \
  --enable-libx264 --enable-libx265 \
  --pkg-config-flags='--static'
make -j10


嘗試推流

./ffmpeg -stream_loop -1 -re -i ~/srs/doc/source.flv -acodec copy -vcodec libx265 \
  -f flv rtmp://localhost/live/livestream