RTMP直播應用與延時分析

直播應用中,RTMP和HLS基本上可以覆蓋所有客戶端觀看,

HLS主要是延時比較大,RTMP主要優勢在于延時低。

一、應用場景

低延時應用場景包括:

. 互動式直播:譬如2013年大行其道的美女主播,游戲直播等等各種主播,流媒體分發給用戶觀看。用戶可以文字聊天和主播互動。

. 視頻會議:我們要是有同事出差在外地,就用視頻會議開內部會議。其實會議1秒延時無所謂,因為人家講完話后,其他人需要思考,思考的延時也會在1秒左右。當然如果用視頻會議吵架就不行。
. 其他:監控,直播也有些地方需要對延遲有要求,互聯網上RTMP協議的延遲基本上能夠滿足要求。

本文福利, 免費領取C++音視頻學習資料包+學習路線大綱、技術視頻/代碼,內容包括(音視頻開發,面試題,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,編解碼,推拉流,srs)↓↓↓↓↓↓見下面↓↓文章底部點擊免費領取↓↓

二、RTMP和延時

1. RTMP的特點如下:

1) Adobe支持得很好:

RTMP實際上是現在編碼器輸出的工業標準協議,基本上所有的編碼器(攝像頭之類)都支持RTMP輸出。原因在于PC市場巨大,PC主要是Windows,Windows的瀏覽器基本上都支持flash,Flash又支持RTMP支持得非常好。

2) 適合長時間播放:
因為RTMP支持的很完善,所以能做到flash播放RTMP流長時間不斷流,當時測試是100萬秒,即10天多可以連續播放。對于商用流媒體應用,客戶端的穩定性當然也是必須的,否則最終用戶看不了還怎么玩?我就知道有個教育客戶,最初使用播放器播放http流,需要播放不同的文件,結果就總出問題,如果換成服務器端將不同的文件轉換成RTMP流,客戶端就可以一直播放;該客戶走RTMP方案后,經過CDN分發,沒聽說客戶端出問題了。

3)延遲較低:
比起YY的那種UDP私有協議,RTMP算延遲大的(延遲在1-3秒),比起HTTP流的延時(一般在10秒以上)RTMP算低延時。一般的直播應用,只要不是電話類對話的那種要求,RTMP延遲是可以接受的。在一般的視頻會議應用中,RTMP延時也能接受,原因是別人在說話的時候我們一般在聽,實際上1秒延時沒有關系,我們也要思考(話說有些人的CPU處理速度還沒有這么快)。

4) 有累積延遲:

技術一定要知道弱點,RTMP有個弱點就是累積誤差,原因是RTMP基于TCP不會丟包。所以當網絡狀態差時,服務器會將包緩存起來,導致累積的延遲;待網絡狀況好了,就一起發給客戶端。這個的對策就是,當客戶端的緩沖區很大,就斷開重連。

2. HLS低延時

主要有人老是問這個問題,如何降低HLS延遲。

HLS解決延時,就像是爬到楓樹上去捉魚,奇怪的是還有人喊,看那,有魚。

你說是怎么回事?

3. RTMP延遲的測量

如何測量延時,是個很難的問題,

不過有個行之有效的方法,就是用秒表,可以比較精確的對比延時。

經過測量發現,在網絡狀況良好時:
. RTMP延時可以做到0.8秒左右。
. 多級邊緣節點不會影響延遲(和SRS同源的某CDN的邊緣服務器可以做到)
. Nginx-Rtmp延遲有點大,估計是緩存的處理,多進程通信導致?
. GOP是個硬指標,不過SRS可以關閉GOP的cache來避免這個影響.
. 服務器性能太低,也會導致延遲變大,服務器來不及發送數據。
. 客戶端的緩沖區長度也影響延遲。

譬如flash客戶端的NetStream.bufferTime設置為10秒,那么延遲至少10秒以上。

4. GOP-Cache

什么是GOP?就是視頻流中兩個I幀的時間距離。

GOP有什么影響?

