组件/VoiceClip 语音条

VoiceClip 语音条

可播放、可拖动定位的语音消息胶囊

已验证自 0.8.0

安装

pnpm add @talex-touch/tuffex
EXAMPLE.TYPESCRIPT
import { TxVoiceClip } from '@talex-touch/tuffex/voice-clip'
import '@talex-touch/tuffex/voice-clip/style.css'
import '@talex-touch/tuffex/base.css' // 设计令牌与重置样式,全应用引入一次

用法

基础

传入录音地址和已知时长;胶囊随时长变宽,同一页面同时只播放一条。

示例加载中...

波形来源与状态

已有电平数据时传 peaks,组件不再解码录音;没有 src 时是不可用态。

示例加载中...

自定义颜色

在任一祖先上设置 --tx-voice-clip-* 变量,里面的语音条都会读到。

示例加载中...

最佳实践

  • 已知时长就传 durationMs:元素读到文件之前,胶囊已经是正确的宽度和时长,加载后不会跳动。
  • 宿主已有电平数据(如听写过程中的电平帧)时传 peaks,省掉一次读取和解码。
  • 远程录音要传 peaks:组件只会再读一次本地录音(blob:、data:、tfile:、file:)。
  • 本地化四个文案属性;读屏通过滑块的 aria-valuetext 读出位置,播放键的名称随状态切换。

API 参考

属性

属性类型默认值说明
srcstring''录音地址;为空或加载失败时进入不可用态。
durationMsnumber-已知时长(毫秒);宽度按它算,元素读到时长后时间文字以元素为准。
peaksreadonly number[]-0–1 的振幅,按容得下的条数重采样;不传时解码本地录音。
disabledbooleanfalse禁用播放与定位;播放中被禁用会暂停。
playLabelstring'Play voice message'播放键的可访问名称。
pauseLabelstring'Pause voice message'播放中播放键的可访问名称。
seekLabelstring'Playback position'波形滑块的可访问名称。
unavailableLabelstring'Recording unavailable'不可用时代替波形显示的文字。

事件

事件参数说明
play-开始播放。
pause-暂停,包括被另一条接替和播放到结尾。
ended-播放到结尾,随后回到开头。
errorerror: unknown录音无法加载(MediaError)或播放被拒绝;被打断的开始不算。

暴露方法

方法签名说明
play() => Promise<void>从当前位置播放;已在结尾时从头开始。
pause() => void暂停。
toggle() => void播放或暂停。

CSS 变量

变量默认值说明
--tx-voice-clip-bg--tx-fill-color-light胶囊底色。
--tx-voice-clip-control-bg--tx-bg-color播放键底色。
--tx-voice-clip-control-ink--tx-text-color-primary播放键图标颜色。
--tx-voice-clip-accent--tx-color-primary已播放部分的波形。
--tx-voice-clip-track主文字色的 28%未播放部分的波形。
--tx-voice-clip-ink--tx-text-color-regular时长与不可用文字。
--tx-voice-clip-focus--tx-color-primary焦点环。
  • 这些变量不在根元素上声明,写在组件或任一祖先上都会生效。

概述

  • 播放键、波形、时长排成 36px 高的胶囊;宽度随时长按平方根增长,140px 起,60 秒及以上为 300px,条数随波形的实际宽度变化。
  • 静止时显示四舍五入的总时长(不足一秒记 1 秒);播放中和暂停在中途时,用它减去已播放的整秒数倒数,开始播放时数字不跳;播放结束后回到开头,重新显示总时长。
  • 同一页面同时只播放一条,新开始的一条会暂停正在播放的那条。
  • 波形是 role="slider":点击或拖动定位,←/→、↑/↓ 步进 1 秒,PageUp/PageDown 步进总时长的 10%,Home/End 跳到头尾;定位不会自动开始播放。
  • 传入 peaks 时直接绘制,否则解码本地录音,解码完成前或失败时是平直轨道;src 为空或加载失败时播放键禁用,波形换成 unavailableLabel。
  • 按压缩放和波形高度过渡只在 prefers-reduced-motion: no-preference 下出现,播放进度始终更新;按物理方向从左往右绘制,从右到左的页面不会镜像。

技术实现

  • 用隐藏的 <audio preload="metadata"> 播放;播放中由 rAF 读取 currentTime(窗口被节流时由元素的 timeupdate 兜底),写入 --tx-voice-clip-progress 裁切叠在上层的强调色波形,不逐帧重渲染。
  • 波形用 8 kHz 的 OfflineAudioContext 解码:按 96 段求 RMS,从最安静的一成拉伸到最响的一段,再按条取平均、让最高的一条撑满高度;按地址缓存最近 24 条。
  • 源码:packages/tuffex/packages/components/src/voice-clip/。
查看源码
packages/tuffex/packages/components/src/voice-clip/index.ts

使用场景

  • 对话里的语音消息:发送前后都可以回放用户录下的语音。
  • 听写结果旁的原始录音,用来重新识别或直接发送。

相关组件