windows下實現螢幕分享 C

2021-09-20 01:33:26 字數 3477 閱讀 4542

採用udp廣播進行資料的傳輸,實現windows下進行低延遲的螢幕共享。

開發語言:c#

第三方元件:redis

1.實現思路

總體流程圖

dgis.desktopshare實現windows下螢幕分享低延遲功能,按照服務執行位置由三部分構成:發起端、接收端、快取端。

通過udp廣播實現發起端和接收端的通訊,是為了盡量的減少通訊負載和降低延遲。眾所周知udp是所有通訊協議中延遲最低的(但也有受網路因素丟包的問題,這裡作為區域網同屏,暫不考慮丟包問題),而採用廣播的方式可以有效的降低發起端的效能負擔。

增加乙個redis服務,是為了減少udp廣播資料,按照1920*1080解析度的截圖資料來算,單張已經超過了udp單包的最大資料量1472位元組,倘若直接使用udp傳輸截圖,需要額外的進行封包拆包,這樣不僅浪費了程式執行時間,也增加了傳送端和接收端的**複雜度。本著最低延遲的目的,將真實的資料存入redis快取,只通過udp廣播redis中對應的uid資訊即可,這也是本程式最核心的地方。接收端接收到uid的資料後,再自行去獲取redis中真實的資料進行解析。

2.**結構

dgis.desktopshare.service的**結構分為frm(窗體)、iservice(介面)、service(實現)三個部分。引用的第三方dll有redis相關操作庫、螢幕獲取相關庫和dgis開頭的輔助操作庫。

frm:

imgdisplyfrm是接收端的預設顯示介面,包含乙個picturebox控制項,顯示接收到的螢幕影象。

iservice:

idesktopshareservice螢幕共享操作介面,主要方法有4個。

注釋的已經很明確了,這裡不多說。

service:

desktopshareservice:idesktopshareservice的實現類,裡面是詳細的實現方法。核心的**有下面幾個地方:

1

public

void start(int framerate, bool mousedisplay, int

port)2);

89 _desktopcapturer =capture***ctory.createdesktopcapturer(framerate, mousedisplay);

10 _desktopcapturer.imagecaptured +=imagecaptured;

11_desktopcapturer.start();

1213

//佇列迴圈處理積壓的

14//

task.factory.startnew(() =>

15//

2324//}

25//

});26 }

開始螢幕分享,_udpservice 初始化,螢幕抓取設定以及開啟螢幕抓取。

1

///2

///螢幕截圖結果

3///

4///

5private

void

imagecaptured(bitmap bitmap)

6

1

///2

///傳送命令

3///

4///

5private

void

sendcommand(bitmap bitmap)

6

抓取到螢幕的結果是bitmap,這裡需要將bitmap轉換為byte,因為在測試中redis直接存入bitmap取出時候有些異常。待redis存入資料後,再通過udp傳送資料。來看下測試資料,獲取到傳送的耗時情況。

主要的耗時在轉換這個地方,耗時約10毫秒,redis存入時間是很快的6毫秒左右,udp傳送時間基本為0.

1

public

void recive(int

port)211

};12

13 _udpservice = new

udpbroadcastservice(port,

14 bytes =>

15);

18_imgdisplyfrm.showdialog();

19 }

1

///2

///顯示影象

3///

4///

5private

void showimg(byte

recivebytes)

6

1

///2

///解析

3///

4///

5///

6private bitmap parseimg(byte

bytes)721

else

22return

null

;23 }

接收端同樣也是開啟乙個_udpservice ,初始化,進行訊息監聽,接收到訊息後進入showimg(顯示影象)方法,中間主要**是parseimg(獲取解析)這部分,這部分實現將真實資料從redis中獲取。看下耗時情況。

這裡能看到,訊息的傳送和接收之間耗時約為0(這裡考慮本機沒有經過網絡卡,實際應該有100毫秒左右延遲),redis快取獲取時間非常的快4毫秒左右,轉碼耗時30毫秒。

以上綜合計算,從螢幕採集到終端接收解析總共耗時50毫秒左右,加上udp廣播理論上的100毫秒延遲,150毫秒是能夠達到的。

下圖是真實環境中兩台電腦的螢幕分享延遲。

從截圖上看,延遲在170毫秒,由此看出這種方案是比較可行的。

放一張測試效果圖。

3.原始碼

原始碼放到了csdn上,不知道如何上傳附件。萬惡的csdn居然至少需要設定2分了。

**開源位址

2018.1.30更新:增加了音效卡聲音採集同步傳輸

Windows下C 實現多執行緒

有時候我們想在乙個類中實現多執行緒,主線程在某些時刻獲得資料,可以 通知 子執行緒去處理,然後把結果返回。下面的例項是主線程每隔2s產生10個隨機數,將這10隨機數傳給多執行緒類,讓它接收到資料後馬上列印出來。首先看類的定義 cpp view plain copy print?pragma once...

分享個windows下的makefile

直接上 insert source test.cpp opencv version opencv ver 2.4.10 visual c version for opencv vc12.0 vc10.0 vc11.0 vsv vc12.0 cvv 2410 arch for opencv x86 x...

FFMPEG在Windows下的螢幕錄影錄音

ffmpeg在linux下用x11grab進行螢幕錄影,在windows下用directshow濾鏡 首先需要安裝乙個軟體,原始碼位址是 安裝完了之後,在命令列執行 ffmpeg list devices true f dshow i dummy 系統輸出大致如下 dshow 002db420 di...