当前位置:首页 > 科技  > 软件

WebRTC.Net库开发进阶,教你实现屏幕共享和多路复用!

来源: 责编: 时间:2023-08-05 11:46:09 5259观看
导读WebRTC.Net库:让你的应用更亲民友好,实现视频通话无痛接入! 除了基本用法外,还有一些进阶用法可以更好地利用该库。自定义 STUN/TURN 服务器配置WebRTC.Net 默认使用 Google 的 STUN 服务器和 Coturn 的 TURN 服务器。如

Met28资讯网——每日最新资讯28at.com

WebRTC.Net库:让你的应用更亲民友好,实现视频通话无痛接入! 除了基本用法外,还有一些进阶用法可以更好地利用该库。Met28资讯网——每日最新资讯28at.com

自定义 STUN/TURN 服务器配置

WebRTC.Net 默认使用 Google 的 STUN 服务器和 Coturn 的 TURN 服务器。如果你需要使用其他 STUN/TURN 服务器,则可以在初始化 PeerConnectionFactory 和 PeerConnection 时设置自定义配置。Met28资讯网——每日最新资讯28at.com

例如,以下代码设置了使用 coturn 服务器的 PeerConnectionFactory:Met28资讯网——每日最新资讯28at.com

var config = new PeerConnectionConfiguration{   IceServers = new List<IceServer>   {      new IceServer{ Urls = new[] { "stun:stun.l.google.com:19302" }},      new IceServer{ Urls = new[] { "turn:my-turn-server.com" }, Username="myusername", Credential="mypassword" }   }};var factory = new PeerConnectionFactory(config);

在不同线程中创建和使用 PeerConnectionFactory 和 PeerConnection 对象:

WebRTC.Net 库本质上是基于线程的,因此它的对象通常在单独的线程中创建和使用。这样可以避免在主线程中对 UI 线程造成大量负担。Met28资讯网——每日最新资讯28at.com

以下代码在后台线程中创建并使用 PeerConnection 对象Met28资讯网——每日最新资讯28at.com

Task.Run(() =>{   var config = new PeerConnectionConfiguration { IceServers = new List<IceServer> { new IceServer { Urls = new[] { "stun:stun.l.google.com:19302" } } } };   var factory = new PeerConnectionFactory(config);   var pc = factory.CreatePeerConnection(config);      // 在这里使用 PeerConnection 对象,不会阻塞主线程}).Wait();

选择视频和音频设备

在创建 PeerConnectionFactory 对象时,可以设置 defaultAudioDevice 和 defaultVideoDevice 参数以选择默认的音频和视频设备。Met28资讯网——每日最新资讯28at.com

例如,以下如何通过设备名称选择视频和音频设备:Met28资讯网——每日最新资讯28at.com

var config = new PeerConnectionConfiguration{   IceServers = new List<IceServer> { new IceServer { Urls = new[] { "stun:stun.l.google.com:19302" } } },   DefaultVideoDevice = VideoCaptureDevice.GetDevices().FirstOrDefault(x => x.Name == "MyCameraName"),   DefaultAudioDevice = AudioCaptureDevice.GetDevices().FirstOrDefault(x => x.Name == "MyMicrophoneName")};var factory = new PeerConnectionFactory(config);

实现数据通道

WebRTC.Net 库不仅支持音视频传输,还支持实现数据通道(DataChannel)。使用数据通道,应用程序可以在客户端之间传输任意类型的数据,例如聊天消息、游戏状态等。Met28资讯网——每日最新资讯28at.com

以下代码如何创建数据通道:Met28资讯网——每日最新资讯28at.com

// 创建 PeerConnection 对象var config = new PeerConnectionConfiguration { IceServers = new List<IceServer> { new IceServer { Urls = new[] { "stun:stun.l.google.com:19302" } } } };var factory = new PeerConnectionFactory(config);var pc = factory.CreatePeerConnection(config);// 创建数据通道var dcConfig = new DataChannelInit { Ordered = true };var dc = pc.CreateDataChannel("mydatachannel", dcConfig);// 监听数据通道事件dc.MessageReceived += (sender, e) =>{   // 处理接收到的数据};

实现屏幕共享

除了音视频传输和数据通道,WebRTC.Net 还支持屏幕共享。这意味着应用程序可以捕获屏幕上的内容并将其共享给其他客户端。Met28资讯网——每日最新资讯28at.com

以下是使用 WinForm 技术栈和 WebRTC.Net 库实现桌面共享的示例代码。Met28资讯网——每日最新资讯28at.com

using System;using System.Drawing;using System.Threading.Tasks;using System.Windows.Forms;using Windows.Graphics.Capture;using Windows.Graphics.DirectX.Direct3D11;using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;using Org.WebRtc;namespace DesktopStreaming{    public partial class MainForm : Form    {        private PeerConnection _peerConnection;        private DataChannel _dataChannel;        private Direct3D11CaptureFramePool _framePool;        private GraphicsCaptureSession _session;        private VideoTrack _videoTrack;        public MainForm()        {            InitializeComponent();            // 初始化 WebRTC            WebRTC.Initialize(new WebRTCInitializationOptions { EnableAudioBufferLog = false });            // 创建 PeerConnectionFactory 对象            var config = new PeerConnectionConfiguration { IceServers = new[] { new IceServer { Urls = new[] { "stun:stun.l.google.com:19302" } } } };            var factory = new PeerConnectionFactory(config);            // 创建 PeerConnection 对象            _peerConnection = factory.CreatePeerConnection();            // 创建数据通道            _dataChannel = _peerConnection.CreateDataChannel("mychannel");            // 订阅数据通道的消息事件            _dataChannel.MessageReceived += (sender, args) =>            {                // 处理收到的消息            };            // 创建 Direct3D11CaptureFramePool 对象            var device = Direct3D11Helpers.CreateDevice();            var size = new Size(800, 600);            _framePool = Direct3D11CaptureFramePool.CreateFreeThreaded(                device,                Direct3DPixelFormat.B8G8R8A8UIntNormalized,                1,                size);            // 订阅 FrameArrived 事件            _framePool.FrameArrived += (sender, args) =>            {                // 获取最新的桌面帧                using var frame = sender.TryGetNextFrame();                if (frame == null) return;                // 将桌面帧转换为 RTCVideoFrame 对象                var videoFrame = new RTCVideoFrame(frame.ContentSize.Width, frame.ContentSize.Height, RTCVideoFrameType.RTCVideoFrameTypeI420);                videoFrame.ConvertFromArgb32(frame.Surface.Direct3D11Device, frame.Surface);                // 将 RTCVideoFrame 对象转换为 VideoTrack 对象并发送                if (_videoTrack != null)                    _videoTrack.PushFrame(videoFrame);            };            // 创建 GraphicsCaptureItem 对象            var item = ScreenCapture.GetDefault();            // 创建 GraphicsCaptureSession 对象            _session = _framePool.CreateCaptureSession(item);        }        private async void btnStart_Click(object sender, EventArgs e)        {            // 开始共享桌面            await _session.StartAsync();            // 创建视频轨道            _videoTrack = await PeerConnectionFactory.GetVideoTrackSourceAsync(_framePool);            // 添加视频轨道到 PeerConnection 对象            await _peerConnection.AddTrack(_videoTrack);            // 创建 Offer SDP 并设置本地描述符            var offerSdp = await _peerConnection.CreateOffer();            await _peerConnection.SetLocalDescription(offerSdp);            // 发送 Offer SDP 到远端            SendSdp(offerSdp);        }        private void SendSdp(RTCSessionDescription sdp)        {            // 将 SDP 转换为 JSON 格式并发送到远端            var json = Newtonsoft.Json.JsonConvert.SerializeObject(new { type = sdp.Type, sdp = sdp.Sdp });            _dataChannel.Send(json);        }        private async void MainForm_FormClosing(object sender, FormClosingEventArgs e)        {            // 关闭 PeerConnection 和 GraphicsCaptureSession 对象            await _peerConnection.CloseAsync();            _session.Dispose();        }    }}

上述代码中,我们使用了 ScreenCapture 类来获取默认的桌面捕获项目,然后创建了 GraphicsCaptureSession 对象来捕获桌面帧。我们还使用了
Direct3D11CaptureFramePool 类来创建一个 Direct3D 11 帧池,并订阅了 FrameArrived 事件以获取最新的桌面帧。在每次收到桌面帧时,我们将其转换为 RTCVideoFrame 对象,再将其发送到 WebRTC 连接中。通过这种方式,我们就实现了桌面共享的功能。
Met28资讯网——每日最新资讯28at.com

需要注意的是,由于 WebRTC 是基于 p2p 的实时通信协议,因此本示例代码中仅演示了如何将桌面共享的数据发送给远端客户端,而没有涉及如何在远端客户端上解析和显示收到的数据。Met28资讯网——每日最新资讯28at.com

处理 ICE 连接状态

WebRTC.Net 使用 ICE(Interactive Connectivity Establishment)协议来建立和维护客户端之间的连接。ICE 协议涉及多个状态和事件,例如 gathering、connected、disconnected 等等。应用程序可以订阅 PeerConnection 对象上的各种事件来处理这些状态。Met28资讯网——每日最新资讯28at.com

以下代码如何订阅 PeerConnection 对象上的连接状态:Met28资讯网——每日最新资讯28at.com

// 创建 PeerConnection 对象var config = new PeerConnectionConfiguration { IceServers = new List<IceServer> { new IceServer { Urls = new[] { "stun:stun.l.google.com:19302" } } } };var factory = new PeerConnectionFactory(config);var pc = factory.CreatePeerConnection(config);// 订阅 PeerConnection 对象上的连接状态pc.IceStateChanged += (sender, iceState) =>{   if (iceState == IceConnectionState.Connected)   {      // 客户端已成功连接   }   else if (iceState == IceConnectionState.Disconnected)   {      // 客户端已断开连接   }};

实现多路复用

WebRTC.Net 支持实现多路复用(Multiplexing),这意味着应用程序可以在同一个数据通道上同时传输多种类型的数据,例如音频、视频、文件等。Met28资讯网——每日最新资讯28at.com

下面是使用 WinForm 技术栈和 WebRTC.Net 库实现多路复用的示例代码。Met28资讯网——每日最新资讯28at.com

Copy Codeusing System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;using Org.WebRtc;namespace WebRTC_Multiplexing{    public partial class Form1 : Form    {        private PeerConnection _peerConnection;        private List<DataChannel> _dataChannels = new List<DataChannel>();        public Form1()        {            InitializeComponent();            // 初始化 WebRTC            WebRTC.Initialize(new WebRTCInitializationOptions { EnableAudioBufferLog = false });            // 创建 PeerConnectionFactory 对象            var config = new PeerConnectionConfiguration { IceServers = new[] { new IceServer { Urls = new[] { "stun:stun.l.google.com:19302" } } } };            var factory = new PeerConnectionFactory(config);            // 创建 PeerConnection 对象            _peerConnection = factory.CreatePeerConnection();            // 订阅 PeerConnection 的连接状态改变事件            _peerConnection.ConnectionStateChanged += (sender, args) =>            {                // 处理连接状态改变事件                BeginInvoke(new Action(() => txtOutput.AppendText($"连接状态:{args.NewState.ToString()}/r/n")));            };            // 订阅 PeerConnection 的数据通道回调事件            _peerConnection.DataChannelAdded += (sender, args) =>            {                // 处理数据通道回调事件                var dataChannel = args.Channel;                dataChannel.MessageReceived += DataChannel_MessageReceived;                _dataChannels.Add(dataChannel);                BeginInvoke(new Action(() => txtOutput.AppendText($"收到数据通道:{dataChannel.Label}/r/n")));            };        }        private async void btnCreateOffer_Click(object sender, EventArgs e)        {            // 创建 Offer SDP 并设置本地描述符            var offerSdp = await _peerConnection.CreateOffer();            await _peerConnection.SetLocalDescription(offerSdp);            // 发送 Offer SDP 到对端            SendSdp(offerSdp);        }        private void SendSdp(RTCSessionDescription sdp)        {            // 将 SDP 转换为 JSON 格式并发送到对端            var json = Newtonsoft.Json.JsonConvert.SerializeObject(new { type = sdp.Type, sdp = sdp.Sdp });            _dataChannels.ForEach(dc => dc.Send(json));        }        private async void DataChannel_MessageReceived(object sender, DataChannelMessageEventArgs e)        {            // 收到数据通道消息后将其转换为 RTCSessionDescription 对象            if (e.MessageType == DataMessageType.Text)            {                var text = e.Data;                var sdp = Newtonsoft.Json.JsonConvert.DeserializeObject<RTCSessionDescription>(text);                // 设置远端描述符并完成连接                await _peerConnection.SetRemoteDescription(sdp);                if (sdp.Type == RTCSessionDescriptionType.Offer) await _peerConnection.CreateAnswer();            }        }    }}

上述代码中,我们创建了一个 PeerConnectionFactory 对象和一个 PeerConnection 对象,用于建立 WebRTC 连接。我们还创建了一个 _dataChannels 列表来保存所有的数据通道对象,每当 PeerConnection 对象添加一个新的数据通道时,我们就将其添加到 _dataChannels 列表中。Met28资讯网——每日最新资讯28at.com

在 btnCreateOffer_Click 事件处理方法中,我们创建了一个 Offer SDP 并设置本地描述符,然后将其发送到所有的数据通道对象中。当收到对端发送过来的 SDP 消息时,我们将其转换为 RTCSessionDescription 对象,并调用 SetRemoteDescription 方法设置远端描述符。如果收到来自对端的 Offer SDP,则执行 CreateAnswer 方法创建 Answer SDP 并将其发送回对端。Met28资讯网——每日最新资讯28at.com

通过这种方式,我们就可以使用同一个 PeerConnection 对象来支持多路复用。每当需要发送数据时,只需要将数据发送到指定的数据通道对象即可。需要注意的是,在使用多路复用时,我们需要为不同的数据通道设置不同的标签(Label),以便在接收端识别不同的通道。Met28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-147-0.htmlWebRTC.Net库开发进阶,教你实现屏幕共享和多路复用!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 一个注解实现接口幂等,这样才优雅!

下一篇: Python异步IO编程的进程/线程通信实现

标签:
  • 热门焦点
  • 7月安卓手机性能榜:红魔8S Pro再夺榜首

    7月份的手机市场风平浪静,除了红魔和努比亚带来了两款搭载骁龙8Gen2领先版处理器的新机之外,别的也想不到有什么新品了,这也正常,通常6月7月都是手机厂商修整的时间,进入8月份之
  • 0糖0卡0脂 旭日森林仙草乌龙茶优惠:15瓶到手29元

    旭日森林无糖仙草乌龙茶510ml*15瓶平时要卖为79.9元,今日下单领取50元优惠券,到手价为29.9元。产品规格:0糖0卡0脂,添加草本仙草汁,清凉爽口,富含茶多酚,保留
  • 三万字盘点 Spring 九大核心基础功能

    大家好,我是三友~~今天来跟大家聊一聊Spring的9大核心基础功能。话不多说,先上目录:图片友情提示,本文过长,建议收藏,嘿嘿嘿!一、资源管理资源管理是Spring的一个核心的基础功能,不
  • 电视息屏休眠仍有网络上传 爱奇艺被质疑“薅消费者羊毛”

    记者丨宁晓敏 见习生丨汗青出品丨鳌头财经(theSankei) 前不久,爱奇艺发布了一份亮眼的一季报,不仅营收和会员营收创造历史最佳表现,其运营利润也连续6个月实现增长。自去年年初
  • 10天营收超1亿美元,《星铁》比《原神》差在哪?

    来源:伯虎财经作者:陈平安即便你没玩过《原神》,你一定听说过的它的大名。恨它的人把《原神》开服那天称作是中国游戏史上最黑暗的一天,有粉丝因为索尼在PS平台上线《原神》,怒而
  • 腾讯盖楼,字节拆墙

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之&ldquo;想重温暴刷深渊、30+技能搭配暴搓到爽的游戏体验吗?一起上晶核,即刻暴打!&rdquo;曾凭借直播腾讯旗下代理格斗游戏《DNF》一
  • “又被陈思诚骗了”

    作者|张思齐 出品|众面(ID:ZhongMian_ZM)如今的国产悬疑电影,成了陈思诚的天下。最近大爆电影《消失的她》票房突破30亿断层夺魁暑期档,陈思诚再度风头无两。你可以说陈思诚的
  • 超闭合精工铰链 彻底消灭缝隙 三星Galaxy Z Flip5与Galaxy Z Fold5发布

    2023年7月26日,三星电子正式发布了Galaxy Z Flip5与Galaxy Z Fold5。三星新一代折叠屏手机采用超闭合精工铰链,让折叠后的缝隙不再可见。同时,配合处
  • 2299元起!iQOO Pad明晚首销:性能最强天玑平板

    5月23日,iQOO如期举行了新品发布会,除了首发安卓最强旗舰处理器的iQOO Neo8系列新机外,还在发布会上推出了旗下首款平板电脑——iQOO Pad,其最大的卖点
Top