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

@kookapp/voice-bot-sdk

v0.1.0

Published

Node bot adapter for KOOK WebRTC voice channels

Readme

@kookapp/voice-bot-sdk

voice-bot-sdk 是 KOOK 语音机器人的 Node.js 适配层。它基于 @kookapp/voice-rtc-core 连接语音频道,并通过可注入的 WebRTC 实现提供 PCM 输入和输出。

本包不内置 wrtc 等原生依赖。不同 Node.js 版本、操作系统和部署环境需要选择不同的 WebRTC 实现,因此由机器人项目自行安装和注入。

功能

  • 使用 QuickJoin 和 InitSpeaking 加入 KOOK 语音频道。
  • 默认以只收听模式建立会话,之后可升级为真实音频 Producer。
  • 通过 NodeAudioSource 把 PCM 数据发送到频道。
  • 通过 NodeAudioSink 接收远端 PCM 数据。
  • 自动安装并在关闭时恢复 mediasoup 所需的 WebRTC 全局对象。
  • ESM、CommonJS 和 TypeScript 类型声明。

环境要求

  • Node.js 20 或更高版本。
  • 一个兼容 wrtc API 的 WebRTC 实现。
  • WebRTC 实现至少提供 RTCPeerConnectionMediaStream
  • 使用 PCM 输入输出时,还要提供 nonstandard.RTCAudioSourcenonstandard.RTCAudioSink

安装

pnpm add @kookapp/voice-bot-sdk

再安装项目选择的 WebRTC 实现。例如:

pnpm add wrtc

wrtc 这里只是接口示例。正式部署前必须确认该实现支持目标 Node.js 版本、操作系统和 CPU 架构。

最小接收示例

import wrtc from 'wrtc'
import NodeBotClient from '@kookapp/voice-bot-sdk'

const channelId = 'channel-123'
const botUid = 'bot-456'

const bot = new NodeBotClient({
  webrtc: wrtc,
  uid: botUid,
  joinId: `bot-${Date.now()}-${channelId}`,
  autoAudioSink: true,
})

bot.on('audio-data', ({ peerId, consumerId, data }) => {
  console.log('收到 PCM', {
    peerId,
    consumerId,
    sampleRate: data.sampleRate,
    channelCount: data.channelCount,
    samples: data.samples.length,
  })
})

bot.on('peer-join', (peer) => console.log('成员加入', peer))
bot.on('peer-leave', (peer) => console.log('成员离开', peer))
bot.on('error', (error) => console.error('RTC 错误', error))

await bot.connect({
  channelId,
  tokenResponse,
  listenOnly: true,
  muted: true,
  deafened: false,
})

connect() 默认 listenOnly: true。SDK 会通过静音音轨完成 InitSpeaking,使机器人可以稳定接收远端 Consumer。

Token 使用

connect() 可以直接接收 KOOK Token 响应:

await bot.connect({
  channelId: 'channel-123',
  tokenResponse: {
    gateway_url: 'wss://gateway.example.com/path?token=...',
    iceServers: [
      {
        urls: 'turn:turn.example.com',
        username: 'user',
        credential: 'pass',
      },
    ],
    iceTransportPolicy: 'all',
    rtc_config: {},
  },
})

也可以在业务层提前归一化:

import { normalizeVoiceTokenConfig } from '@kookapp/voice-bot-sdk'

const tokenConfig = normalizeVoiceTokenConfig(tokenResponse)

await bot.connect({
  channelId: 'channel-123',
  tokenConfig,
})

不要记录完整 gateway_url,其中通常包含临时鉴权信息。

发送 PCM 音频

const source = bot.createAudioSource({
  sampleRate: 48000,
  bitsPerSample: 16,
  channelCount: 1,
  frameDurationMs: 10,
})

await bot.publishAudioSource(source, {
  stopTracks: false,
})

// 48 kHz、单声道、10 ms 对应 480 个采样点
const frame = new Int16Array(480)
source.push(frame, {
  sampleRate: 48000,
  bitsPerSample: 16,
  channelCount: 1,
  numberOfFrames: 480,
})

push() 不负责调度播放节奏。调用方必须按真实时间持续推送 PCM 帧,例如每 10 ms 推送一帧,否则远端会出现卡顿、加速或断续。

PCM 数据要求:

  • Int16Array 或可转换为 Int16Array 的数据。
  • 有符号 16 位 PCM。
  • 多声道数据按帧交错排列。
  • numberOfFrames 是每声道帧数,不是数组总长度。

停止发布:

await bot.unpublishTrack()
source.close()

接收 PCM 音频

autoAudioSinktrue 时,SDK 会为每个远端音轨自动创建 NodeAudioSink,并派发 audio-data

bot.on('audio-data', ({ peerId, data }) => {
  pcmRecorder.write(peerId, data.samples, {
    sampleRate: data.sampleRate,
    channelCount: data.channelCount,
  })
})

需要自行管理 Sink 时:

const bot = new NodeBotClient({
  webrtc: wrtc,
  uid: botUid,
  joinId,
  autoAudioSink: false,
})

bot.on('audio-track', ({ peerId, track }) => {
  const sink = bot.createAudioSink(track)
  sink.on('data', (frame) => {
    console.log(peerId, frame.samples)
  })
})

手动创建的 Sink 也必须由调用方调用 close()

复用 NodeWebRtcRuntime

多个 Bot 使用同一个 WebRTC 实现时,可以显式创建 Runtime:

import { NodeBotClient, NodeWebRtcRuntime } from '@kookapp/voice-bot-sdk'

const runtime = new NodeWebRtcRuntime(wrtc, {
  handlerName: 'Chrome111',
})

const botA = new NodeBotClient({ runtime, uid: 'bot-a', joinId: 'join-a' })
const botB = new NodeBotClient({ runtime, uid: 'bot-b', joinId: 'join-b' })

Runtime 会对全局 WebRTC 对象做引用计数。最后一个客户端关闭后,会恢复进程原有的全局对象。

connect 参数

| 参数 | 默认值 | 说明 | | --- | --- | --- | | channelId / roomId | 构造时的 joinId | KOOK 频道或 RTC 房间 ID | | tokenResponse | 无 | 原始 Token 接口响应 | | tokenConfig | 无 | 已归一化的 Token 配置 | | gatewayUrl / gateway_url | Token 中的地址 | Protoo WebSocket 地址 | | iceServers | Token 中的配置 | TURN/STUN 配置 | | iceTransportPolicy | Token 中的策略 | ICE 传输策略 | | forceRelay | Token 中的配置 | 是否强制中继 | | listenOnly | true | 是否使用静音占位音轨加入 | | muted | false | 初始麦克风暂停状态 | | deafened | false | 初始耳机静音状态 |

常用事件

| 事件 | 说明 | | --- | --- | | audio-track | 收到远端音轨;包含自动创建的 sinknull | | audio-data | 自动 Sink 输出的一帧 PCM | | consumer / consumer-close | Core Consumer 生命周期 | | peer-join / peer-leave | 成员变化 | | connection-state-change | RTC 连接状态变化 | | reconnect / disconnect | 服务端重连或断开通知 | | error | 异步错误 |

关闭

try {
  await bot.leave()
} finally {
  bot.close()
}

close() 会关闭自动创建的 Sink、RTC Core 和注入的全局 WebRTC 环境。进程退出前还应关闭业务侧创建的音频源、文件句柄和定时器。

不包含的能力

  • 不负责申请 KOOK Bot Token 或频道 Token。
  • 不内置音频解码器、FFmpeg、音乐播放队列或混音器。
  • 不提供浏览器设备 API 和 AI 降噪。
  • 不保证任意 wrtc 分支都兼容,必须进行目标环境端到端验证。

测试、构建和打包

pnpm --filter @kookapp/voice-bot-sdk test
pnpm --filter @kookapp/voice-bot-sdk typecheck
pnpm --filter @kookapp/voice-bot-sdk build
pnpm --filter @kookapp/voice-bot-sdk dev
pnpm --dir packages/voice-bot-sdk pack --pack-destination packs

dev 会持续构建 ESM、CommonJS 和类型声明。Node 消费项目可以配合 node --watch 或进程管理器在产物变化后重启。