npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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 | 是否已接通通话 |

功能特性

  1. 音视频通话:仅支持一对一音视频通话
  2. 网络质量监测:实时监测网络质量,动态调整视频质量
  3. 设备控制:支持开启/关闭麦克风、摄像头
  4. 扬声器控制:支持切换扬声器/听筒
  5. 动态视频质量调整:根据网络状况自动调整视频分辨率

注意事项

  1. 使用前需获取腾讯云 TRTC 服务的 SDK App ID 和 SDK 密钥
  2. 确保在 HTTPS 环境下使用,否则可能无法正常访问摄像头和麦克风
  3. 首次使用时需要用户授权摄像头和麦克风权限
  4. 建议在组件销毁前调用 hangup 方法关闭所有媒体流