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

virtual-human-cf

v1.4.0

Published

Vue3 Digital Human Component Package by cf

Readme

Virtual Human Component Framework (virtual-human-cf)

一个基于 Vue 3 的虚拟数字人组件库,用于展示和控制数字人视频,并处理相关音频和交互事件。

特性

  • 支持数字人视频播放控制
  • WebSocket 实时通信
  • 音频播放处理
  • 事件监听和响应
  • 暗黑模式支持
  • 响应式设计

更新日志

1.4.0

  • 新增VirtualHumanEventAdapter组件对外暴露pause、resume、stop方法
  <VirtualHumanEventAdapter
    v-if="activeScreenClientId"
    @controlEvent="onControlEvent"
    ref="adapterRef"
  />
 const adapterRef = ref(null);

  // 底部有使用demo,这里不重复
 // 暂停播放
 adapterRef.value.pause().then(() => {}).catch(() => {});
 // 恢复播放
 adapterRef.value.resume().then(() => {}).catch(() => {});
 // 停止播放
 adapterRef.value.stop().then(() => {}).catch(() => {});

1.2.0

  • 新增VirtualHumanEventAdapter组件controlEvent事件,用于数字人播放周期控制指令通知
  <VirtualHumanEventAdapter
    v-if="activeScreenClientId"
    @controlEvent="onControlEvent"
  />
  const onControlEvent = (event) => {
    console.log(event);
    // play 初次开始播放
    // resume 恢复播放
    // pause 暂停播放
    // stop 停止播放
    // tts_complete 文本转语音完成,不代表本地播放完成
  }

1.0.10

  • 新增VirtualHumanPersona组件styles属性,用于控制视频容器 宽高 绝对定位位置等

安装

npm install virtual-human-cf

使用方法

全局注册

import { createApp } from "vue";
import App from "./App.vue";
import VirtualHumanCF from "virtual-human-cf";

const app = createApp(App);
app.use(VirtualHumanCF);

按需导入

import {
  VirtualHumanPersona,
  VirtualHumanEventAdapter,
} from "virtual-human-cf";

组件说明

VirtualHumanPersona

数字人视频展示组件,负责视频播放和状态控制。

Props

| 属性 | 类型 | 默认值 | 必填 | 说明 | | -------------- | ------- | ------ | ---- | ------------------------------------------------- | | videoSrc | String | - | 是 | 视频源 URL | | visible | Boolean | true | 否 | 是否可见 | | isPlaying | Boolean | false | 否 | 是否正在播放 | | muted | Boolean | true | 否 | 是否静音 | | isDark | Boolean | false | 否 | 是否暗黑模式 | | screenClientId | String | - | 否 | 屏幕客户端 ID | | wsUrl | String | - | 否 | WebSocket 连接地址 | | styles | Object | - | 否 | 组件样式,包含 width、height、left、bottom 等属性 |

Events

| 事件名 | 说明 | 回调参数 | | ---------------- | ------------ | ----------------- | | update:isPlaying | 播放状态变更 | 播放状态(Boolean) | | update:visible | 可见性变更 | 可见状态(Boolean) | | ended | 播放结束 | - |

示例

<template>
  <VirtualHumanPersona
    :video-src="videoUrl"
    :is-playing="playing"
    :muted="true"
    :is-dark="false"
    :screen-client-id="clientId"
    :ws-url="websocketUrl"
    :styles="styles"
    @update:isPlaying="onPlayingChange"
    @ended="onEnded"
  />
</template>

<script setup>
import { ref } from "vue";
import { VirtualHumanPersona } from "virtual-human-cf";

const videoUrl = ref("https://example.com/video.mp4");
const playing = ref(false);
const clientId = ref("screen-123");
const websocketUrl = ref("ws://localhost:8080/ws");
const styles = ref({
  width: "400px",
  height: "500px",
  left: "16px",
  bottom: "16px",
});
const onPlayingChange = (isPlaying) => {
  console.log("播放状态改变:", isPlaying);
};

const onEnded = () => {
  console.log("播放结束");
};
</script>

VirtualHumanEventAdapter

数字人事件适配器组件,负责处理 WebSocket 消息、音频播放和各种交互事件。

Props

| 属性 | 类型 | 默认值 | 必填 | 说明 | | -------------- | ------ | ------ | ---- | ------------------ | | screenClientId | String | - | 是 | 屏幕客户端 ID | | wsUrl | String | - | 是 | WebSocket 连接地址 |

Events

| 事件名 | 说明 | 回调参数 | | ---------------- | ------------------------------------ | -------- | | connected | WebSocket 连接成功 | - | | eventNotifaction | 自定义事件接收器 | 载荷数据 | | end | 数字人对话结束 | 载荷数据 | | pause | 暂停播放 | 载荷数据 | | error | 错误事件 | 错误信息 | | playComplete | 播放完成,数字人对话结束,关闭数字人 | - | | controlEvent | 数字人控制事件 | 载荷数据 |

refs

| 方法名 | 说明 | 回调参数 | | ------ | -------- | -------- | | pause | 暂停播放 |Promise | | resume | 恢复播放 |Promise | | stop | 停止播放 |Promise |

// eventNotifaction 载荷数据
{

    "type": "send_event",
    // 自定义事件名称
    "event": "heightlight",
    // 自定义事件参数
    "params": {
        "domid": "wrap-1"
    }
}
// controlEvent String 载荷数据
"play" | "resume" | "pause" | "stop" | "tts_complete"
play 初次开始播放
resume 恢复播放
pause 暂停播放
stop 停止播放
tts_complete 文本转语音完成,不代表本地播放完成

示例

<template>
  <VirtualHumanEventAdapter
    :screen-client-id="clientId"
    :ws-url="websocketUrl"
    @connected="onConnected"
    @eventNotifaction="onEventNotifaction"
    @playComplete="onPlayComplete"
    @controlEvent="onControlEvent"
    @end="onEnd"
    @error="onError"
    ref="adapterRef"
  >
    <div>其他内容</div>
  </VirtualHumanEventAdapter>
</template>

<script setup>
import { VirtualHumanEventAdapter } from 'virtual-human-cf';

const clientId = 'screen-123';
const websocketUrl = 'ws://localhost:8080/ws';

const onConnected = () => {
  console.log('WebSocket 连接成功');
};

const onEventNotifaction = (payload) => {
  console.log('自定义事件接收:', payload);
};

const onPlayComplete = () => {
  console.log('播放完成');
};

const onEnd = (payload) => {
  console.log('对话结束:', payload);
};

const onError = (error) => {
  console.error('错误:', error);
};

const adapterRef = ref(null);
const controlFunc = () => {
  // 暂停播放
  adapterRef.value.pause().then(res => {
    // res boolean true 暂停成功 false 暂停失败
  }).catch((error) => {
    console.error('暂停播放失败:', error);
  });
  // 恢复播放
  adapterRef.value.resume().then(res => {
    // res boolean true 恢复成功 false 恢复失败
  }).catch((error) => {
    console.error('恢复播放失败:', error);
  });
  // 停止播放
  adapterRef.value.stop().then(res => {
    // res boolean true 停止成功 false 停止失败
  }).catch((error) => {
    console.error('停止播放失败:', error);
  });
}
</script>

完整示例

以下是一个结合两个组件使用的完整示例:

<template>
  <div class="container">
    <VirtualHumanPersona
      :video-src="videoUrl"
      :visible="personaVisible"
      :is-playing="isPlaying"
      :muted="true"
      :is-dark="isDarkMode"
      :screen-client-id="activeScreenClientId"
      :ws-url="websocketUrl"
      :styles="styles"
      @update:isPlaying="onPersonaPlayingUpdate"
      @update:visible="onPersonaVisibleUpdate"
      @ended="onVideoEnded"
    />

    <VirtualHumanEventAdapter
      :screen-client-id="activeScreenClientId"
      :ws-url="websocketUrl"
      @connected="onConnected"
      @eventNotifaction="onEventNotifaction"
      @controlEvent="onControlEvent"
      @end="onEnd"
      @error="onError"
      @playComplete="onPlayComplete"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { VirtualHumanPersona, VirtualHumanEventAdapter } from 'virtual-human-cf';

const videoUrl = ref('/path/to/digital-human-video.mp4');
const isPlaying = ref(false);
const isDarkMode = ref(false);
const personaVisible = ref(true);
const activeScreenClientId = ref('screen-123');
const websocketUrl = ref('ws://localhost:8080/ws');

const onConnected = () => {
  console.log('连接到 WebSocket 服务器');
};

const onVideoEnded = () => {
  console.log('视频播放结束');
};

const onControlEvent = (action: string) => {
  console.log('获取到控制指令:', action);
};


const onEnd = (payload) => {
  console.log('数字人交互结束:', payload);
  isPlaying.value = false;
};

const onEventNotifaction = (payload) => {
  console.log('自定义事件接收:', payload);
};

const onPlayComplete = () => {
  console.log('播放完成');
  // 关闭数字人
  personaVisible.value = false;
}

const onError = (error) => {
  console.error('发生错误:', error);
};
</script>

开发

# 安装依赖
npm install

# 构建项目
npm run build

发布

在发布之前,请确保按照 npm 包发布安全与流程规范操作:

  1. 确保项目已通过 npm run build 成功构建
  2. 检查 package.json 中版本号是否更新
  3. 登录 npm 账户并使用令牌认证
  4. 确保 registry 指向官方源

许可证

MIT