WebRTC for UWP

来源:http://www.cnblogs.com/Yixin-ran/archive/2016/10/21/webrtc.html
-Advertisement-
Play Games

首先還是簡單的介紹下webRTC吧: WebRTC,名稱源自網頁實時通信(Web Real-Time Communication)的縮寫,是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術,是谷歌2010年以6820萬美元收購Global IP Solutions公司而獲得的一項技術。2011年5 ...


首先還是簡單的介紹下webRTC吧:

  WebRTC,名稱源自網頁實時通信(Web Real-Time Communication)的縮寫,是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術,是谷歌2010年以6820萬美元收購Global IP Solutions公司而獲得的一項技術。2011年5月開放了工程的源代碼,在行業內得到了廣泛的支持和應用,成為下一代視頻通話的標準。(摘自百度百科)

  簡而言之,webrtc就是一種讓瀏覽器獲得更好的音視頻實時通話的技術,現在各大瀏覽器都已經支持。由於是開源的,所以不僅僅局限於瀏覽器,各大平都有相應編譯的版本,包括uwp。

  介紹完了(雖然你肯定還不明白),那就來談談uwp的實現吧。

  首先要使用webrtc需要在nuget包管理中搜索並安裝”webrtc“,或者在nuget控制台輸入Install-Package WebRTC。安裝完成後using webrtc_winrt_api;這個命名空間,接下來就可以直接用了。

  先來說下使用webrtc需要具備的條件:

    1.發送連接信息和打洞信息的伺服器,也就是信令伺服器。不過這個沒有什麼要求,只要可以把信息送到對方就可以了。你可以使用任何協議來完成信令傳輸,比如socket,websocket,http等等。

    2.打洞伺服器IceServer。這個伺服器需要有兩個功能:

      1. NAT/防火牆穿越
      2. 如果點對點通信建立失敗,可以作為中轉伺服器

  如果網路條件具備了,那麼請接著往下看:

  WebRTC這裡提供了三個介面:

     MediaStream:通過MediaStream的API能夠通過設備的攝像頭及麥克風獲得視頻、音頻的同步流
     RTCPeerConnection:RTCPeerConnection是WebRTC用於構建點對點之間穩定、高效的流傳輸的組件
     RTCDataChannel:RTCDataChannel建立一個高吞吐量、低延時的通道,用於傳輸任意數據 

這和web端以及其他平臺是一致的,只不過實現的方法略微不同。

  下麵來看看如何獲取視頻流以及音頻流:

首先最重要的是初始化 

 WebRTC.Initialize(this.Dispatcher);

接下來

            Media = Media.CreateMedia();//創建一個Media對象

            RTCMediaStreamConstraints mediaStreamConstraints = new RTCMediaStreamConstraints() //設置要獲取的流 
            {
                audioEnabled = true,
                videoEnabled = true
            }; 

            var apd = Media.GetAudioPlayoutDevices(); 
            var acd = Media.GetAudioCaptureDevices(); 
            var vcd = Media.GetVideoCaptureDevices(); 
            Media.SelectAudioCaptureDevice(acd[0]);
            Media.SelectAudioPlayoutDevice(apd[0]); 
            Media.SelectVideoDevice(vcd.First(p => p.Location.Panel == Windows.Devices.Enumeration.Panel.Front));//設置視頻捕獲設備
            var mediaStream = await Media.GetUserMedia(mediaStreamConstraints);//獲取視頻流 這裡視頻和音頻是一起傳輸的
            var videotracs = mediaStream.GetVideoTracks();
            var audiotracs = mediaStream.GetAudioTracks();
            var source = Media.CreateMediaSource(videotracs.FirstOrDefault(), mediaStream.Id);//創建播放源
            LocalMediaPlayer.SetMediaStreamSource(source); //設置MediaElement的播放源

現在就已經獲取到了本地視頻了,如果媒體播放控制項的autoplay為true的話,那麼視頻已經開始播放,你將看到自己帥氣的臉龐。

下麵就要開始連接了,首先創建一個RTCPeerconnection並包含你的打洞伺服器IceServer:

        List<RTCIceServer> iceservers = new List<RTCIceServer>()
              {
                    new RTCIceServer {Url="<your server>",Username="<your name>" },
                    new RTCIceServer {Url="<your server>",Username="<your name>" },
                    new RTCIceServer {Url="<your server>",Username="<your name>" },
                    new RTCIceServer {Url="<your server>",Username="<your name>" }
               }; //不一定是這麼多個

            RTCConfiguration configuration = new RTCConfiguration() { BundlePolicy = RTCBundlePolicy.Balanced, IceServers = servers, IceTransportPolicy = RTCIceTransportPolicy.All };
            conn = new RTCPeerConnection(configuration);
            conn.AddStream(mediaStream);
            conn.OnIceCandidate += Conn_OnIceCandidate;
            conn.OnAddStream += Conn_OnAddStream;

 

