如何通过提供/应答从两个对等连接交换流

2023-12-02

我正在尝试设置视频聊天,其中两个对等连接交换视频。创建数据通道后会发生这种情况。那么事件的流程是这样的:

  1. offerer创建数据通道,offerer创造并提供,answerer创建一个答案。到目前为止,一切都很好。我们有一个数据通道。
  2. offerer获取视频流获取用户媒体并将其添加到对等连接中,然后谈判的事件offerer fires, offerer创建新报价,同时answerer给出答案。还是一切都好。这offerer正在流式传输。
  3. answerer获取视频流获取用户媒体并将其添加到对等连接中,offerer创建新报价,同时answerer给出答案。还在。这answerer也在流媒体。

但是,如果我交换步骤 2 和 3 (所以answerer首先开始流式传输)然后事情开始出错。只有在步骤 1、3 和 2 全部完成后,双方才可以开始直播。

我很确定这与 SDP 提供和答案的顺序有关。

当我让应答者创建一个新的报价时需要谈判如果行为不同但仍然不稳定。

我现在对如何添加优惠和答案一无所知。

这是代码:

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
PeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection || window.RTCPeerConnection;
IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate || window.RTCIceCandidate;
SessionDescription =  window.mozRTCSessionDescription || window.webkitRTCSessionDescription || window.RTCSessionDescription;

var videoOfferer = document.getElementById('videoOfferer');
var videoAnswerer = document.getElementById('videoAnswerer');
var buttonOfferer = document.getElementById('buttonOfferer');
var buttonAnswerer = document.getElementById('buttonAnswerer');

var servers = {
    iceServers: [
        {url: "stun:23.21.150.121"},
        {url: "stun:stun.1.google.com:19302"}
    ]
};

var offerer = new PeerConnection(servers), answerer = new PeerConnection(servers);
var channelOfferer = null, channelAnswerer = null;

offerer.onicecandidate = function(e) {
    if(e.candidate == null) return;
    answerer.addIceCandidate(new IceCandidate(e.candidate), function(){}, error);
};

offerer.onaddstream = function(e) {
    videoOfferer.src = URL.createObjectURL(e.stream);
    videoOfferer.play();
};

answerer.onicecandidate = function(e) {
   if(e.candidate == null) return;
    offerer.addIceCandidate(new IceCandidate(e.candidate), function(){}, error);
};

answerer.onaddstream = function(e) {
    videoAnswerer.src = URL.createObjectURL(e.stream);
    videoAnswerer.play();
};

function offerCreated(sdp) {
    console.log('offer');
    offerer.setLocalDescription(new SessionDescription(sdp), function() {
        answerer.setRemoteDescription(new SessionDescription(sdp), function() {
            answerer.createAnswer(answerCreated, error);
        }, error);
    }, error);
}

function answerCreated(sdp) {
    console.log('answer');
    answerer.setLocalDescription(new SessionDescription(sdp), function() {
    }, error);
    offerer.setRemoteDescription(new SessionDescription(sdp), function() {
    }, error);
}

function error() {}

buttonOfferer.addEventListener('click', function() {
    navigator.getUserMedia({audio: true, video: true}, function(stream) {
        offerer.addStream(stream);
    }, function(){});
});

buttonAnswerer.addEventListener('click', function() {
    navigator.getUserMedia({audio: true, video: true}, function(stream) {
        answerer.addStream(stream);
    }, function(){});
});

channelOfferer = offerer.createDataChannel('channel', {reliable: true});

offerer.createOffer(offerCreated, error);

answerer.ondatachannel = function(e) {
    channelOfferer = e.channel;
    channelOfferer.onmessage = function(e) {
        console.log(e.data);
    };
    channelOfferer.onmessage = function(e) {
        console.log(e.data);
    };

      // these are added later
    offerer.onnegotiationneeded = function() {
        offerer.createOffer(offerCreated, error);
    };

    answerer.onnegotiationneeded = function() {
        offerer.createOffer(offerCreated, error);
    };
};

我认为问题出在第 3 步,当应答者添加视频时,要约者启动。在真正的远程调用中,报价者如何知道要这样做?

据我了解,当应答者需要重新协商时,角色实际上就会颠倒过来,因为为了重新谈判的目的:谈判者充当要约者,非谈判者充当应答者。

