jssip(一)——安装与配置

需求

最近接手的vue项目需要使用jssip通话,jssip官网是全英文,所有看起来比较费劲。完成项目后记录一下jssip。
这一章节主要记录了jssip的安装、配置以及一些状态信息传递,包括二次拨号函数、来电铃声开关函数、通话添加媒体流函数、接听挂断函数、初始化函数等

安装

npm install jssip

jssip文件

在src/utils下创建jssip.js文件

import JsSIP from 'jssip'
import bus from '@/utils/bus'

var ua = null
var currentSession // 当前会话
var peer
var stream // 流媒体

// 初始化配置
function initConfig(data) {
  // Create our JsSIP instance and run it:
  const socket = new JsSIP.WebSocketInterface(`wss://${data.url}:${data.port}`)
  const configuration = {
    sockets: [socket],
    uri: `sip:${data.username}@${data.url}`, // 分机号注册 格式 sip: + 分机号码 + @ + FS注册地址
    authorization_user: data.username, // 授权用户
    password: data.password, // 密码
    register: true, // 自动注册
    connection_recovery_max_interval: 60, // 链接恢复的最大间隔
    connection_recovery_min_interval: 5 // 链接恢复的最小间隔
  }
  return configuration
}

// 初始化jssip
function jssipInit(data) {
  JsSIP.C.SESSION_EXPIRES = 120 // FreeSWITCH 默认设置要求 Session Expires 不低于120 低于120打不出电话
  JsSIP.C.MIN_SESSION_EXPIRES = 120
  const configuration = initConfig(data) // 配置参数
  ua = new JsSIP.UA(configuration) // 创建对象
  addRegisterMethod(ua) // 添加监听方法
  ua.start() // 链接
  return ua
}

// 打电话
function call(data) {
  // 这一步也是添加监听,不过已经使用在addRegisterMethod方法中添加了这里为空就行
  const eventHandlers = {
    // 呼叫中
    // progress: function (e) {
    //   console.log('call is in progress')
    // },
    // 失败
    // failed: function (e) {
    //   console.log('call failed: ', e)
    // },
    // 结束
    // ended: function (e) {
    //   console.log('call ended : ', e)
    // }
    // 呼叫确认
    // confirmed: function (e) {
    //   console.log('call confirmed')
    // }
  }
  const options = {
    eventHandlers: eventHandlers,
    mediaConstraints: {
      audio: true,
      video: false
    }
  }
  // console.log('呼叫:' + data.phone)
  ua.call(`sip:${data.phone}@${data.url}`, options)
}