接下來開始連接:

  Step1:視頻通話發起方Creeat一個Offer,設置Peerconnection的LocalDescription,把offer的Sdp發送到視頻通話接收方:

 public async Task CreatOffer() //此時是發起方的操作
        {
            var offer = await conn.CreateOffer();
            await conn.SetLocalDescription(offer);
            await Send_Message(offer.Sdp);
        }

 

  Step2:接收方收到Offer消息,此時同發起方一樣,初始化並創建mediaStream,創建peerconnection。設置peerconnection的RemoteDescription,創建一個Answer,設置LocalDescription,發送Answer的Sdp給發起方:

 async public Task CreatAnswer(string offersdp) //此時是接受方的操作
        { 
            var offer = new RTCSessionDescription(RTCSdpType.Offer, offersdp);
            await conn.SetRemoteDescription(offer);
            var answer = await conn.CreateAnswer();
            await conn.SetLocalDescription(answer); 
            await Send_Message(answer.Sdp);    
        }

 

於此同時,RTCPeerconnection的OnIceCandidate事件會被觸發,發送Candidate的數據到另一端

  private async void Conn_OnIceCandidate(RTCPeerConnectionIceEvent __param0) //此事件接收方和發起方都需要
        {
            var Candidate = __param0.Candidate;
            var candidate = JsonConvert.SerializeObject(Candidate);
            await Send_Message(candidate);
        }

 

接收到Candidate後將Candidate添加到Peerconnection

  await conn.AddIceCandidate(JsonConvert.DeserializeObject<RTCIceCandidate>(CandidateMsg));//兩邊都與要添加,candidatemsg為收到的信息,而非自己的

當上述過程完成後,Peerconnection的OnAddStream事件會被觸發,這也代表通信建立完成,通話開始。將接收到的stream添加到MEdiaElement:

            var stream = __param0.Stream;
            var videotracks = stream.GetVideoTracks();
            var source = Media.CreateMediaSource(videotracks.FirstOrDefault(), stream.Id); 
            RemoteMediaPlayer.SetMediaStreamSource(source);
            RemoteMediaPlayer.Play(); 

好了一個完整的WebRTC通話過程就完成了!

讓我們再來回顧一下整個過程:Server代表發起方,Client代表接收方(很顯然這樣稱呼是不正確的)

  Step1.  WebRTC.Initialize                Server & Client

  Step2.  Media.CreatMedia                Server & Client

  Step3.  Media.GetUserMedia              Server & Client

  Step4.  new RTCPeerconnection             Server & Client

  Step5.  Conn.AddStream                 Server & Client

  Step6.  CreatOffer                     Server

  Step7.  SetLocalDescription               Server

  Step8.  Send Offer.Sdp                  Server

  Step9.  SetRemoteDescription               Client

  Step10.  CreatAnswer                    Client

  Step11.  SerLocalDescription                Client

  Step12.  Send Answer.Sdp                 Client

  Step13.  Send Candidate                 Server & Client

  Step14.  AddCandidate                  Server & Client

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在項目中,有時候一些信息不便完全顯示,只需要顯示部分信息。現在提供一些隱藏敏感信息的操作方法,主要為對信息的截取操作: 1.指定左右字元數量,中間的*的個數和實際長度有關: 2.指定左右字元數量,中間的*的個數固定: 3.“*”數量一定,設置為4個,按信息總長度的比例來取,預設左右各取1/3: 4. ...
  • 一、前言 前不久因公司產品需要完成了線上升級功能,因為編程技術不精,不敢冒然採用Socket方法實現線上升級,所以使用比較方便穩妥的WCF方式 如果考慮併發能力的話還是Socket>WCF>Remoting,所以如果你是Socket專家的話這篇你就不用看了。 二、流程 本篇主要講述一個完整的升級思路 ...
  • 在.NET項目中,我們較多的使用到加密這個操作。因為在現代的項目中,對信息安全的要求越來越高,那麼多信息的加密就變得至關重要。現在提供幾種常用的加密/解密演算法。 1.用於文本和Base64編碼文本的互相轉換 和 Byte[]和Base64編碼文本的互相轉換: (1).將普通文本轉換成Base64編碼 ...
  • 上一章筆者對於WinForm開發過程用到的幾個知識點做了講解。筆者們可以以此為開端進行學習。而本章我們來講一個跟ORM思想有關的知識點。在講之前讓我們想一下關於JAVA的hibernate知識點。hibernate也是ORM框架。記得hibernate裡面有一個叫HQL。先不管HQL的好與壞。主要是 ...
  • 一、目標樣式 我們要實現上圖中的效果,需要如下的操作: 1.從工具欄上的”Smobiler Components”拖動一個Button控制項到窗體界面上 2.修改Button按鈕的屬性 a.Size屬性 設置控制項的寬度和高度,見下圖; b.BarcodeScanned事件代碼 3.Smobiler窗體 ...
  • 說到參數獲取,大家肯定會說,能玩出什麼花來呢! 今天我們就來說說,關於Request[“參數名”],你天天和他打交道的主! Long ago,一經理跟我說,今天你來開發一個註冊的頁面吧,註冊的實體類,都已經有啦!如下: 好啦,你可以開發了! 按照策劃稿,頁面樣式,腳本,都已經寫好了,接下來,需要提交 ...
  • 因為ComboxItem是Object對象,而控制項自身沒有Value屬性.所以,需要自定義一個類,用其對象來存儲Text,Value. public class ComboxItem { private string text; private string values; public strin ...
  • 以下內容全部為web版本的老模板風格下完成。 一、在編輯狀態的詳細視圖下列印報表。 有些時候,需要在編輯狀態下直接列印報表內容,官方預設是不允許這樣做的。用Reflector查看源碼,可以看到: 在這個方法中禁止了顯示按鈕的邏輯。 ShowInReportActionEnableModeDefaul ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...