jssip连freeswitch加webRtc相关控制

2023-11-01


highlight: a11y-light

theme: juejin

摘要:最近在做一个freeSwitch项目,前端需要通过sip协议完成音视频通话,把一些关键的核心api记录一下;因为网上找的一部分资料不一定准确,这个是实际操作过得具有一定的参考性;基本复制粘贴可快速完成直连freeSwitch的目的;更新日期2022-10-19;

前端sip这块使用的是jssip(版本3.9.1),详细api可以去官网查看;freeSwitch(1.10.7)这个我们只做参考;

注册

js let ws = '你的freeSwitch直连地址'; let socket = new JsSIP.WebSocketInterface(ws); let configuration = { sockets: [socket], uri: `sip:${username}@${serverip}`, password: '', authorizationUser: '', sessionTimersExpires: 5000 } let UA = new JsSIP.UA(configuration); // 存储当前session和connection let currentSession = null; let currentConnection = null;

绑定事件

```js // 开始尝试连接 UA.on('connecting', () => {}); // 连接完毕 UA.on('connected', () => {}); // 主动取消注册或注册后定期重新注册失败 UA.on('unregistered', () => {}); // 注册失败 UA.on('registrationFailed', () => {}); // 注册成功 UA.on('registered', () => {}); // websocket 连接失败 UA.on('disconnected', () => {}); // 新消息接收和发送消息 UA.on('newMessage', (res) => { console.log('接收和发送消息', res, '消息字段', res.data); if (res.originator === 'remote') { // 远程消息 } else if ( res.originator === 'local') { // 本地消息 }; }); // 这一块处理webRTC音视频逻辑 UA.on('newRTCSession', (res) => { let { session, originator } = res; // 远程来电 if (originator === 'remote') { // 处理接听逻辑 handleAnswerWebRTCSession(session); } else if (originator === 'local') { // 处理呼叫逻辑 handleCallWebRTCSession(session); }; });

```

newRTCSession处理

```js // 处理接听newRTCSession function handleAnswerWebRTCSession(session) { /* session 要单独存下,后面接听挂断需要 挂断: session.terminate(); 接听:session.answer({'mediaConstraints': { 'audio': true, 'video': true }}) */ let {connection} = session; let currentSession = session; let currentConnection = connection; // 来电-被接听了 session.on("accepted", () => {
handleStreamsSrcObject(connection); }); session.on("peerconnection", () => {}); // 来电=>自定义来电弹窗,让用户选择接听和挂断 session.on("progress", () =>{}); // 挂断-来电已挂断 session.on("ended", () => {}); // 当会话无法建立时触发 session.on("failed", () => {}); } // 处理呼叫newRTCSession function handleCallWebRTCSession(session){ /
* session 要单独存下挂断需要 挂断: session.terminate(); connection 如果后面音视频做禁音,或者解绑轨道,或共享桌面需要 */ let {connection} = session; let currentSession = session; let currentConnection = connection; session.on('confirmed', () => { handleStreamsSrcObject(connection); }); } // 处理媒体流 handleStreamsSrcObject(connection) { if (connection.getRemoteStreams().length > 0) { // 获取远程媒体流 let srcObject = connection.getRemoteStreams()[0];
};

if (connection.getLocalStreams().length > 0) {
    // 获取本地媒体流
    let srcObject = connection.getLocalStreams()[0];
};

} ```

挂断/接听/呼叫

