中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python使用UDP實現720p視頻傳輸的操作方法

發布時間:2021-04-26 14:12:16 來源:億速云 閱讀:689 作者:小新 欄目:開發技術

小編給大家分享一下Python使用UDP實現720p視頻傳輸的操作方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

Python的優點有哪些

1、簡單易用,與C/C++、Java、C# 等傳統語言相比,Python對代碼格式的要求沒有那么嚴格;2、Python屬于開源的,所有人都可以看到源代碼,并且可以被移植在許多平臺上使用;3、Python面向對象,能夠支持面向過程編程,也支持面向對象編程;4、Python是一種解釋性語言,Python寫的程序不需要編譯成二進制代碼,可以直接從源代碼運行程序;5、Python功能強大,擁有的模塊眾多,基本能夠實現所有的常見功能。

1. 項目背景

視頻傳輸: 在一臺電腦上播放視頻(捕捉攝像頭畫面),同局域網內另一臺電腦上實時播放,盡量不卡頓。

先放最后的照片,和用gif展示一下視頻效果。

Python使用UDP實現720p視頻傳輸的操作方法

Python使用UDP實現720p視頻傳輸的操作方法

傳輸視頻可以采取圖片或者流的形式,本文采取傳輸圖片的形式,在1s之內顯示多張圖片從而形成連續的視頻畫面。

經費有限,所有實驗均基于筆記本電腦。

使用的視頻源是本機攝像頭,以及進擊的巨人720p資源。

2. 解決方案

1. 使用Python的Socket,使用opencv捕捉攝像頭/視頻的畫面。

2. 原始的圖片很大(720p的大小是1920*1080*3),整圖就算壓縮成jpg格式其大小也非常大。而UDP最大只能傳輸65535字節大小的數據區,故對圖片進行分塊,分塊過后的數據壓縮成jpg格式,并對圖片分塊數據進行編號。

3. 實驗檢測表明,本文實驗環境發送端不需要使用發送隊列,基本上新生成的幀很快就能被socket傳輸掉。

4. 接收端使用多線程接收,每個線程是一個socket,接收過后的數據存儲于數據片池。

5. 接收端另開一個線程,用于反復從數據片池 讀取數據片,根據數據片的編號更新幕布,這里幕布是專門用于圖像顯示的一個數組,其維度是720p(1920*1080*3)。更新過后的結果暫存于圖片池

6. 主線程反復從圖片池讀取圖片,并顯示。

3. 實現細節

3.1 TCP/UDP的選擇

為了實現低延遲,毫無疑問選取無連接的UDP傳輸。

3.2 圖片分片算法

這里其實也談不上什么算法,就是將圖片水平分割。這種做法的好處在于,分割后圖片的編號可以和區域一一對應。本文沒有探索更為復雜的圖片分片算法。

Python使用UDP實現720p視頻傳輸的操作方法

經過處理,圖片變為一個個分片,如下:

Python使用UDP實現720p視頻傳輸的操作方法

Python使用UDP實現720p視頻傳輸的操作方法

Python使用UDP實現720p視頻傳輸的操作方法

Python使用UDP實現720p視頻傳輸的操作方法

對上述圖片進行編號,很顯然可以編號0,1,2,3,對于任意分塊(例如2)在圖像數組中對應的區域是frame[2*piece_size:(2+1)*piece_size],其中piece_size表示一片數據的大小。

這種對應關系方便解壓后的圖像還原操作。

3.3 JPG壓縮

這其實是個很小的技術點,因為使用的壓縮算法都是現成的。但是值得一提的是,JPG的壓縮率是真的高,在實驗數據上實現了10-20倍的壓縮率。

使用了多線程壓縮,壓縮完過后,更新對應的桶,這里的桶實際上就是數據片。

Python使用UDP實現720p視頻傳輸的操作方法

由主線程Main Thread反復從桶里取數據片(t1),每取1片發送一次,然后再取下一片(t2),直到所有桶都被取了一次(例子中有10片)。

至此,一張圖片的分片數據被全部取完,于是開始統計一些FPS相關信息。

3.4 接收隊列

接收端開了10個線程用于異步socket接收數據片。

為了保證接收端產生絲滑的視頻效果,使用接收隊列是個不錯的選擇。本文使用了2個隊列的設計。實現數據接收的二級緩沖。示意圖如下:

Python使用UDP實現720p視頻傳輸的操作方法

這樣一來,視頻效果明顯絲滑了很多。

4. 遇到的坑及解決辦法

4.1. Windows防火墻

巨坑,最好都關了。

Python使用UDP實現720p視頻傳輸的操作方法

4.2. 路由器網絡頻段

同一臺路由器的5G和2.4G頻段有時候不能互相ping通,要確保兩個電腦連接在同一頻段上。

4.3. Wifi配置

如果上述設置都對了,但是還是ping不通。將wifi連接設置成專用網絡,也許就能解決問題。

Python使用UDP實現720p視頻傳輸的操作方法

4.4. 硬件瓶頸

個人PC的性能是較大瓶頸,尤其是單機測驗的時候(本地兩個終端,一個發送、一個接收),CPU使用率分分鐘到100%。聽某個技術大哥說要使用GPU壓縮。

Python使用UDP實現720p視頻傳輸的操作方法

用兩臺電腦,一臺接收一臺發送之后,效果要好很多。

4.5. OpenCV讀取攝像頭大坑

由于攝像頭驅動的關系,在我的電腦上需要設置以下兩個變量,才能成功啟用外置的720p攝像頭。

	os.environ["OPENCV_VIDEOIO_DEBUG"] = "1"
	os.environ["OPENCV_VIDEOIO_PRIORITY_MSMF"] = "0"

即使如此,如果不做額外的設置,讀出來的圖片將是480p的(看起來很像是720p被壓縮過后的)。所以如果要傳輸真·720p,還需要設置讀出的圖像大小,如下:

	self.stream = cv2.VideoCapture(1) # 讀取第一個外置攝像頭
	self.stream.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)   # float
	self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)   # float

4.6. Socket卡頓

不知道是不是我寫的有問題,感覺多線程的socket會爭搶資源(發送和接收的線程間,對應5.1節功能),造成接收端的畫面顯示將變得卡頓。

5. 尚未Bug Free的功能

5.1 使用TCP回傳幀率信息

為了計算網絡時延,采取類似伽利略測光速的方法。從數據包打包之前,到對方收到數據包之后,再將這個數據回傳到發送方。

這樣就不存在兩臺機器時間差校準的問題。

該算法的大致流程如下圖所示。

Python使用UDP實現720p視頻傳輸的操作方法

Python使用UDP實現720p視頻傳輸的操作方法

這種計算方式應該是自己的實驗環境下比較準確的方法了。

時延信息的反饋不需要特別快(比如200-500ms發送一次),所以使用TCP技術

其實TCP和UDP在使用Python編程的時候代碼差距可以說極小…

但是!!!

自己目前在實現信息回傳的時候,會莫名卡頓起來。

接收端建立回傳的socket之后,甚至還沒傳輸數據,整個程序運行起來就變得非常卡頓,這個讓我比較苦惱,目前正在找bug.

5.2 擁塞控制 (流量控制)的算法

這部分的思想是流量控制,感謝評論區指正。

5.1節如果一并回傳接收端隊列狀態信息。如果接收端隊列太滿,說明來不及處理視頻幀了,從而對發送端的發送速度進行控制,才是“擁塞控制”

這個本來是想著和5.1綜合起來用的,已經寫好了,但是還沒能真正展現價值,設計是否合理也值得商榷。

控制的是發送端的發送頻率,從而實現接收端的流暢播放

思想和TCP的擁塞控制一樣慢增長,快下降。如果接收端的隊列一直處于較空的狀態,則表明還有一定的性能剩余,此時可以緩慢加快發送的頻率;如果檢測到接收端隊列中數據較多,表明發送速度太快來不及顯示,這時候就大幅下降發送的頻率。

這個擁塞控制的算法基于幾個假設:

1.網絡情況良好,丟包率比較低;

2接收端電腦的性能足夠高,來得及處理解包、顯示圖像。

如果5.1能夠正確實現,則應該根據網絡時延Python使用UDP實現720p視頻傳輸的操作方法的大小來控制發送的頻率。

以上是“Python使用UDP實現720p視頻傳輸的操作方法”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

象州县| 梁平县| 兴化市| 观塘区| 南召县| 青龙| 美姑县| 陆良县| 临夏县| 台南县| 定边县| 平顶山市| 内江市| 遂宁市| 八宿县| 五华县| 大田县| 虹口区| 哈密市| 揭西县| 娱乐| 贵港市| 扶余县| 隆尧县| 汉源县| 泰来县| 古蔺县| 金华市| 咸丰县| 丰镇市| 萝北县| 浮梁县| 嘉兴市| 余干县| 河池市| 蒲江县| 南充市| 永平县| 江陵县| 澎湖县| 永仁县|