换句话说:响应pc.onnegotiationneeded总是:

  1. createOffer(),
  2. then setLocalDescription(description)
  3. 然后发送pc.localDescription到另一边

无论一边。

我不是 SDP 的权威,所以我不确定这是正确的方法,但是规范中的示例至少向我表明上述步骤是正确的,并且我是这样工作的。

我已经对此进行了测试这个 Firefox jsfiddle这似乎有效。小提琴使用说明:

  1. 没有服务器(因为它是一个小提琴),所以按Offer按钮并复制报价。
  2. 将报价粘贴到另一个选项卡或另一台计算机上同一小提琴中的同一位置。
  3. 按 ENTER 键,然后复制您得到的答案并将其粘贴回第一个小提琴中。
  4. 您现在已连接到两个数据通道:一个用于聊天,另一个用于发送信号。
  5. 现在按addTrack在任一端,视频应显示在另一端。
  6. Press addTrack在另一个方向,你应该有双向视频。

这样会产生眩光吗?我确信,可能有更好的方法来处理这个问题,但这似乎对我有用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何通过提供/应答从两个对等连接交换流 的相关文章

  • 如何将一个表单的文件上传字段中的值复制到另一个表单的文本字段?

    我有一页上有两种不同的表格 第一个表单允许用户上传图像文件并通过电子邮件发送 第二个表单根据用户输入生成 URL 为了将图像名称添加到 URL 我需要在第二个表单中有一个字段 该字段从第一个表单的字段中复制图像名称 我不想让用户浏览并选择图
  • 设置 location.hash 时防止默认行为

    当我这样做时 location hash test url 会更新 页面会定位到具有该 id 的元素 有没有办法阻止页面定位到该元素 Solution 您无法阻止这种行为 但您可以通过暂时隐藏目标来愚弄它 例如 像这样 与 jQuery 无
  • 不使用 PHP 提交联系表单

    我还是一名学生 今天我们的讲师告诉我们 无需使用 mailto 函数即可提交联系我们表单的唯一方法是使用 PHP 我发誓去年另一位讲师向我们展示了一种仅使用 javascript 的方法 是否可以使用基本表单和 javascript 提交反
  • 将 FireBug 用于带有框架的网站

    我下载了 Firebug 并尝试使用它来调试使用框架的站点的 JS 我的理解是 当我进入 Firebug 中的 脚本 选项卡时 我会看到 aspx 上的 JS 函数以及包含的任何文件中的 JS 并且我将能够设置断点 然而 我在这个网站上看到
  • Chrome 开发工具:无需切换到“源”选项卡即可进入调试器

    如果我把debugger https developer mozilla org en US docs JavaScript Reference Statements debugger当 Chrome 开发工具打开时 我的 JavaScri
  • 是否可以进行条件解构或有后备?

    我有一个具有许多深层嵌套属性的对象 我希望能够访问 MY KEY 上的属性 如下 但如果该属性不存在 则获取 MY OTHER KEY 我怎样才能做到这一点 const X Y MY KEY Values segments segment
  • 如何解构 React props 并仍然访问其他 props?

    我很好奇如果我想要所有的 props 但也想要解构单个属性 那么组件的参数 props 是否可以像导入一样解构 我想这更像是一个 JavaScript 问题 而不是一个 React 问题 但是举个例子 import React useEff
  • 三.js环境光意想不到的效果

    在下面的代码中 我渲染了一些立方体并使用点光源和环境光照亮它们 然而 当设置为 0xffffff 时 AmbientLight 会将侧面的颜色更改为白色 无论其指定的颜色如何 奇怪的是 点光源按预期工作 我怎样才能使环境光表现得像点光 因为
  • 修剪日期格式 PrimeNG 日历 - 删除时间戳、角度反应形式

    我将以下内容推入我的反应形式 obj 中2016 01 01T00 00 00 000Z但我想要以下2016 01 01 有谁知道有一个内置函数可以实现上述目的 我已经搜索过文档here https www primefaces org p
  • Next.js:如何将 source-map-explorer 与 Next.js 一起使用

    我想分析我的 Next js 构建源地图浏览器 https www npmjs com package source map explorer 有人可以帮我编写脚本吗 对于 React CRA 我使用以下脚本 build analyze n
  • 动态更改 vuejs 2 中的选择输入选项

    如何动态更改选择下拉 v model 中的选项 我有 2 个选择输入 其中一个应该根据其他输入进行更改 例如 如果我选择 水果 则选择显示水果 如果我选择 蔬菜 则选择显示蔬菜 我不使用Vuejs 但查看文档后 var TypesArr F
  • 在电子生成器反应电子应用程序后,在 Windows 中出现空白屏幕

    在电子生成器反应电子应用程序后 Windows 中出现空白屏幕 这是package json 在电子生成器反应电子应用程序后 Windows 中出现空白屏幕 name SmallBusinessManagement version 0 1
  • 在移动网站中处理 iPhone 事件(如向左滑动)

    iPhone 浏览器是否有可以使用 Javascript 挂钩的特殊事件 例如 如果用户向左滑动 我想执行某个操作 如果有类似的活动 很高兴看到所有这些活动的参考 理想情况下 有一天所有触摸屏移动浏览器都会有一个标准 您可以访问多点触控事件
  • 在 Chrome 中加载analytics.js时出现307重定向

    我正在构建一个网络应用程序并使用 Google Analytics analytics js 进行分析 我最近注意到 Chrome 中的分析功能无法正常工作 我使用单独模块中的标准代码片段加载分析并通过 requirejs 包含 我已验证该
  • 如何更改元素的 CSS 类并在单击时删除所有其他类

    我如何处理 AngularJS 2 中的一种情况 即单击一个元素需要更改其自己的样式 并且如果其他元素具有该样式 则需要将其删除 最好在一个函数中 如同Angular js 如何在单击时更改元素 css 类并删除所有其他元素 https s
  • 我们如何使用 thymeleaf 绑定对象列表的列表

    我有一个表单 用户可以在其中添加任意数量的内容表对象这也可以包含他想要的列对象 就像在 SQL 中构建表一样 我尝试了下面的代码 但没有任何效果 并且当我尝试绑定两个列表时 表单不再出现 控制器 ModelAttribute page pu
  • 动态 dom 操作后,如何在浏览器历史记录中保留 dom 状态?

    是否有一个通用的解决方案来保留 dom 状态 以便当用户使用后退 前进返回页面时 整个页面处于他们离开时的确切状态 这篇文章询问并回答了为什么不同浏览器和不同 javascript 库的行为不一致 Ajax 后退按钮和 DOM 更新 htt
  • 如何调试 Node.js 应用程序?

    如何调试 Node js 服务器应用程序 现在我主要使用警报调试打印语句如下 sys puts sys inspect someVariable 一定有更好的调试方法 我知道谷歌浏览器 http en wikipedia org wiki
  • Javascript/jQuery 外部高度()

    Does idOfLememt outerHeight 对所有浏览器产生相同的结果 IE7 有什么不同吗 只要去http api jquery com outerHeight http api jquery com outerHeight
  • 我如何用 javascript/jquery 进行两指拖动?

    我正在尝试创建当有两个手指放在 div 上时拖动 div 的功能 我已将 div 绑定到 touchstart 和 touchmove 事件 我只是不确定如何编写这些函数 就像是if event originalEvent targetTo

随机推荐

  • Flask WTForms 在 validate_on_submit() 上总是给出 false

    我使用 wtforms 创建了一个注册表单 我在其中使用 FormField 这样我就不必再次重复表单的某些元素 但每当我单击 提交 按钮时 它总是在 validate on submit 方法调用上给出 false 不明白为什么会发生这种
  • 如何处理与 Google 游戏服务的断开连接?

    我使用 Google 游戏服务作为排行榜 像这样显示它 static public void showLeaderboard String lid if isLogined 1 Log i TAG Showing leaderboard I
  • 使用 awk 或 sed 解析来自 ifconfig 的数据?

    我正在尝试使用 sed 解析 ifconfig 输出中的一些数据 但我无法正确执行此操作 我希望该命令只提取我想要的数字 例如 我有兴趣提取发送的字节 eth1 Link encap Ethernet HWaddr 00 00 00 09
  • CUDA 支持的 Windows 编译器

    我是一个正在尝试入门的 CUDA 程序员新手 我在 5 5 版本中遇到了这里提到的问题 Visual Studio 2010 Express 中 CUDA 5 5 出现 干净 错误 谁能确认这只是 5 5 版本的问题吗 是否有我可以安装的早
  • Firebase 推送通知添加操作按钮

    我正在服务器端发送推送通知 并且我正在使用这个 http 协议 https firebase google com docs cloud messaging http server ref 并且我想添加像这样的操作按钮https githu
  • 函数未定义

    我的 jquery 脚本出现函数未定义错误 我不知道为什么 jQuery 代码 http maps google com maps file api v 2 key ABQIAAAAhTrgZ5jvdqcEQouEpPcZ hS81NmJw
  • 如何通过CSS或javascript给句子赋予句首字母? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 如何通过CSS或javascript给句子赋予句首字母 我已经尝试过这些 CSS 属性
  • 为 jax rs 客户端设置超时

    我想为 jax rs 客户端设置连接超时 ClientConfig configuration new ClientConfig configuration property ClientProperties CONNECT TIMEOUT
  • 将 GestureOverlayView 添加到我的 SurfaceView 类,如何添加到视图层次结构?

    在后来的回答中我被告知 我必须将我在代码中创建的 GestureOverlayView 添加到我的视图层次结构中 但我并不 100 知道如何做到这一点 以下是为了完整性而提出的原始问题 我希望我的游戏能够识别手势 我有一个很好的 Surfa
  • iOS 中的后台录音

    我广泛搜索了有关如何在后台录制音频的文档 并得出结论 在 plist 文件中指定 音频 可能有效 但是 由于 iOS 4 在内存不足时会终止后台应用程序 因此当我们转换到后台时 我们还必须采取一些措施来减少内存使用量 我们如何减少内存使用
  • 在 pycrypto 中使用 RSA 的致盲因子

    在Python中 我试图对消息进行盲化和取消盲化 当我取消隐藏消息时 我没有收到原始消息 有谁知道我可能做错了什么 以下是我的代码 s Hello loadedPublic get publickey loadedPrivate get p
  • SQLite 和自定义排序依据

    我有一个包含类别的表 ID Category 1 Baking 3 Family 4 Entertaining 5 Children 6 Desserts 现在我想将 select 语句的结果排序为 ID Category 4 Entert
  • 使用c#将一个字节数组插入到另一个字节数组的特定位置

    这可能是一个愚蠢的问题 但尚未找到简单的答案 我正在尝试将一个简单的 C 字节数组插入到另一个字节数组的特定位置 例如 现有字节不应被覆盖 而应向后移动 真的就像您在现有文本块中复制页面某些文本块一样 到目前为止 我将创建一个具有两个现有数
  • jQuery SlideToggle 一次一个 div 而不是全部独立

    我使用下面的函数来切换 div 通过它 任何一个条目内容 div 都可以独立打开或关闭 如果任何时候只打开一个条目内容 div 那就太好了 单击关闭的条目标题 div 将关闭任何其他条目内容 div 然后打开单击的条目 我需要保留 html
  • 如何通过 javax.xml.ws.Service 进行调用

    在 Eclipse 中创建了一个新的标准 java 7 项目 并成功获得了一个实例javax xml ws Service像这样 String wsdlURL http example com 3000 v1 0 foo bar SomeS
  • hiveconf 变量可以从文件加载吗? (与 HiveQL 文件分开)

    我经常有一大块 HiveQL 我想使用某些变量的不同设置来运行多次 一个简单的例子是 set mindate 2015 01 01 00 00 00 set maxdate 2015 04 01 00 00 00 select from m
  • 二维数组java中的最小值和最大值

    我想输出二维数组的最大值和最小值 Max 效果很好 但即使数组中没有零 min 也始终输出零 我设置Math random 到 99 以防止在此示例中数组中出现零的可能性较小 完整代码如下 public class e public sta
  • 从终端创建项目时 Gitlab 默认项目可见性

    每当我开始一个新项目时 我都会将其添加到我的 Gitlab VCS 本地 中 git init git add git commit m Commit message git remote add origin gi email prote
  • Ghostscript - PS 到 PDF - 反转图像问题

    我正在尝试使用 Ghostscript 将 postscript 转换为 PDF 一切都可以正常转换 除了在某些情况下图像由于某种原因被反转 报告的错误信息 http bugs ghostscript com show bug cgi id
  • 如何通过提供/应答从两个对等连接交换流

    我正在尝试设置视频聊天 其中两个对等连接交换视频 创建数据通道后会发生这种情况 那么事件的流程是这样的 offerer创建数据通道 offerer创造并提供 answerer创建一个答案 到目前为止 一切都很好 我们有一个数据通道 offe