
Product
Introducing Repository Access Permissions and Custom Roles
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.
janus-manager
Advanced tools
janus-managerAn adapter manager for Janus client library.
Janus 原文档地址可参考
基于 janus-manager Vue实现的 janus-connector 组件库可用于快速构建通讯应用。
npm install janus-manager --save
import JanusManager from "janus-manager";
const manager = new JanusManager();
// 查看当前版本
const version = JanusManager.version;
// 传入服务器地址,进行服务连接初始化,返回连接上下文对象
const context = await manager.init({
server: this.server,
// 设置连接超时时间,默认6000,60s
longPollTimeout: 60000,
// iceServers config
/* iceServers: [{
"urls": ["turn:xxxxx:xxxx"],
"username": "username",
"credential": "credential"
}]*/
}).catch((err) => {
// 可处理兼容性及连接异常错误
throw err
});
handle 插件配置,通过已建立的连接通道,将插件与通过建立关联,建立插件状态Session// 创建一个可用于拨打电话的插件处理器,将插件与服务器建立关联,返回插件处理器对象,并进行消息监听
const handler = await manager.createCallHandle({
// plugin options
});
handler.on("message", (msg, jsep) => {
// handle events.
// eg: registered / hangup / accepted / progress / hangup | incomingcall
// 处理接通事件
const event = msg?.result?.event;
if (event === "progress" || event === "accepted") {
jsep && handler.handleRemoteJsep(jsep);
}
}
// 处理音频流播放事件
handler.on("remotestream", (stream) => {
manager.attachMediaStream(remoteMediaDom, stream);
});
webrtc通讯能力handler.sendMessage("register", {
authuser: this.authuser,
proxy: this.sipServer,
secret: this.password,
username: this.username,
display_name: this.displayname,
});
// 拨打电话,通话地址 格式: sip:{phone}@ip:port
handler.makeCall(uri);
// 发送数字键盘命令信息
// 参数: tones - DTMF tones
handler.sendDtmf({ tones: '1'});
// 挂断电话
handler.hangup();
// 接听电话 - 监听 incomingcall 事件
handler.on("message", (msg, jsep) => {
const event = msg?.result?.event;
if (event === "incomingcall") {
handler.answerCall(jsep, { audio: true });
}
}
// 拒接电话
handler.declineCall();
// 呼出端禁用音频输入
handler.muteAudio();
// 呼出端重新启用音频输入
handler.unmuteAudio();
// 判断呼出端是否启用音频输入,返回boolean
handler.isAudioMuted(); // true/false
// 等同于 manager.destory();
context.destory();
const isSupported = manager.isSupportedUserMedia();
可用于在通话前判断当前系统兼容性,是否支持音视频调用
在如下方法调用时,注意为异步操作,同时根据逻辑决定是否需要捕获异常,若不catch,执行错误时,会默认抛出异常
await manager.init({ }).catch()
await manager.createCallHandle({ }).catch()
await handler.sendMessage({ }).catch()
// 拨打电话
await handler.makeCall({ }).catch()
// 挂断通话
await handler.hangup({ }).catch()
// 拒绝来电
await handler.declineCall({ }).catch()
// 接听来电
await handler.answerCall({ }).catch()
Promise类型的方法调用异常,都可使用 catch 来捕获const context = await manager.init({
server: this.server,
// 设置连接超时时间,默认6000,60s
longPollTimeout: 60000,
})
.catch(error => {
// 可处理兼容性及连接异常错误
});
context.error = (err: Error) => {
// 一般网络连接超时,可在此处处理
}
managercontextmanager创建业务操作对象handlerhandler进行通话操作(可多次调用相关方法)context.destory 或 manager.destory以上操作除对
handler对象进行相关操作外,其他流程只需要执行一次。
麦克风权限
android.permission.RECORD_AUDIO和android.permission.MODIFY_AUDIO_SETTINGS权限AVAudioSession.sharedInstance().recordPermission 获取麦克风权限音视频自动播放
webView.getSettings().setMediaPlaybackRequiresUserGesture(false)WKWebViewConfiguration().mediaTypesRequiringUserActionForPlayback 根据客户端使用语言或版本设置为 []或 WKAudiovisualMediaTypeNon 或 false 可参考因系统支持问题,在Android系统版本 >=7.0 及 IOS系统版本 >=14.3才支持在webview中获取系统mediaDevices,才可正常使用库基础功能,
可通过实例方法 isSupportedUserMedia 来检测。
see call-demo
<template>
<div class="page">
<div class="home-container">
<!-- 第一部分 启动服务 -->
<div class="start-btn">
<button type="primary" @click="start">启动服务</button>
</div>
<!-- 第二部分 注册服务配置 -->
<div v-if="running" class="register-infor">
<div>
<input
v-model="sipServer"
type="text"
placeholder="SIP服务器(例如, sip:10.10.10.10:5688)"
/>
</div>
<div>
<input
v-model="username"
type="text"
placeholder="SIP身份(例如,sip:0000@10.10.10.10:5688)"
/>
</div>
<div>
<input
v-model="authuser"
type="text"
placeholder="SIP号(例如, 1001)"
/>
</div>
<div>
<input
v-model="password"
type="password"
placeholder="SIP密码"
/>
</div>
<div>
<input
v-model="displayname"
type="text"
placeholder="显示名称 (例如, 806100)"
/>
</div>
<div class="start-btn">
<button type="primary" @click="connect">建立连接</button>
</div>
</div>
<!-- 第三部分 通话 -->
<div v-if="connected" class="register-infor">
<div>
<input
placeholder="请输入手机号 如: 13688886666"
v-model="phoneNumber"
/>
</div>
<div class="start-btn">
<button
:class="{ primary: !calling, danger: calling }"
type="primary"
@click="callHandler"
>
{{ calling ? "挂断" : "拨打" }}
</button>
</div>
</div>
<!-- 远程音频,接听电话时音频输入,需在 remotestream 事件中处理 -->
<video ref="remoteMedia" class="hide" autoplay playsinline />
</div>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import JanusManager from "janus-manager";
const manager = new JanusManager();
export default Vue.extend({
data() {
return {
running: false,
server: [
"https://servername.com/janus",
"wss://servername.com/janus",
],
sipServer: "sip:server_ip:port", // SIP服务器
username: "sip:user_name@server_ip:port", // SIP身份
authuser: "user", // SIP号
password: "password",
displayname: "", // 显示名称
connected: false,
calling: false,
phoneNumber: "",
};
},
computed: {
callNumber() {
return `sip:${this.phoneNumber}@server_ip:port`;
},
},
methods: {
async start() {
const context = await manager
.init({ server: this.server })
.catch((err) => {
console.error(err);
this.running = false;
throw err;
});
this.context = context;
this.running = true;
},
async connect() {
const handler = await manager.createCallHandle({
mediaState: function (medium, on) {
const status = on ? "started" : "stopped";
const msg = `Janus ${status} receiving our ${medium}`;
console.info("Janus mediaState:", msg);
},
webrtcState: function (on) {
const status = on ? "up" : "down";
const msg = `Janus says our WebRTC PeerConnection is ${status}`;
console.info("Janus webrtcState:", msg);
},
iceState: function (state) {
// state: 'connected' | 'failed'
console.info("iceState", state);
},
});
handler.on("message", (msg, jsep) => {
console.info("message event:", msg?.result?.event, jsep);
const event = msg && msg.result && msg.result.event;
// 注册成功
if (event === "registered") {
this.connected = true;
} else if (event === "hangup") {
// 通话挂断
console.warn("通话已挂断:", msg, jsep);
this.calling = false;
handler.hangup();
} else if (event === "progress" || event === "accepted") {
// 接听
jsep && handler.handleRemoteJsep(jsep);
}
});
handler.on("remotestream", (stream) => {
manager.attachMediaStream(this.$refs.remoteMedia, stream);
});
console.log("connect success....");
this.handler = handler;
handler.sendMessage("register", {
authuser: this.authuser,
proxy: this.sipServer,
secret: this.password,
username: this.username,
display_name: this.displayname,
});
},
callHandler() {
if (this.calling) {
this.handler.hangup();
this.calling = false;
return;
}
if (this.phoneNumber === "") return;
this.handler.makeCall(this.callNumber).catch(error => {
throw error;
});
},
},
beforeDestroy() {
this.context && this.context.destroy();
},
});
</script>
<style lang="less" scoped>
.page {
text-align: center;
padding: 20px;
display: flex;
justify-content: center;
.text-center {
text-align: center;
}
.home-container {
text-align: left;
width: 300px;
.hide {
display: none;
}
input {
height: 32px;
line-height: 32px;
border-radius: 4px;
border: 1px solid #dcdfe6;
padding: 0 15px;
box-sizing: border-box;
width: 100%;
}
button {
border: none;
color: #fff;
padding: 10px 20px;
border-radius: 4px;
background-color: #357bff;
cursor: pointer;
&:focus {
outline: none;
}
&:active {
background-color: #2671fc;
}
}
.primary {
background-color: #357bff;
}
.danger {
background-color: #f8483b;
}
.register-infor {
margin-top: 10px;
> div {
margin-bottom: 10px;
}
}
}
}
</style>
FAQs
An adapter for Janus client library.
The npm package janus-manager receives a total of 22 weekly downloads. As such, janus-manager popularity was classified as not popular.
We found that janus-manager demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.

Product
Socket Firewall blocks malicious VS Code and Open VSX extensions before install, protecting developers from compromised editor marketplaces.