// jssip监听方法
function addRegisterMethod(ua) {
  // 接线中
  ua.on('connecting', (res) => {
    // console.log('接线中', res)
  })
  // 连线中
  ua.on('connected', (res) => {
    // console.log('连线中', res)
  })
  // 取消连线
  ua.on('disconnected', (res) => {
    console.log('取消连线', res)
  })
  // 注册成功
  ua.on('registered', (res) => {
    console.log('注册成功', res)
    bus.$emit('sessionData', { state: 'registered' }) // 这里使用bus将数据传递到对应的监听文件进行处理
  })
  // 注册失败
  ua.on('registrationFailed', (res) => {
    // console.log('注册失败', res)
  })
  // 注册即将失效(重新注册)
  ua.on('registrationExpiring', (res) => {
    console.log('重新注册', res)
  })
  // 注销回调
  ua.on('unregistered', (res) => {
    console.log('解除注册', res)
    bus.$emit('sessionData', { state: 'unregistered' }) // 这里使用bus将数据传递到对应的监听文件进行处理
  })

  // 会话
  ua.on('newRTCSession', function (data) {
    const { session, request, originator } = data
    currentSession = session
    // 呼叫中 打电话与接电话的呼叫都走这里
    currentSession.on('progress', (res) => {
      if (originator === 'remote') {
        console.log('电话过来拉~~~~~~~~~··', res)
        // console.log('我接听了', res)
        bus.$emit('sessionData', { state: 'progress-remote', data: request })
        playRingMedia() // 这里可以加一个判断,如果是监听的时候不需要播放音乐
      } else {
        console.log('接听事件在progress中触发', res)
        bus.$emit('sessionData', { state: 'progress' })
        streamingMediaPlayer() // 添加媒体流 这时候开启音频
      }
    })
    // 对等连接事件触发
    currentSession.on('peerconnection', (data) => {
      console.log('对等连接事件触发,peerconnection', data)
      bus.$emit('sessionData', { state: 'peerconnection' })
    })
    // 交换sdp信令事件触发
    currentSession.on('sdp', (res) => {
      console.log('交换sdp信令事件触发,sdp', res)
      bus.$emit('sessionData', { state: 'sdp' })
    })
    // 对等连接建立(通话连线时候触发)
    currentSession.on('connecting', (data) => {
      peer = currentSession._connection
      console.log('对等连接建立,connecting', peer, data)
      bus.$emit('sessionData', { state: 'connecting' })
    })
    // 通话接受时候触发
    currentSession.on('accepted', (res) => {
      console.log('通话接受时候触发', res)
      bus.$emit('sessionData', { state: 'accepted' })
    })
    // 通话失败事件触发
    currentSession.on('failed', (res) => {
      console.log('通话失败事件触发--- failed', res)
      stopPlayRingMedia() // 关闭来电振铃
      bus.$emit('sessionData', { state: 'failed' })
    })
    currentSession.on('reinvite', (res) => {
      // openLocalCamera()
      console.log('重新协商事件触发', res)
      if (currentSession._connection.getLocalStreams().length > 0) {
        // 接听后,判断localStream

      }
      if (currentSession?._connection.getRemoteStreams().length > 0) {

      }
    })
    // 呼叫确认
    currentSession.on('confirmed', (res) => {
      console.log('呼叫确认--设置媒体流到音视频中,confirmed', res)
      bus.$emit('sessionData', { state: 'confirmed' })
      if (originator === 'remote') {
        streamingMediaPlayer() // 呼入时没有添加媒体流,这时候添加媒体流
      }
    })
    // 通话结束
    currentSession.on('ended', (res) => {
      console.log('通话结束--- ended', res)
      bus.$emit('sessionData', { state: 'ended' })
    })
  })
}
// 挂断
function hangUp() {
  stopPlayRingMedia() // 关闭放来电振铃
  ua.terminateSessions()
}
// 接听
function answer() {
  var options = {
    mediaConstraints: { audio: true, video: false, mandatory: { maxWidth: 640, maxHeight: 360 } }
  }
  currentSession.answer(options) // 接听来电
}
// 添加媒体流
function streamingMediaPlayer() {
  stopstreamingMediaPlayer() // 先关闭媒体流
  stream = new MediaStream()
  const receivers = currentSession.connection?.getReceivers()
  if (receivers) {
    receivers.forEach((receiver) => stream.addTrack(receiver.track))
  }
  // 这里创建一个audio标签隐藏,添加媒体流,添加到界面id为ringMediaAudioId的标签中
  var ringAudio = document.getElementById('ringMediaAudioId')
  ringAudio = document.createElement('audio')
  ringAudio.id = 'ringMediaAudioId'
  ringAudio.hidden = true
  ringAudio.srcObject = stream // 添加媒体流
  var box = document.getElementById('ringMediaAudioBox')
  box.appendChild(ringAudio) // 添加到box中
  ringAudio.play() // 播放
}
// 停止播放媒体流
function stopstreamingMediaPlayer() {
  var ringAudio = document.getElementById('ringMediaAudioId')
  if (ringAudio) {
    var box = document.getElementById('ringMediaAudioBox')
    box.removeChild(ringAudio)
  }
}
// 播放来电振铃 
function playRingMedia() {
  stopPlayRingMedia()
  var ringAudio = document.getElementById('cheerMusic') // 这是界面存在的audio标签,隐藏了的,里面的音乐可以自己找,主要用于呼入时响铃
  ringAudio.play()
}
// 停止播放来电振铃
function stopPlayRingMedia() {
  var cheerMusic = document.getElementById('cheerMusic')
  cheerMusic.load()
}
/**
 * 二次拨号
 * @param dtmfNumber 二次拨号号码
 * 注意功能是打通电话后,在按键时对方可接收到
 */
function dtmf(dtmfNumber) {
  console.log(dtmfNumber)
  const options = {
    transportType: 'RFC2833' // dtmf类型,默认是info
  }
  currentSession.sendDTMF(dtmfNumber, options)
}
const sip = {
  jssipInit: jssipInit, // 初始化
  call: call, // 拨号
  answer: answer, // 接听
  hangUp: hangUp, // 挂断
  dtmf: dtmf // 二次拨号
}
export default sip

bus.js文件

在src/utils文件下创建bus.js文件(在需要跨文件触发时引入)

// @/utils/bus.js
import Vue from 'vue'
const bus = new Vue()
export default bus

使用

由于内容过多,具体使用请看jssip(二)——使用

https://blog.csdn.net/xuelong5201314/article/details/132623288
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
jssip demo是一个基于JavaScript的开源软件库,用于实现SIP(Session Initiation Protocol,会话发起协议)通信协议的Web应用程序的开发。SIP是一种通信协议,用于建立、修改和解除多媒体会话,比如VoIP电话、视频通话等。 jssip demo提供了一个示例,用于演示如何使用jssip库来实现浏览器之间的实时通信。这个demo可以在网页上直接运行,不需要额外的软件安装。 在jssip demo中,我们可以看到一个网页界面,其中包含了拨号键盘、呼叫按钮等元素。我们可以输入电话号码,然后点击呼叫按钮,就可以建立起与对方的通话连接。 jssip demo的实现过程包括以下几个步骤: 1. 引入jssip库:在网页上引入jssip库的JavaScript文件。 2. 创建SIP用户:配置SIP服务器的信息,并创建一个SIP用户。 3. 建立连接:与SIP服务器建立WebSocket连接,以便进行通信。 4. 监听事件:监听SIP服务器发送的各种事件,比如呼叫建立、通话结束等。 5. 呼叫:在网页上输入对方的电话号码,点击呼叫按钮,发送呼叫请求给SIP服务器,并等待对方接听。 6. 通话:如果对方接听了呼叫请求,就可以进行实时通话。可以使用网页上的声音输入、输出设备,与对方进行语音通话。 通过jssip demo,我们可以了解到如何使用jssip库来开发基于Web的实时通信应用程序。这个demo提供了一个简单、易于理解的示例,可以作为我们开发自己应用程序的参考。无论是开发VoIP电话应用还是实时视频通话应用,jssip demo都是一个很好的起点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuelong-ming

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值