js hangUp() { currentSession.terminate(); }, answer(){ currentSession.answer({'mediaConstraints': { 'audio': true, 'video': true }}) } call(target, options = {isAudio: true, isVideo: true}, callback) { let url = `sip:${target}@${serverip}`; var eventHandlers = { // 在接收或生成对INVITE请求的1XX SIP类响应(> 100)时触发 'progress': function(data){ callback('呼叫中'); }, // 会议无法建立时触发 'failed': function(data){ callback('无法建立', data); }, // 通话确认(ACK收/发)时触发 'confirmed': function(data){ callback('已接听', data); }, // 当已建立的通话结束时触发 'ended': function(){ callback('通话结束了'); } } this.UA.call(url, { 'eventHandlers': eventHandlers, 'mediaConstraints': { 'audio': options.isAudio, 'video': options.isVideo}, }); }

屏幕共享-结束共享后切换原摄像头

js // 共享桌面 desktopSharing(){ let peerConnection = currentConnection; navigator.mediaDevices.getDisplayMedia({video: true, audio: true}).then((disStream) => { let srcObject = disStream; peerConnection.getSenders().forEach((sender) => { if (sender.track.kind == 'video') { var res = sender.replaceTrack(disStream.getVideoTracks()[0]); console.log(res); }; }); // 监听屏幕共享 disStream.getVideoTracks()[0].addEventListener('ended', () => { // '屏幕共享结束, 准备切换为本地摄像头 this.switchLocalCamera(peerConnection); }); }).catch((error) => { console.error('屏幕共享失败,失败原因:', error); }); } // 手动结束屏幕共享 endDesktopSharing() { let disStream = currentConnection.getLocalStreams()[0]; disStream.getVideoTracks().forEach((track) => { track.stop(); }); } // 切换为本地摄像头 switchLocalCamera() { var constraints = { audio: { autoGainControl: true, // 噪音消除 noiseSuppression: true, // 设置降噪 echoCancellation: true }, video: true } navigator.mediaDevices.getUserMedia(constraints).then((stream) => { let srcObject = stream; peerConnection.getSenders().forEach((sender) => { if (sender.track.kind == 'video') { sender.replaceTrack(stream.getVideoTracks()[0]) } }); }).catch((error) => { console.error('切换摄像头失败,失败原因:', error); }); }

视频上传分辨率

js // 视频上传分辨率 settingsScreenSize(constraints = { width: {exact: 50}, height: {exact: 50}}) { let tmpLocal = currentConnection.getLocalStreams()[0]; const videoTrack = tmpLocal.getVideoTracks()[0]; videoTrack.applyConstraints(constraints).then(() => { console.log('动态改变分辨率'); }); }

开启/关闭音频

js // 禁音 mute(){ let pc = currentConnection; if (pc.getSenders) { pc.getSenders().forEach((sender) => { // 如果是视频的话 kind === 'video' if (sender.track.kind === 'audio') { sender.track.enabled = false } }) } else { pc.getLocalStreams().forEach((stream) => { stream.getAudioTracks().forEach((track) => { // 如果是视频的话 kind === 'video' if (track.kind === 'audio') { track.enabled = false; } }) }); } } // 解除禁音 unmute(){ var pc = currentConnection; if (pc.getSenders) { pc.getSenders().forEach(function (sender) { // 如果是视频的话 kind === 'video' if (sender.track.kind === 'audio') { sender.track.enabled = true; } }); } else { pc.getLocalStreams().forEach(function (stream) { stream.getAudioTracks().forEach(function (track) { // 如果是视频的话 kind === 'video' if (track.kind === 'audio') { track.enabled = true; } }); }); } }

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

jssip连freeswitch加webRtc相关控制 的相关文章

  • 多方peer.js应用程序

    我对 PeerJs 和 WebRTC 是全新的 我有一个 1 1 NodeJS PeerJS 应用程序在我的远程服务器上运行 效果很好 然而现在我想探索将其扩展到 1 N 模型 其中主机 ID 可以有多个对等点连接到它们 并且每个对等点都可
  • CoTURN:如何使用 TURN REST API?

    我已经构建了 coturn 并成功运行它 ip 192 168 1 111 现在我面临的问题是通过REST API获取Turn凭证 https datatracker ietf org doc html draft uberti behav
  • 无法编译适用于 Android 的 WebRTC 库

    我正在尝试编译 WebRTC Native Stack 来构建libwebrtc aar但不幸的是无法理解出了什么问题 系统信息 Distributor ID Ubuntu Description Ubuntu 18 04 4 LTS Re
  • 通过 PeerConnection 发送具有 Web 音频效果的 MediaStream 对象

    我正在尝试发送通过以下方式获得的音频getUserMedia 并通过 WebRTC 的 PeerConnection 使用 Web Audio API 进行更改 Web Audio API 和 WebRTC 似乎有能力做到这一点 但我无法理
  • getUserMedia() 权限被拒绝

    我正在尝试使用测试屏幕共享getUserMedia 我有 Chrome 版本 28 和getUserMedia 屏幕捕获标志已启用 但我仍然收到权限被拒绝的错误 On this 屏幕截图演示 http simpl info screenca
  • 将 WebRTC (AudioTrackSinkInterface) 原始音频写入光盘

    我正在尝试录制 WebRTC 传输的音频PeerConnection MediaStream 我在音轨中添加了一个接收器 它实现了AudioTrackSinkInterface 它实现了OnData method void TestAudi
  • WebRTC、捕获屏幕

    我当前的问题是 我想找到一种在 Android 上的 webrtc 连接期间捕获帧 屏幕截图的方法 我知道这里已经有一些解决方案 但没有一个对我有用 按照我目前的方法 我遵循了这个Gist https gist github com Eri
  • iOS 和 Safari 11 WebRTC 不收集 STUN/TURN Trickle ICE 候选者

    在 iOS 11 iPhone 5s 和 iPhone 7 或桌面上使用 Safari 11 时 我的 Web 应用程序无法通过 CoTURN 服务器收集 WebRTC 中继 ICE 候选项 Web 应用程序 建立单向音频 WebRTC 对
  • WebRTC:对多个对等连接使用相同的 SDP?

    是否可以在多个对等连接中使用相同的 SDP 我正在使用 WebRTC 构建视频会议 这个想法是 呼叫者使用某种信令机制 使用其 SDP 每个用户相同的 SDP 向所有其他用户发送广播消息 然后用户将使用其 SDP 进行响应 当用户收到某人的
  • 直接从冷启动弹出状态

    我建造了一个科尔多瓦app https play google com store apps details id com everycrave livewire使用离子框架 它是使用构建的Peer JS http peerjs com 每
  • 如何在java应用程序中使用webRTC特定模块

    我有一个简单的java应用程序应用程序客户端可以向服务器发送 接收纯音频 UDP 数据包 服务器将音频数据包转发给除发送者之外的所有人 现在我该如何使用webRTC 回声消除我的应用程序端的模块或其他功能模块 我发现可以使用 JNI 和 w
  • 为 webRTC 使用特定端口

    当使用 webRTC 创建点对点音频连接时 如果用户位于路由器后面 我们使用的 STUN 服务器将返回公共 IP 现在在 ICE 对象中 我可以看到 rport 始终介于 50000 及以上 有没有办法使用特定端口 以便用户不必打开所有这些
  • 通过 Websocket 传输视频

    我正在尝试构建可以从双方传输视频的移动应用程序 即视频通话之类的东西 我研究了 webrtc 但这还没有为移动本机应用程序做好准备 无论如何 webrtc 正在做的是允许浏览器直接捕获相机和音频而不需要插件等 但在本机移动应用程序中捕获相机
  • Three.js 使用 WebRTC 并应用 Shader

    我不知道如何将着色器应用于具有视频纹理的 Three js 对象 我一直在使用 webRTC 和 Three js 并使用标准材质成功将视频纹理映射到网格上 var material new THREE MeshBasicMaterial
  • 我们可以将多个 html5

    我有两个视频 一个用于流式传输我的webcam另一个共享我的桌面屏幕 窗户 我需要合并这两个媒体流合而为一 这样我就可以将其另存为 mp4 文件并广播它WebRTC 我能够将两者结合起来VIDEO 流 标签通过将它们限制为DIV tag d
  • 在 Objective C 中使用 static init 有什么好处?

    最近我发现来自 Github 的 webrtc ios 示例 https github com gandg webrtc ios 当我浏览该项目时 我注意到 VideoView 类使用静态方法 但我不确定这是否必要 VideoView 是
  • WebRTC 和 Asp.Net Core

    我想将音频流从我的 Angular Web 应用程序录制到我的 Asp net Core Api 我认为 使用 SignalR 及其 websockets 是实现这一目标的好方法 通过这个打字稿代码 我可以获得一个 MediaStream
  • MediaStream 未处理的承诺拒绝:[object DOMError](在 Safari 11 中)

    在下面初始化 WebRTC 的方法中 我在 Safari Tech Preview 11 中遇到了未处理的承诺拒绝 具体来说 当我分配MediaStream像这样的视频元素 video srcObject event stream 堆栈跟踪
  • 通过 Websockets 进行 WebRTC 视频聊天

    我正在尝试使用 webRTC 和 WebSockets 进行信号发送来开发视频聊天应用程序 我的问题是 我不知道创建 RTCPeerConnection 并通过 webSocket 连接两个对等点 2 个浏览器 的过程是什么 至少在本地 我
  • Twilio webRTC 通话在 10 分钟后中断

    使用 Twilio js 使用 webRTC 录制通话 工作正常 但在 10 分钟时 完全正确 电话挂断 TwiML 上的最大记录时间设置为 7200 秒 浏览器的控制台显示 Twilio PeerConnection signalingS

随机推荐

  • osg::ref_ptr<osg::Image> image = osgDB::readImageFile(fileName); image指针为空

    前言 使用 OpenSceneGraph Quick Start Guide 中文版及源码 里面的一个例子TextureMapping 在我本机上运行没有问题 但拷贝到公司电脑 发现总是运行异常 无法读取纹理图片 调试到136行 image
  • lua的pcall

    对于大多数应用而言 我们无须在Lua代码中做任何错误处理 应用程序本身会负责处理这类问题 所有Lua语言的行为都是由应用程序的一次调用而触发的 这类调用通常是要求Lua语言执行一段代码 如果执行中发生了错误 那么调用会返回一个错误代码 以便
  • AcWing 196. 质数距离 二次筛法

    题 想求231 1范围的质数距离 那么我们可以求5e4范围中的所有质数 然后这些质数可以组成2 231 1中的所有合数 打表求5e4范围中的质数 用类似埃氏筛的方法把l到r的所有质数筛出来 由于差值不会超过 106 可以O n 扫描一遍求距
  • pytorch,mmdetection的安装以及注意事项

    如题 记录一下pytorch mmdetection的安装 以及注意事项 conda 基础操作 创建 name mmlab conda create n mmlab python 3 8 删除 conda remove n mmlab al
  • 数学建模-启发式算法-蚁群算法

    文章目录 蚁群算法 算法原理 算法特点 算法步骤 流程图 代码 蚁群算法 蚁群算法 由Marco Dorigo于1992年在他的博士论文中提出 是一种灵感来源于蚂蚁在寻找食物过程中发现路径的行为 用来在图中寻找优化路径的算法 算法原理 蚂蚁
  • 单例模式中的懒汉模式和饿汉模式是什么?

    一 懒汉模式 顾名思义 他是一个懒汉 他不愿意动弹 什么时候需要吃饭了 他就什么时候开始想办法搞点食物 即懒汉式一开始不会实例化 什么时候用就什么时候new 才进行实例化 二 饿汉模式 顾名思义 他是一个饿汉 他很勤快就怕自己饿着 他总是先
  • sqldeveloper 格式化(美化)sql语句快捷键

    1 Ctrl A 全选需要格式化的sql 2 Ctrl F7 格式化
  • C语言文件操作(1)

    目录 一 为什么使用文件 二 什么是文件 2 1 程序文件 2 2 数据文件 2 3 文件名 三 文件的打开和关闭 3 1 文件指针 3 2 文件的打开和关闭 四 文件的顺序读写 4 1 对比一组函数 一 为什么使用文件 我们前面学习 结构
  • UVA 1601 The Morning after Halloween (BFS/双向BFS)

    单向BFS 1150ms include
  • opencv-bayes模型训练以及加载

    此代码适用于opencv 数据集分开训练数据集和测试数据集合 训练模型代码 Ptr
  • 分享5个免费的Python学习网站,抓紧收藏吧~

    最近有好多人说刚开始学习 有哪些免费的学习网站可以自学一下 于是 趁着空闲的时间在各大网站上面梳理了一下 找出了5个比较好的学习网站 并且都是免费的 比较适合初学者了解一些基础语法 解决BUG问题 如果是大佬的话了解一下就行了 废话不多说了
  • 基于RRT算法的避障路径规划(MATLAB代码)

    基于RRT算法的避障路径规划 MATLAB代码 路径规划是机器人导航和自主移动中的关键问题之一 Rapidly exploring Random Trees RRT 算法是一种经典的随机采样路径规划算法 它通过随机采样和不断扩展树结构来搜索
  • Java英文日期格式转换yyyy-MM-dd格式

    我们在后端的开发过程中会经常跟日期相关的类型打交道 不过我们大多数在开发过程中遇到的格式都是基本的 年 月 日 yyyy MM dd 格式 当然 这种格式的日期我们都可以用Java自带的SimpleDateFormat类自带的转换方法来进行
  • Animate 2021 for Mac(an 2021中文版) v21.0.1中文直装版

    全新的adobe animate2021版本更加的引入注目 比如经过修改后的资产面板允许您在新的 默认 和 自定义 选项卡中查找 组织和管理资产 并且可通过组合各种资产快速创建炫酷的动画 从而减轻了以往的逐个创建动画效果 Animate 2
  • 关于moment时区处理问题,指定时间转换特定时区

    如题网上一堆复制粘贴让使用timezone插件的文章 查了十几分钟 真是浪费生命 垃圾文章太多 如果只想转换某个时间而已 是不需要使用timezone插件的 这个插件一用可能全局的时区就变了 问题就大了 只转换某几个时间的时区解决办法是mo
  • echart时间轴设置详解

    timeline x center 时间轴X轴方向位置设置 y bottom 时间轴Y轴方向位置设置 width 80
  • 常见算法题(包括华为机试题)

    一 维护O 1 时间查找最大元素的栈 问题描述 一个栈stack 具有push和pop操作 其时间复杂度皆为O 1 设计算法max操作 求栈中的最大值 该操作的时间复杂度也要求为O 1 可以修改栈的存储方式 push pop的操作 但是要保
  • vue + element + CDN 的方式使用

    CDN方式开发vue项目步骤 1 cdn 链接相关css element ui css common css js jq vue js element ui js common js 等 2 每个页面嵌入 下列相关内容 div 3 1415
  • DOM驱动和数据驱动的区别

    引言 在前端开发中 DOM驱动和数据驱动是两种常见的开发模式 它们代表了不同的思维方式和开发方式 本文将深入探讨DOM驱动和数据驱动的区别 并通过代码详解它们在前端开发中的应用 1 DOM驱动 DOM驱动是传统的前端开发方式 它的核心思想是
  • jssip连freeswitch加webRtc相关控制

    highlight a11y light theme juejin 摘要 最近在做一个freeSwitch项目 前端需要通过sip协议完成音视频通话 把一些关键的核心api记录一下 因为网上找的一部分资料不一定准确 这个是实际操作过得具有一