RTMP低延遲推流

人總是需要壓力才能進步, 最近有個項目, 需要我在RK3568上, 推流到公網, 最大程度的降低延遲.
廢話不多說, 先直接看效果:
在這里插入圖片描述
數據經過WiFi發送到Inenter的SRS服務器, 再通過網頁拉流的.

因為是打金任務, 所以逼了自己一把, 把RTMP推流好好捋一遍.
先說說任務目標, 首先是MPP編碼, 把mpp的github庫下載下來, 研究mpi_enc_test這個例程, 基本就能實現, 從攝像頭/dev/video0獲取yuv數據, 編碼為h264, 保存為文件.

最終值得注意是兩點:

  1. log看不到, mpp的log都保存到了/var/log/messages中.

在這里插入圖片描述

  1. 輸入參數, 因為人家的test demo, 包裝得非常好, 編碼的參數需要用參數輸入, 而你必須設置一些編碼參數, 我想到一個非常偷懶的做法:

在這里插入圖片描述
偽裝, 哈哈
這里面幾個比較重要的參數,
-w -h分辨率之類,
-n 表示連續獲取數據幀, 不顯示數量
-t 就是h264比那嗎
-g 是關鍵幀間隔
-rc 是碼流控制, 1代表固定碼流, 可根據需要修改, 在固定碼流模式下, 可以設置碼率

下圖的bps就是碼率, 直接寫死, 要提高碼率, 可以修改這里
在這里插入圖片描述
3. 在整個編碼一開始, 會有一個生成SPS/PPS幀的過程, 原本的代碼是直接寫入到h264裸文件中. 我看了下面雷神的做法, 先緩存了下來, 跟第一個I幀一起發送.

接下來就是RTMP推流國過程了.

整個過程的前提是, 我之前在騰訊, 花5分鐘(開通)+30分鐘(折騰防火墻發現是梯子的問題), 搞了個SRS的服務器, 這個服務能接收N種推流方式:
在這里插入圖片描述
這里面我最熟悉的就是RTMP了.
其實我最迷信的就是直接TCP轉發…但是播放端沒有研究, 而我之前試過, 先在板子這端用RTSP, 然后用ZLMedia的pusher, 或者叫Muxer, 把RTSP轉到RTMP上去:

https://blog.csdn.net/zunly/article/details/138510170?spm=1001.2014.3001.5502

我偶然發現, 通過網頁看到的流, 延遲非常小, 說明這個路應該是ok的, 但是經過RTSP, 再轉推, 實在太2, 于是乎經過了幾天的折騰, 下面是一點發現:

先說說目前的目標, 就是把mpp編碼完的h264數據幀, 一幀一幀的通過RTMP推到Internet上的SRS上去.

首先我能想到的, 就是這么普及的應用, 應該是有庫的吧, 搜了一圈, 發現有幾個選擇:
傳說的librtmp, 如果直接在github搜索, librtmp, 過濾掉iOS, 安卓平臺, 就會看到雷神(致敬RIP)之前的倉庫:

https://github.com/leixiaohua1020/simplest_librtmp_example.git

他的做法是使用一個叫librtmp的庫, 但是這個庫沒有源碼, 只有編譯好的lib文件跟dll文件, 這沒法移植啊…

github上, SRS librtmp的倉庫, 留了一個留言:

在這里插入圖片描述
兩個連接都已經失效.

我又研究了ZLMedia的RTMP部分, 發現一時之間很難看懂…

接下來是ffmpeg, ffmpeg最早進入視野是因為我一開始就想研究webRTC的推流, 據說那玩意兒賊快, 于是看到了一個國內的現狀, 很多開發者, 開發出一個框架, 像變現, 方法成了, 什么知識星球, 什么CSDN收費下載…唉…當然作為一個自由主義知識分子, 信仰的是Milton Friedman, Ronald H. Coase, 我舉雙手贊同知識付費…
最后因為沒有錢, 我放棄了WHIP就是webRTC推流的方法…默默留下了貧窮的眼淚.

偶然的機會, 我發現了另一個雷神的倉庫:
https://github.com/leixiaohua1020/simplest_ffmpeg_streamer

差點跟前面那個搞混了, 這個倉庫就是一個既可以推mp4也可以推flv, 也可以推裸流的寶藏代碼, 也是雷神在8年前遺珠…
這個方案用的是ffmpeg的庫, ffmpeg老早就集成了這些了…ffmpeg牛逼!!!
我先是在Unbantu上面, 把代碼在x86/x64環境跑起來(居然真的能跑通, 推流也是能看到畫面的).
然后通過WireShark抓包, 看看到底除了了裸流的數據, ffmpeg 還發了些啥:

在wireshark中, 我發現了幾個問題, 一個是對應代碼的, RTMP的初始化連接過程, 是非常必要的, 這個過程相當于告訴RTMP的服務器, 你要推流的視頻的一些信息, 例如寬高, 幀率之類.
在這里插入圖片描述
而這些信息, 其實是ffmpeg通過讀取你要發送的h264/flv文件來獲取的, 就是這個write_head的過程
在這里插入圖片描述

實際的每一個數據幀的發送, 根據打印結果發現, 如下圖, 如果我推流的是一個h264的文件, 每次發送的packet, 其實就是通過ffmpeg的 av_read_frame方法, 跟NAL的分割字符(00 00 00 01或者00 00 01), 讀取的一幀數據

在這里插入圖片描述
read之后, 打印pkt, 長度跟數據內容, 用winhex打開比較

在這里插入圖片描述
發現, 每個包, 就是一幀
在這里插入圖片描述
那么思路就這樣串起來了.

首先, 通過編碼, 把攝像頭數據, 保存為一個h264的文件, 這個文件當中, 最少有1個SPS, PPS, 跟一個關鍵幀, 作為一個初始化ffmepg AVPacket對象的工具, 同時也供RTMP的連接初始化使用, 接下來, 再使用實時編碼出來的h264幀, 不斷填充AVPacket對象的data 跟len這兩個參數, 再通過ffmpeg的av_interleaved_write_frame 方法, 就可以把數據源源不斷的推到RTMP上去了.

代碼暫時不開源, 因為是個打金的項目, 如果上面的文章您還有任何疑問, 歡迎發私信討論, 感謝大家.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/13276.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/13276.shtml
英文地址,請注明出處:http://en.pswp.cn/web/13276.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Altium】AD-檢查原理圖中元器件未連接的Passive Pin

1、 文檔目標 如何讓原理圖編譯時找出元器件上未連接的Passive Pin 2、 問題場景 當引腳屬性(Pin type)為passive時,原理圖編譯的默認規則是不會去檢查它們是否有連接的。在實際設計過程中,經常會有導線虛連,漏連的事…

醫療傳感器種類不斷增多 市場規模逐漸擴大

醫療傳感器種類不斷增多 市場規模逐漸擴大 醫療傳感器是將人體的生理信息轉換為電信息的變換裝置。醫療傳感器具有高靈敏度、高精度、實時監測等優點,可以檢測佩戴者的心率、呼吸頻率、活動量等,從而更加準確地了解身體情況。   經過多年發展&#…

【極簡】docker常用操作

鏡像images是靜態的 容器container是動態的,是基于鏡像的,類似于一個進程。 查看docker images: docker images 或者docker image ls 查看docker container情況:docker ps -a,-a意思是--all 運行一個container: doc…

MySQL not in不等于找不到null的數據

在使用MySQL的NOT IN語句時,如果找不到NULL值,可能是因為NULL值在比較中具有特殊性質。NULL值不等于任何其他值,包括它自己。因此,使用NOT IN語句時,如果列表中包含NULL值,則查詢不會返回任何結果。 解決此…

有意思的數組

var nums [1,2,3,6] const nums1 [6, 8, 7, 10, 9];/* 數組合并————push */ var n nums.push(...nums1); // 將列表 nums1 拼接到 nums 之后 n //n會是nums的長度 > 9 nums //也push了 > (9) [1, 2, 3, 6, 6, 8, 7, 10, 9]/* 數組合并————concat*/ var arr0…

數字水印 | 奇異值分解 SVD 的 Python 代碼實現

🥑原理:數字水印 | 奇異值分解 SVD 的定義、原理及性質 🥑參考:Python 機器學習筆記:奇異值分解(SVD)算法 正文 對于一個圖像矩陣,我們總可以將其分解為以下形式: 通過…

使用API有效率地管理Dynadot域名,默認將域名隱形轉發至其他界面

關于Dynadot Dynadot是通過ICANN認證的域名注冊商,自2002年成立以來,服務于全球108個國家和地區的客戶,為數以萬計的客戶提供簡潔,優惠,安全的域名注冊以及管理服務。 Dynadot平臺操作教程索引(包括域名郵…

英譯漢早操練-(十九)

hello,are you OK? 生活如此美好,周四了,你還好嗎?堅持了快一周了,是不是最后沖刺一把就開啟周末的美好生活了。 今天我們學習這篇經濟學人文章: 題目是:Banks, at least, are making money from a turbul…

【大模型微調】一文掌握7種大模型微調的方法

本篇文章深入分析了大型模型微調的基本理念和多樣化技術,細致介紹了LoRA、適配器調整(Adapter Tuning)、前綴調整(Prefix Tuning)等多個微調方法。詳細討論了每一種策略的基本原則、主要優點以及適宜應用場景,使得讀者可以依據特定的應用要求和計算資源限…

Linux | VMware安裝鏡像指南(Windows、IOS、麒麟)

文章目錄 虛擬機安裝推薦 虛擬機安裝推薦 macOS系統:macOS虛擬機安裝全過程(VMware)麒麟系統:麒麟系統虛擬機安裝(VMware)VMtools工具解決方案: [第一步](https://blog.csdn.net/weixin_421187…

openGauss一主兩備集群異常斷電后不能正常啟動的解決過程簡記

背景 因異常斷電后opengauss 5.0.0版本,一主兩備集群啟動失敗。 報錯不是主機,由于當時沒有截圖,查看日志后發現報錯是: 定位過程 Day1 1. 嘗試用另外兩臺機器啟動每臺機器 發現都報錯自己不是主機,像極了唐僧被妖…

【算法刷題day55】Leetcode:583. 兩個字符串的刪除操作、72. 編輯距離

文章目錄 Leetcode 583. 兩個字符串的刪除操作解題思路代碼總結 Leetcode 72. 編輯距離解題思路代碼總結 草稿圖網站 java的Deque Leetcode 583. 兩個字符串的刪除操作 題目:583. 兩個字符串的刪除操作 解析:代碼隨想錄解析 解題思路 dp數組的含義是&a…

哪款桌面便簽app能幫助我提升工作效率

作為上班族,我們每天都要處理大量的工作事項,從策劃方案到處理郵件,每一個環節都需高效且有條不紊。在這樣的工作環境下,提升效率顯得尤為重要。而選擇一款優秀的桌面便簽app,無疑是提高工作效率的關鍵。 桌面便簽app…

【數據結構】數據結構大匯總 {數據結構的分類總結:定義和特性、實現方式、操作與復雜度、適用場景、相關算法、應用實例}

一、線性結構 1.1 順序表 定義和特性:順序表是一種線性表的存儲結構,它采用一段地址連續的存儲單元依次存儲線性表中的元素。順序表具有隨機訪問的特性,即可以通過元素的下標直接訪問元素。 實現方式:順序表可以通過數組來實現&…

基于51單片機的非接觸式無線紅外測溫

基于51單片機的無線紅外測溫 (程序+原理圖+設計報告) 功能介紹 具體功能: 1.采用紅外溫度傳感器測溫并用LCD1602顯示; 2.按鍵為啟動按鍵、保存按鍵、顯示數據按鍵,可以實現對溫度數值的控制…

【制作100個unity游戲之26】unity2d橫版卷軸動作類游戲6(附帶項目源碼)

最終效果 系列導航 文章目錄 最終效果系列導航前言敵人動畫配置撞墻判斷敵人基本AI邏輯實現 野豬受傷死亡死亡敵人死亡時,還是會對人物產生傷害有限狀態機&抽象類多態 定義不同狀態的敵人行為防止野豬在懸崖掉下去野豬的追擊狀態的轉換敵人主動查找玩家 追擊狀態…

基于微信小程序+JAVA Springboot 實現的【智慧鄉村旅游服務平臺】app+后臺管理系統 (內附設計LW + PPT+ 源碼+ 演示視頻 下載)

項目名稱 項目名稱: 基于微信小程序的智慧鄉村旅游服務平臺的設計與實現 項目技術棧 該項目采用了以下核心技術棧: 后端框架/庫: Java SSM框架數據庫: MySQL前端技術: 微信開發者工具、uni-app其他技術&#xff1a…

8B10B編碼(高速收發器五)

1、8B10B解決的問題 8B10B編碼是1983年IBM公司提出的傳輸編碼標準,通常用于高速收發器中,常見的JESD204B、SATA等接口協議,使用查表就可以實現編碼和解碼。 在這些高速收發器的接收端需要通過CDR技術去恢復時鐘與數據的相位關系,在…

Linux day6 yum下載,systemctl,

yum命令 yum [-y] install wget 通過yum下載wget小工具 -y的意思是,如果有詢問,自動確認(總是允許)。 yum remove wget 也可以通過這種方式卸載wget

Git版本控制工具的原理及應用詳解(四)

本系列文章簡介: 隨著軟件開發的復雜性不斷增加,版本控制成為了開發團隊中不可或缺的工具之一。在過去的幾十年里,版本控制工具經歷了各種發展和演變,其中Git無疑是目前最受歡迎和廣泛應用的版本控制工具之一。 Git的出現為開發者…