当前位置: 首页 > 工具软件 > JsSIP > 使用案例 >

JSSIP踩坑记

孔海超
2023-12-01

前言

事情经过是这样的,公司最近准备搞一个移动端的项目,里面需要集成打电话功能(就是可以从页面直接打电话类型微信语音的感觉),最先考虑到是移动端项目(h5)就采用的uniapp,但电话播出去后却出现了h5无声音,但被叫端有声音。其中使用到audio 的srcObject属性,经自己实验得知uniapp的audio没有srcObject属性,故无法使用uniapp来实现该功能。我将源码复制到vue项目中,就不存在单通的问题。故决定将uniapp项目调整为vue2 + vantui的h5项目。贴上关键代码,方便日后有需求可以查看
JSSIP版本:“jssip”: “^3.3.11”
该代码不涉及接听电话

<template>
  <div>
    <button @click="startCall">拨打</button>
    <audio id="audioElement"></audio>
  </div>
</template>
<script>
import JsSIP from "jssip";
export default {
  data() {
    return {
      ua: null,
    };
  },
  created() {
    this.handleUA();
  },
  methods: {
    startCall() {
      this.ua.call("phonenum", your_options);
    },
    //初始化配置
    initConfig() {
      // Create our JsSIP instance and run it:
      const socket = new JsSIP.WebSocketInterface('your_fs_wss_url’);
      const configuration = {
        sockets: [socket],
        uri: `sip:${your mobile}@${your_fs_register_url}`,
        authorization_user: 'your mobile',
        password: this.userInfo.mobile,
        // WebSocket重新连接调度之间的最大间隔(秒)。默认值是30。
        connection_recovery_max_interval: 300,
        // WebSocket重新连接尝试之间的最小间隔(秒)。默认值是2。
        connection_recovery_min_interval: 10,
        // String 注册到fs显示的url
        contact_uri: `sip:${your mobile}@${your_fs_register_url};transport=wss`,
        // 外显
        display_name: this.org.id,
        // 来电后,120秒内未接听,将会拒绝.默认60s
        no_answer_timeout: 120,
        // 会话计时器,默认true
        session_timers: false,
        // 用于刷新会话计时器的SIP方法。有效值是UPDATE或INVITE。默认值是UPDATE。
        session_timers_refresh_method: "invite",
        // 是否应该在启动时自动注册.默认true
        register: true,
        // 注册过期时间(秒) 默认值是600。
        register_expires: 7200,
        //  User-Agent header中的值,默认是JsSIP
        user_agent: "your_user_agent",
        registrar_server: `sip:${your_fs_register_url}`,
      };
      this.ua = new JsSIP.UA(configuration);
    },
    handleUA() {
      this.initConfig();
      this.ua.start();

      if (!this.ua.isRegistered()) {
        //未注册的情况下
        this.ua.register();
      }

      if (this.ua.isConnected()) {
        console.log("软电话已连接");
      }

      this.ua.on("registered", (data) => {
        console.log("软电话认证成功");
      });

      this.ua.on("registrationFailed", (data) => {
        console.log("软电话认证失败");
      });

      // 新来会话
      this.ua.on("newRTCSession", function (data) {
        let originator = data.originator;
        let session = data.session;
        //连接中
        session.on("connecting", (data) => {
          console.log("建立连接中");
        });
        // 连接已接受
        session.on("accepted", () => {
          console.log("连接已接受");
        });

        // 接通,在这一步可以处理音频播放
        // 接通并不代表对方已经接受,接通代表 滴 滴 滴
        session.on("confirmed", () => {
          console.log("接通中");
          const audioElement = document.getElementById("audioElement");
          audioElement.autoplay = true;
          const stream = new MediaStream();
          const receivers = session.connection?.getReceivers();
          if (receivers)
            receivers.forEach((receiver) => stream.addTrack(receiver.track));
          console.log("audioElement.srcObject2", "srcObject" in audioElement);
          audioElement.srcObject = stream;
          // 最后都要播放
          audioElement.play();
        });

        // 结束
        session.on("ended", () => {
          console.log("通话结束");
        });

        // 失败
        session.on("failed", () => {
          console.log("失败");
        });

        // 手动让打孔结束,最多4次,有时候等待时间会很长
        let iceCandidateCount = 0;
        session.on("icecandidate", (data) => {
          if (iceCandidateCount++ > 4) data.ready();
        });
      });
    },
  },
};
</script>

 类似资料: