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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...