bl-trtc-callkit-vue
v1.1.3
Published
基于腾讯云 TRTC SDK 开发的 Vue 3 通话组件,支持一对一音视频通话、网络质量监测、动态视频质量调整等功能。 (内部使用、userSig不安全) ## 安装
Readme
bl-trtc-callkit-vue
基于腾讯云 TRTC SDK 开发的 Vue 3 通话组件,支持一对一音视频通话、网络质量监测、动态视频质量调整等功能。 (内部使用、userSig不安全)
安装
npm install bl-trtc-callkit-vue使用示例
基本用法
<script setup>
import { ref, onMounted } from 'vue'
import BlTRTCCallKit from 'bl-trtc-callkit-vue';
const callKitRef = ref(null)
const targetId = ref('')
const localUserId = ref(String(Math.floor(Math.random() * 900 + 100)))
const remoteUsers = ref([])
function onNotify({ type, text }) {
showToast(text, type)
}
// 处理远端用户状态变化
function onRemoteUserStatusChange({ userId, action, userList }) {
console.log('远端用户状态变化:', { userId, action, userList })
if (action === 'enter') {
// 检查用户是否已在列表中
const existingIndex = remoteUsers.value.findIndex(u => u.userId === userId)
if (existingIndex === -1) {
remoteUsers.value.push({
userId,
status: 'online',
})
} else {
// 更新现有用户状态
remoteUsers.value[existingIndex].status = 'online'
}
} else if (action === 'exit') {
const existingIndex = remoteUsers.value.findIndex(u => u.userId === userId)
if (existingIndex !== -1) {
remoteUsers.value[existingIndex].status = 'offline'
}
}
}
onMounted(() => {
// 初始化:传入 userId、sdkAppId、sdkSecretKey
callKitRef.value.init({
userId: localUserId.value,
sdkAppId: "YOUR_SDK_APP_ID",
sdkSecretKey: "YOUR_SDK_SECRET_KEY",
profile: "1080p"
})
})
// 主动呼叫某用户
function callSomeone() {
callKitRef.value.handleCall(targetId.value)
}
function handleRemoteUserClick(user) {
if (user.status === 'online') {
callKitRef.value.handleCall(user.userId)
} else {
alert('对方已离线')
}
}
const toastList = ref([]);
// 生成唯一ID
function generateId() {
return Date.now() + Math.random()
}
// 显示 Toast
function showToast(text, type = 'info') {
const id = generateId()
const toast = {
id,
text,
type
}
toastList.value.push(toast)
// 3秒后自动移除
setTimeout(() => {
const index = toastList.value.findIndex(item => item.id === id)
if (index !== -1) {
toastList.value.splice(index, 1)
}
}, 3000)
}
// 获取图标
function getIcon(type) {
switch (type) {
case 'error':
return '❌'
case 'info':
default:
return 'ℹ️'
}
}
</script>
<template>
<div class="wrapper">
<div style="font-size: 1rem;">当前 userId:<strong>{{ localUserId }}</strong></div>
<div class="remote-user-call">
<input v-model="targetId" placeholder="输入要呼叫的用户ID" style="height: 36px;" />
<button @click="callSomeone" style="height: 36px;padding: 0 8px;">呼叫 {{ targetId || '目标用户' }}</button>
</div>
<div style="margin-top:12px; border:1px solid #ccc; padding:10px; border-radius:4px;">
<h4>远端用户列表</h4>
<ul>
<li v-for="user in remoteUsers" :key="user.userId"
:style="{ color: user.status === 'online' ? 'green' : 'gray' }" @click="handleRemoteUserClick(user)">
{{ user.userId }} ({{ user.status === 'online' ? '在线' : '离线' }})
</li>
</ul>
</div>
<BlTrtcCallkit ref="callKitRef" @notify="onNotify" @remote-user-status-change="onRemoteUserStatusChange" />
<!-- Toast 通知组件 -->
<div class="toast-container">
<transition-group name="toast">
<div v-for="toast in toastList" :key="toast.id" :class="['toast-item', `toast-${toast.type}`]">
<span class="toast-icon">{{ getIcon(toast.type) }}</span>
<span class="toast-text">{{ toast.text }}</span>
</div>
</transition-group>
</div>
</div>
</template>
<style scoped>
.wrapper {
max-width: 1200px;
margin: 0 auto;
padding: 12px;
display: flex;
flex-direction: column;
gap: 8px;
box-sizing: border-box;
}
.wrapper .remote-user-call {
margin-top: 12px;
display: flex;
gap: 8px;
align-items: center;
}
.wrapper ul {
margin-top: 12px;
}
.wrapper li {
height: 32px;
display: flex;
align-items: center;
background: #eee;
border-radius: 4px;
padding: 6px 8px;
margin-bottom: 12px;
cursor: pointer;
}
.toast-container {
position: fixed;
top: 20px;
right: 20px;
z-index: 9999;
display: flex;
flex-direction: column;
gap: 10px;
max-width: 300px;
}
.toast-item {
display: flex;
align-items: center;
padding: 12px 16px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
animation: slideInRight 0.3s ease;
min-width: 250px;
max-width: 100%;
}
.toast-info {
background-color: #e3f2fd;
color: #1976d2;
border-left: 4px solid #2196f3;
}
.toast-error {
background-color: #ffebee;
color: #d32f2f;
border-left: 4px solid #f44336;
}
.toast-icon {
margin-right: 10px;
font-size: 18px;
}
.toast-text {
flex: 1;
word-break: break-word;
}
/* 动画效果 */
.toast-enter-active,
.toast-leave-active {
transition: all 0.3s ease;
}
.toast-enter-from {
opacity: 0;
transform: translateX(100%);
}
.toast-leave-to {
opacity: 0;
transform: translateX(100%);
position: absolute;
}
@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
</style>API 说明
组件方法
| 方法名 | 参数 | 说明 |
|-------|------|------|
| init | { userId: string, sdkAppId: number, sdkSecretKey: string, profile?: string } | 初始化组件,传入用户 ID、SDK App ID、SDK 密钥和可选的视频分辨率(默认1440p,支持360p、720p、1080p、1440p) |
| handleCall | targetId: string | 发起呼叫,传入目标用户 ID |
| show | 无 | 显示通话组件 |
| hide | 无 | 隐藏通话组件 |
| hangup | 无 | 挂断通话 |
| setVideoProfile | profile: string | 设置视频分辨率(支持360p、720p、1080p、1440p) |
组件事件
| 事件名 | 回调参数 | 说明 |
|-------|----------|------|
| notify | { type: string, text: string } | 通知事件,包含通知类型和内容 |
| remote-user-status-change | { userId: string, action: string, userList: string[] } | 远程用户状态变化事件,action 为 'enter' 或 'exit' |
组件属性
| 属性名 | 类型 | 默认值 | 说明 |
|-------|------|--------|------|
| visible | boolean | false | 控制组件显示隐藏 |
| inCall | boolean | false | 是否已接通通话 |
功能特性
- 音视频通话:仅支持一对一音视频通话
- 网络质量监测:实时监测网络质量,动态调整视频质量
- 设备控制:支持开启/关闭麦克风、摄像头
- 扬声器控制:支持切换扬声器/听筒
- 动态视频质量调整:根据网络状况自动调整视频分辨率
注意事项
- 使用前需获取腾讯云 TRTC 服务的 SDK App ID 和 SDK 密钥
- 确保在 HTTPS 环境下使用,否则可能无法正常访问摄像头和麦克风
- 首次使用时需要用户授权摄像头和麦克风权限
- 建议在组件销毁前调用
hangup方法关闭所有媒体流