Flash(解碼器)只有拿到GOP才能開始解碼播放。

也就是說,服務器一般先給一個I幀給Flash。

可惜問題來了,假設GOP是10秒,也就是每隔10秒才有關鍵幀,如果用戶在第5秒時開始播放,會怎么樣?

第一種方案:等待下一個I幀,也就是說,再等5秒才開始給客戶端數據。這樣延遲就很低了,總是實時的流。

問題是:等待的這5秒,會黑屏,現象就是播放器卡在那里,什么也沒有,有些用戶可能以為死掉了,就會刷新頁面。

總之,某些客戶會認為等待關鍵幀是個不可饒恕的錯誤,延時有什么關系?我就希望能快速啟動和播放視頻,最好打開就能放!

第二種方案:馬上開始放,放什么呢?

你肯定知道了,放前一個I幀。

也就是說,服務器需要總是cache一個gop,這樣客戶端上來就從前一個I幀開始播放,就可以快速啟動了。

問題是:延遲自然就大了。

有沒有好的方案?

有!至少有兩種:

編碼器調低GOP,譬如0.5秒一個GOP,這樣延遲也很低,也不用等待。

壞處是編碼器壓縮率會降低,圖像質量沒有那么好。

5. 累積延遲

除了GOP-Cache,還有一個有關系,就是累積延遲。

服務器可以配置直播隊列的長度,服務器會將數據放在直播隊列中,如果超過這個長度就清空到最后一個I幀:

當然這個不能配置太小,譬如GOP是1秒,queue_length是1秒,這樣會導致有1秒數據就清空,會導致跳躍。

有更好的方法?有的。
延遲基本上就等于客戶端的緩沖區長度,因為延遲大多由于網絡帶寬低,服務器緩存后一起發給客戶端,現象就是客戶端的緩沖區變大了,譬如NetStream.BufferLength=5秒,那么說明緩沖區中至少有5秒數據。

處理累積延遲的最好方法,是客戶端檢測到緩沖區有很多數據了,如果可以的話,就重連服務器。

當然如果網絡一直不好,那就沒有辦法了。

直播現狀簡介

想做一套直播系統?

1.技術實現層面:

技術相對都比較成熟,設備也都支持硬編碼。IOS還提供現成的 Video ToolBox框架,可以對攝像頭和流媒體數據結構進行處理,但Video ToolBox框架只兼容8.0以上版本,8.0以下就需要用x264的庫軟編了。

github上有現成的開源實現,推流、美顏、水印、彈幕、點贊動畫、濾鏡、播放都有。技術其實不是很難,而且現在很多云廠商都提供SDK,七牛云、金山云、樂視云、騰訊云、百度云、斗魚直播伴侶推流端,功能幾乎都是一樣的,沒啥亮點,不同的是整個直播平臺服務差異和接入的簡易性。后端現在 RTMP/HTTP-FLV 清一色,App掛個源站直接接入云廠商或CDN就OK。

2.直播優化層面

其實最難的難點是提高首播時間、服務質量即Qos(Quality of Service,服務質量),如何在丟包率20%的情況下還能保障穩定、流暢的直播體驗,需要考慮以下方案:

1.為加快首播時間,收流服務器主動推送 GOP :(Group of Pictures:策略影響編碼質量)所謂GOP,意思是畫面組,一個GOP就是一組連續的畫面至邊緣節點,邊緣節點緩存 GOP,播放端則可以快速加載,減少回源延遲

GOP.1

2.GOP丟幀,為解決延時,為什么會有延時,網絡抖動、網絡擁塞導致的數據發送不出去,丟完之后所有的時間戳都要修改,切記,要不客戶端就會卡一個 GOP的時間,是由于 PTS(Presentation Time Stamp,PTS主要用于度量解碼后的視頻幀什么時候被顯示出來) 和 DTS 的原因,或者播放器修正 DTS 和 PTS 也行(推流端丟GOD更復雜,丟 p 幀之前的 i 幀會花屏)

3.純音頻丟幀,要解決音視頻不同步的問題,要讓視頻的 delta增量到你丟掉音頻的delta之后,再發音頻,要不就會音視頻不同步

4.源站主備切換和斷線重連

5.根據TCP擁塞窗口做智能調度,當擁塞窗口過大說明節點服務質量不佳,需要切換節點和故障排查

6.增加上行、下行帶寬探測接口,當帶寬不滿足時降低視頻質量,即降低碼率

7.定時獲取最優的推流、拉流鏈路IP,盡可能保證提供最好的服務

8.監控必須要,監控各個節點的Qos狀態,來做整個平臺的資源配置優化和調度

直播過程.3

9.如果產品從推流端、CDN、播放器都是自家的,保障 Qos 優勢非常大

10.當直播量非常大時,要加入集群管理和調度,保障 Qos

11.播放端通過增加延時來減少網絡抖動,通過快播來減少延時

3.運營成本和客戶體驗

根據網上的數據,斗魚 TV 為 3 億人民幣,戰旗 TV 為 1.5 億人民幣,龍珠為 1.2 億人民幣,虎牙為 3000 萬 + 人民幣。

運營和推廣:這個就比較燒錢了,一些做移動直播、游戲直播、秀場直播的A輪至少得上千萬。

用戶體驗:流暢、不卡頓、不花屏、斷線重連、丟包策略、首畫加載速度、豐富的禮物系統,為了提高用戶體驗,可以在后臺加載其他頁面數據,但要在用戶體驗和內存優化方面找到平衡點。

流媒體傳輸

1.TCP:TCP為點對點的協議,雖然能保證了數據傳輸的可靠性,但是對服務器資源耗費較大,在數據流大的場合難以保證數據流傳輸的實時性。

2.UDP:UDP為不可靠傳輸協議,不需要維護連接狀態,也不認為每個數據包都必須到達接受端,因此網絡負荷比TCP小,傳輸速度也要比TCP快;但在網絡越擁擠時,越有更多的數據包丟失。

3.RTMP:RTMP一個專門為高效傳輸視頻,音頻和數據而設計的協議。它通過建立一個二進制TCP連接或者連接HTTP隧道實現實時的視頻和聲音傳輸。

4.FFmpeg:FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,并能將其轉化為流的開源計算機程序。采用LGPL或GPL許可證。它提供了錄制、轉換以及流化音視頻的完整解決方案

協議差異.4

項目搭建:采集端

1.目前比較知名的有VideoCore

目前國內很多知名的推流框架都是對VideoCore的二次開發。這個框架主要使用C++寫的,支持RTMP推流,但對于iOS開發者來說有點晦澀難懂(精通C++的除外)。想開源和免費的可以選擇現在的幾個知名項目VideoCore + GPUImage+基于GPU的美顏濾鏡 ,播放用IJKPlayer自己修改。

2.國內比較火的LiveVideoCoreSDK

框架提供IOS蘋果手機的RTMP推流填寫RTMP服務地址,直接就可以進行推流,SDK下載后簡單的工程配置后能直接運行,實現了美顏直播和濾鏡功能,基于OpenGL,前后攝像頭隨時切換,提供RTMP連接狀態的回調。

這個框架是國內比較早的一款推流框架有不少在使用這個SDK,功能非常齊全,作者也比較牛,用來學習推流采集相關內容非常好,但是集成到工程中有些困難(對于我來說)。總的來說這是一款非常厲害的推流SDK,幾乎全部使用C++寫的,編譯效率非常好,如果有實力的話推薦使用這個框架來做自己項目的推流端。

3.可讀性比較好的推流LFLiveKit

框架支持RTMP(Real Time Messaging Protocol ):實時消息傳輸協議,Adobe公司的。

HlS (HTTP Live Streaming) :蘋果自家的動態碼率自適應技術。主要用于PC和Apple終端的音視頻服務。包括一個m3u(8)的索引文件,TS媒體分片文件和key加密串文件。

推薦這個框架第一是因為它主要使用OC寫的,剩下的用C語言寫的,框架文件十分清晰,這對不精通C++的初學者提供了很大的便利,并且拓展性非常強,支持動態切換碼率功能,支持美顏功能。

4.美顏功能

美顏的話一般都是使用的GPUImage基于OpenGl開發,純OC語言,這個框架十分強大,可以做出各種不同濾鏡,可拓展性高。如果對美顏沒有具體思路可以直接用BeautifyFace,可以加入到項目中,很方便的實現美顏效果。

項目具體搭建

1.如何實現美顏?

美顏功能使用的是BeautifyFace,它可以很快速的實現美顏功能,效果不錯,它的底層還是基于的GPUImage,對GPUImage十分喜愛的Developer,可以參照BeautifyFace,寫出一個屬于自己的美顏功能,并且添加各種濾鏡。

2.懸浮TabBar的實現

這個TabBar看著像是用自定義TabBar做的,但事實上它還是用的系統的TabBar,給系統的tabBar.backgroundImage設置一張設計好的背景圖片。

想做一套像映客的直播系統?

TabBar.8

添加后會發現頂部有一條陰影線,并且TabBar的高度也不夠。陰影線與上圖綠色線條之間變成了透明顏色,實現下面方法隱藏陰影線,并且調高TabBar的高度。

TabBar.9

//隱藏陰影線[[UITabBar appearance] setShadowImage:[UIImage new]];- (void)setupTabBarBackgroundImage { UIImage *image = [UIImage imageNamed:@"tab_bg"]; CGFloat top = 40; // 頂端蓋高度CGFloat bottom = 40 ; // 底端蓋高度CGFloat left = 100; // 左端蓋寬度CGFloat right = 100; // 右端蓋寬度UIEdgeInsets insets = UIEdgeInsetsMake(top, left, bottom, right); // 指定為拉伸模式,伸縮后重新賦值UIImage *TabBgImage = [image resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch]; self.tabBar.backgroundImage = TabBgImage;[[UITabBar appearance] setShadowImage:[UIImage new]];[[UITabBar appearance] setBackgroundImage:[[UIImage alloc]init]];}//自定義TabBar高度- (void)viewWillLayoutSubviews { CGRect tabFrame = self.tabBar.frame;tabFrame.size.height = 60;tabFrame.origin.y = self.view.frame.size.height - 60; self.tabBar.frame = tabFrame;}

3.播放端的實現

播放端用的針對RTMP優化過的ijkplayer(),ijkplayer是基于FFmpeg的跨平臺播放器,這個開源項目已經被多個 App 使用,其中映客、美拍和斗魚使用了 ijkplayer(5700+??) 。在本文的末未提供了,已經打包好的ijkplayer,直接拖入項目就可以使用。省去了編譯的過程(編譯十分麻煩,并且容易出錯)。

- (void)goPlaying { //獲取urlself.url = [NSURL URLWithString:_liveUrl];_player = [[IJKFFMoviePlayerController alloc] initWithContentURL:self.url withOptions:nil]; UIView *playerview = [self.player view]; UIView *displayView = [[UIView alloc] initWithFrame:self.view.bounds]; self.PlayerView = displayView;[self.view addSubview:self.PlayerView]; // 自動調整自己的寬度和高度playerview.frame = self.PlayerView.bounds;playerview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;[self.PlayerView insertSubview:playerview atIndex:1];[_player setScalingMode:IJKMPMovieScalingModeAspectFill];}

4.推送端的實現

使用的是LFLiveKit,推流端可以選擇很多GitHub上的開源項目替代LFLiveKit,比如上面所提到的VideoCore,和LiveVideoCoreSDK。商用的話可以選擇各大廠商的SDK,網易直播云、七牛、騰訊、百度、新浪、其中金山直播云本人用過。使用直播云的好處就是能快速上線App,功能十分齊全,可以播放器和推流端,服務器一套下來,有專業客服人員幫助集成到工程中,缺點就是流量費太貴了。

- (UIButton*)startLiveButton{ if(!_startLiveButton){_startLiveButton = [UIButton new]; //位置_startLiveButton.frame = CGRectMake((XJScreenW - 200) * 0.5, XJScreenH - 100, 200, 40);_startLiveButton.layer.cornerRadius = _startLiveButton.frame.size.height * 0.5;[_startLiveButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[_startLiveButton.titleLabel setFont:[UIFont systemFontOfSize:16]];[_startLiveButton setTitle:@"開始直播" forState:UIControlStateNormal];[_startLiveButton setBackgroundColor:[UIColor grayColor]];_startLiveButton.exclusiveTouch = YES;__weak typeof(self) _self = self;[_startLiveButton addBlockForControlEvents:UIControlEventTouchUpInside block:^(id sender) {_self.startLiveButton.selected = !_self.startLiveButton.selected; if(_self.startLiveButton.selected){[_self.startLiveButton setTitle:@"結束直播" forState:UIControlStateNormal];LFLiveStreamInfo *stream = [LFLiveStreamInfo new];stream.url = @"rtmp://daniulive.com:1935/live/stream238";[_self.session startLive:stream];}else{[_self.startLiveButton setTitle:@"開始直播" forState:UIControlStateNormal];[_self.session stopLive];}}];} return _startLiveButton;}

stream.url是服務器的地址,推流完成后使用VLC播放

本文福利, 免費領取C++音視頻學習資料包+學習路線大綱、技術視頻/代碼,內容包括(音視頻開發,面試題,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,編解碼,推拉流,srs)↓↓↓↓↓↓見下面↓↓文章底部點擊免費領取↓↓

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

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

相關文章

TFA-Net

TFA SCA means ‘Self-Context Aggregation’ 作者未提供代碼

一文講明Mybatis 的使用 超詳細 【爆肝兩萬字教程】

我 | 在這里 🕵? 讀書 | 長沙 ?軟件工程 ? 本科 🏠 工作 | 廣州 ? Java 全棧開發(軟件工程師) 🎃 愛好 | 研究技術、旅游、閱讀、運動、喜歡流行歌曲 🏷? 標簽 | 男 自律狂人 目標明確 責任心強 ??公…

數據字典回顯功能設計與實現

數據字典回顯功能設計與實現 文章目錄 數據字典回顯功能設計與實現1. 業務場景2. 實現設計2.1 注解AOP切面2.2 注解mybatis攔截器2.3 注解序列化2.4 涉及字段直接申明成字典引用類型mybatis攔截器反序列化處理 3. 具體實現 1. 業務場景 我們日常開發中經常會遇到:數…

羊大師教你,什么搭配羊奶能夠帶來全方位的營養?

羊奶作為一種營養價值極高的乳制品,其豐富的營養成分對人體健康有著諸多益處。然而,不同的食物搭配會對羊奶的營養吸收產生不同的影響。為了讓大家更好地利用羊奶的營養價值,下面小編羊大師將為大家介紹一些與羊奶搭配的食物,幫助…

Qt實現畫的圖片移動

要實現左鍵點擊鼠標時圖片跟著鼠標移動,可以通過以下步驟來實現:1. 在QGraphicsView的構造函數中設置鼠標跟蹤屬性,以便能夠捕獲鼠標事件。cpp QGraphicsView::QGraphicsView(QWidget *parent) : QGraphicsView(parent) {setMouseTracking(tr…

Leetcode617合并二叉樹

理解題意:相同節點位置上,都有數據的話,節點值相加,只有一方有數據的話,把有數據的部分及相關子樹保留下來。 考察操作兩棵二叉樹,二叉樹的遍歷。 一般有兩種解決方式: 遞歸|迭代。 區別&#x…

element 中文地址

Element - The worlds most popular Vue UI framework 2 Menu 菜單 | Element Plus 3 偵聽器 | Vue.js vue中文官網

軟件測試職業規劃導圖

公司開發的產品專業性較強,軟件測試人員需要有很強的專業知識,現在軟件測試人員發展出現了一種測試管理者不愿意看到的景象: 1、開發技術較強的軟件測試人員轉向了軟件開發(非測試工具開發); 2、業務能力較強的測試人員轉向了軟件…

ubuntu創建新用戶, 并賦予root權限

在Ubuntu上創建新用戶可以通過adduser命令來完成。以下是創建新用戶的基本步驟: 打開終端:你可以按下Ctrl Alt T來打開終端。 使用sudo命令以管理員權限執行adduser命令。例如,如果你要創建一個名為newuser的新用戶,運行以下命…

【EI會議征稿】第三屆電子信息技術國際學術會議(EIT 2024)

The 3rd International Conference on Electronic Information Technology 第三屆電子信息技術國際學術會議(EIT 2024) 電子信息工程在我國信息化產業的發展過程中舉足輕重,且隨著現代社會的發展,航空航天領域、制造業領域和智能…

LSTM+CNN實現時間序列預測(負荷預測)

文章目錄 LSTM+CNN實現時間序列預測(PyTorch版)基于PyTorch搭建LSTM+CNN模型實現風速時間序列預測配置類時序數據集的制作數據歸一化數據集加載器搭建LSTM+CNN模型定義模型、損失函數、優化器模型訓練可視化結果十、完整源碼LSTM+CNN實現時間序列預測(Keras版)源碼模型訓練繪制…

每日一題:LeetCode-102.二叉樹的層序遍歷

每日一題系列(day 03) 前言: 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 &#x1f50e…

NX二次開發UF_CSYS_set_wcs 函數介紹

文章作者:里海 來源網站:https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_set_wcs Defined in: uf_csys.h int UF_CSYS_set_wcs(tag_t csys_id ) overview 概述 Sets the work coordinate system to the prototype coordinate system whose tag y…

為什么技術干不過產品?

近年來,我們經常會聽到一些關于技術和產品之間關系的討論,包括最近的ChatGPT之父奧特曼被董事會開除事件。在這個問題上,有人認為技術應該優于產品,因為技術是實現產品的基礎。然而,也有人認為產品比技術更重要&#x…

基于低代碼平臺搭建應用程序

目錄 一、背景 二、如何基于低代碼開發應用? 1.創建數據表 2.添加數據表屬性 3.配置功能 4.數據篩選 5.數據集顯示&功能發布 三、寫在最后 一、背景 很多時候,市場上的管理軟件魚龍混雜,找一些外包團隊在實際應用中效果并不理想&#xff…

企業微信平臺:連接你我,引領數字化未來

近年來,隨著移動互聯網的飛速發展,社交媒體平臺如微信已經成為人們生活中必不可少的一部分。對于企業而言,微信平臺不僅是一個重要的宣傳渠道,更是實現數字化轉型的關鍵工具。本文將探討企業微信平臺的發展趨勢、運營策略以及成功…

開源還是閉源(=°Д°=)!!趨勢表明,開源技術在諸多領域中日益受到重視

開源和閉源,兩種截然不同的開發模式,對于大模型的發展有著重要影響。開源讓技術共享,吸引了眾多人才加入,推動了大模的創新。而閉源則保護了商業利益和技術優勢,為大模型的商業應用提供了更好的保障。 一、開源和閉源的…

堆和前綴樹

1 堆 1.1 堆結構 堆是用數組實現的完全二叉樹結構完全二叉樹中如果每棵樹的最大值都在頂部就是大根堆,最小值在頂部就是小根堆堆結構的heapInsert就是插入操作,heapify是取出數組后進行堆結構調整的操作優先級隊列結構就是堆結構 public class Heap {…

通過ros系統中websocket中發送sensor_msgs::Image數據給web端顯示(三)

通過ros系統中websocket中發送sensor_msgs::Image數據給web端顯示(三) 不使用base64編碼方式傳遞 #include <ros/ros.h> #include <signal.h> #include <sensor_msgs/Image.h> #include <message_filters/subscriber.h> #include <message_filter…