一、事件分类概览
事件类型分类
- 生命周期事件 - 实例创建、销毁
- 音频加载事件 - 音频文件加载过程
- 播放控制事件 - 播放、暂停、停止
- 时间进度事件 - 播放进度变化
- 交互事件 - 用户交互操作
- 音频处理事件 - 音频数据相关
- 插件事件 - 插件特有事件
- 错误事件 - 异常情况
二、事件列表(表格形式)
1. 生命周期事件
| 事件名称 |
触发时机 |
回调参数 |
示例 |
ready |
音频解码完成并准备就绪 |
duration |
wavesurfer.on('ready', (duration) => {}) |
destroy |
实例销毁时 |
无 |
wavesurfer.on('destroy', () => {}) |
init |
初始化完成 |
无 |
wavesurfer.on('init', () => {}) |
2. 音频加载事件
| 事件名称 |
触发时机 |
回调参数 |
示例 |
load |
开始加载音频时 |
url |
wavesurfer.on('load', (url) => {}) |
loading |
加载过程中 |
percent |
wavesurfer.on('loading', (percent) => {}) |
decode |
音频解码开始时 |
无 |
wavesurfer.on('decode', () => {}) |
waveform-ready |
波形数据准备完成 |
无 |
wavesurfer.on('waveform-ready', () => {}) |
audio-process |
Web Audio API 处理音频时 |
time |
wavesurfer.on('audio-process', (time) => {}) |
3. 播放控制事件
| 事件名称 |
触发时机 |
回调参数 |
示例 |
play |
开始播放时 |
无 |
wavesurfer.on('play', () => {}) |
pause |
暂停播放时 |
无 |
wavesurfer.on('pause', () => {}) |
finish |
播放结束时 |
无 |
wavesurfer.on('finish', () => {}) |
stop |
停止播放时 |
无 |
wavesurfer.on('stop', () => {}) |
seek |
跳转到指定位置时 |
progress |
wavesurfer.on('seek', (progress) => {}) |
4. 时间进度事件
| 事件名称 |
触发时机 |
回调参数 |
示例 |
audioprocess |
播放过程中持续触发 |
currentTime |
wavesurfer.on('audioprocess', (time) => {}) |
timeupdate |
播放时间更新时 |
currentTime |
wavesurfer.on('timeupdate', (time) => {}) |
scroll |
波形滚动时 |
scrollLeft |
wavesurfer.on('scroll', (scroll) => {}) |
5. 交互事件
| 事件名称 |
触发时机 |
回调参数 |
示例 |
click |
点击波形图时 |
relativeX, relativeY |
wavesurfer.on('click', (x, y) => {}) |
dblclick |
双击波形图时 |
relativeX, relativeY |
wavesurfer.on('dblclick', (x, y) => {}) |
dragstart |
开始拖动时 |
relativeX |
wavesurfer.on('dragstart', (x) => {}) |
dragmove |
拖动过程中 |
relativeX |
wavesurfer.on('dragmove', (x) => {}) |
dragend |
拖动结束时 |
relativeX |
wavesurfer.on('dragend', (x) => {}) |
interaction |
任何交互发生时 |
无 |
wavesurfer.on('interaction', () => {}) |
6. 音频处理事件
| 事件名称 |
触发时机 |
回调参数 |
示例 |
volume |
音量改变时 |
volume |
wavesurfer.on('volume', (vol) => {}) |
mute |
静音时 |
muted |
wavesurfer.on('mute', (isMuted) => {}) |
backend-change |
音频后端改变时 |
backend |
wavesurfer.on('backend-change', (backend) => {}) |
rate |
播放速率改变时 |
rate |
wavesurfer.on('rate', (rate) => {}) |
7. 错误事件
| 事件名称 |
触发时机 |
回调参数 |
示例 |
error |
发生错误时 |
error |
wavesurfer.on('error', (error) => {}) |
8. 区域插件事件 (Regions Plugin)
| 事件名称 |
触发时机 |
回调参数 |
示例 |
region-created |
区域创建时 |
region |
wavesurfer.on('region-created', (region) => {}) |
region-updated |
区域更新时 |
region |
wavesurfer.on('region-updated', (region) => {}) |
region-removed |
区域删除时 |
region |
wavesurfer.on('region-removed', (region) => {}) |
region-in |
播放进入区域时 |
region |
wavesurfer.on('region-in', (region) => {}) |
region-out |
播放离开区域时 |
region |
wavesurfer.on('region-out', (region) => {}) |
region-mouseenter |
鼠标进入区域时 |
region, e |
wavesurfer.on('region-mouseenter', (region, e) => {}) |
region-mouseleave |
鼠标离开区域时 |
region, e |
wavesurfer.on('region-mouseleave', (region, e) => {}) |
region-click |
点击区域时 |
region, e |
wavesurfer.on('region-click', (region, e) => {}) |
region-dblclick |
双击区域时 |
region, e |
wavesurfer.on('region-dblclick', (region, e) => {}) |
9. 标记插件事件 (Markers Plugin)
| 事件名称 |
触发时机 |
回调参数 |
示例 |
marker-created |
标记创建时 |
marker |
wavesurfer.on('marker-created', (marker) => {}) |
marker-updated |
标记更新时 |
marker |
wavesurfer.on('marker-updated', (marker) => {}) |
marker-removed |
标记删除时 |
marker |
wavesurfer.on('marker-removed', (marker) => {}) |
marker-click |
点击标记时 |
marker, e |
wavesurfer.on('marker-click', (marker, e) => {}) |
marker-drag |
拖动标记时 |
marker, e |
wavesurfer.on('marker-drag', (marker, e) => {}) |
10. 光标插件事件 (Cursor Plugin)
| 事件名称 |
触发时机 |
回调参数 |
示例 |
cursor-created |
光标创建时 |
cursor |
wavesurfer.on('cursor-created', (cursor) => {}) |
cursor-move |
光标移动时 |
cursor, time |
wavesurfer.on('cursor-move', (cursor, time) => {}) |
cursor-click |
点击光标时 |
cursor, e |
wavesurfer.on('cursor-click', (cursor, e) => {}) |
三、事件使用示例
1. 基本事件监听
javascript
复制代码
// 创建实例
const wavesurfer = WaveSurfer.create({
container: '#waveform',
waveColor: 'violet',
progressColor: 'purple'
});
// 监听单个事件
wavesurfer.on('ready', function() {
console.log('音频准备就绪');
wavesurfer.play();
});
// 监听多个事件
wavesurfer.on('play', () => console.log('开始播放'));
wavesurfer.on('pause', () => console.log('暂停播放'));
wavesurfer.on('finish', () => console.log('播放结束'));
// 监听进度事件
wavesurfer.on('audioprocess', function(currentTime) {
console.log('当前时间:', currentTime.toFixed(2), '秒');
});
// 监听错误事件
wavesurfer.on('error', function(error) {
console.error('发生错误:', error);
});
2. 一次性事件监听
javascript
复制代码
// 只触发一次的事件
wavesurfer.once('ready', function() {
console.log('音频第一次准备就绪');
});
// 使用Promise风格
await new Promise((resolve) => {
wavesurfer.once('ready', resolve);
});
3. 事件参数使用
javascript
复制代码
// 使用事件参数
wavesurfer.on('loading', function(percent) {
console.log(`加载进度: ${percent}%`);
// 更新进度条
document.getElementById('progress').style.width = percent + '%';
});
wavesurfer.on('seek', function(progress) {
console.log(`跳转到: ${(progress * 100).toFixed(1)}%`);
});
wavesurfer.on('volume', function(volume) {
console.log(`音量调整为: ${volume}`);
});
4. 区域事件处理
javascript
复制代码
// 区域插件事件
wavesurfer.on('region-created', function(region) {
console.log('区域创建:', region.id);
// 区域点击事件
region.on('click', function() {
console.log('区域被点击:', region.id);
wavesurfer.play(region.start, region.end);
});
// 区域鼠标事件
region.on('mouseenter', function() {
console.log('鼠标进入区域');
region.update({ color: 'rgba(255, 0, 0, 0.3)' });
});
region.on('mouseleave', function() {
console.log('鼠标离开区域');
region.update({ color: 'rgba(0, 0, 255, 0.3)' });
});
});
// 播放进入/离开区域事件
wavesurfer.on('region-in', function(region) {
console.log('进入区域:', region.id);
});
wavesurfer.on('region-out', function(region) {
console.log('离开区域:', region.id);
});
5. 交互事件处理
javascript
复制代码
// 点击事件
wavesurfer.on('click', function(relativeX, relativeY) {
const duration = wavesurfer.getDuration();
const currentTime = relativeX * duration;
console.log(`点击位置: X=${relativeX}, Y=${relativeY}`);
console.log(`对应时间: ${currentTime.toFixed(2)}秒`);
// 跳转到点击位置
wavesurfer.seekTo(relativeX);
});
// 双击事件
wavesurfer.on('dblclick', function(relativeX, relativeY) {
// 双击创建标记
const time = relativeX * wavesurfer.getDuration();
wavesurfer.addMarker({
time: time,
color: 'red',
label: '标记点'
});
});
6. 自定义事件触发
javascript
复制代码
// 触发自定义事件
wavesurfer.fireEvent('custom-event', { data: 'custom data' });
// 监听自定义事件
wavesurfer.on('custom-event', function(data) {
console.log('自定义事件触发:', data);
});
7. 事件移除
javascript
复制代码
// 定义事件处理函数
function handlePlay() {
console.log('播放中...');
}
// 添加事件监听
wavesurfer.on('audioprocess', handlePlay);
// 移除特定监听器
wavesurfer.un('audioprocess', handlePlay);
// 移除所有audioprocess事件监听器
wavesurfer.unAll('audioprocess');
// 移除所有事件监听器
wavesurfer.unAll();
四、事件生命周期流程图
arduino
复制代码
音频加载过程事件流:
load → loading → decode → ready → waveform-ready
↓
error(如果发生错误)
播放过程事件流:
play → audioprocess(持续) → pause/stop/finish
↓
seek(跳转时)
↓
volume/rate(设置时)
交互事件流:
click/dblclick → dragstart → dragmove → dragend
↓
interaction
五、事件配置参数表格
事件相关配置参数
| 参数名 |
类型 |
默认值 |
说明 |
影响的事件 |
interact |
Boolean |
true |
是否启用交互 |
click, dblclick, drag* |
dragToSeek |
Boolean |
true |
是否允许拖动跳转 |
dragstart, dragmove, dragend |
autoScroll |
Boolean |
true |
播放时自动滚动 |
scroll |
scrollParent |
Boolean |
false |
启用横向滚动 |
scroll |
partialRender |
Boolean |
false |
部分渲染 |
影响渲染相关事件 |
splitChannels |
Boolean |
false |
分离声道显示 |
影响波形渲染事件 |
播放控制配置参数
| 参数名 |
类型 |
默认值 |
说明 |
影响的事件 |
audioRate |
Number |
1 |
播放速度 |
rate |
volume |
Number |
1 |
音量 |
volume, mute |
loopSelection |
Boolean |
true |
循环选区 |
region-in, region-out |
backend |
String |
'WebAudio' |
音频后端 |
backend-change |
插件配置参数
| 插件 |
参数名 |
默认值 |
说明 |
影响的事件 |
| Regions |
regions |
[] |
初始区域 |
region-* 事件 |
| Regions |
dragSelection |
true |
启用拖动选择 |
region-created |
| Regions |
maxRegions |
null |
最大区域数 |
区域管理事件 |
| Markers |
markers |
[] |
初始标记 |
marker-* 事件 |
| Markers |
markerWidth |
2 |
标记宽度 |
标记渲染事件 |
| Cursor |
showTime |
true |
显示时间 |
cursor-move |
| Cursor |
followCursorY |
false |
跟随光标Y轴 |
cursor-move |
六、最佳实践
1. 事件监听顺序
javascript
复制代码
// 推荐的事件监听顺序
wavesurfer.on('error', handleError); // 首先监听错误
wavesurfer.on('load', handleLoadStart); // 加载开始
wavesurfer.on('loading', updateProgress); // 加载进度
wavesurfer.on('ready', initializePlayer); // 准备就绪
wavesurfer.on('play', updatePlayState); // 播放状态
wavesurfer.on('pause', updatePlayState); // 暂停状态
wavesurfer.on('audioprocess', updateTime); // 时间更新
wavesurfer.on('finish', handlePlaybackEnd); // 播放结束
2. 内存管理
javascript
复制代码
// 在组件销毁时移除事件监听
class AudioPlayer {
constructor() {
this.wavesurfer = WaveSurfer.create(config);
this.bindEvents();
}
bindEvents() {
this.eventHandlers = {
ready: this.handleReady.bind(this),
play: this.handlePlay.bind(this),
pause: this.handlePause.bind(this)
};
Object.entries(this.eventHandlers).forEach(([event, handler]) => {
this.wavesurfer.on(event, handler);
});
}
destroy() {
// 移除所有事件监听
Object.entries(this.eventHandlers).forEach(([event, handler]) => {
this.wavesurfer.un(event, handler);
});
this.wavesurfer.destroy();
}
}
3. 事件防抖处理
javascript
复制代码
// 对频繁触发的事件进行防抖处理
let debounceTimer;
wavesurfer.on('audioprocess', (time) => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
updateUI(time);
}, 100); // 100ms防抖
});
// 或者使用节流
let lastUpdate = 0;
wavesurfer.on('scroll', (scrollLeft) => {
const now = Date.now();
if (now - lastUpdate > 200) { // 200ms节流
lastUpdate = now;
updateScrollPosition(scrollLeft);
}
});
4. 错误处理
javascript
复制代码
// 全面的错误处理
wavesurfer.on('error', (error) => {
console.error('WaveSurfer错误:', error);
// 根据错误类型处理
if (error.message.includes('NetworkError')) {
showError('网络错误,请检查音频文件地址');
} else if (error.message.includes('decode')) {
showError('音频解码失败,请检查文件格式');
} else if (error.message.includes('NotSupportedError')) {
showError('浏览器不支持音频播放');
} else {
showError('音频播放错误: ' + error.message);
}
// 恢复UI状态
resetPlayerState();
});
七、事件调试技巧
1. 事件日志记录
javascript
复制代码
// 记录所有事件的实用函数
function logAllEvents(wavesurfer) {
const events = [
'ready', 'load', 'loading', 'play', 'pause', 'finish',
'seek', 'audioprocess', 'error', 'volume', 'mute', 'rate',
'click', 'dblclick', 'dragstart', 'dragmove', 'dragend'
];
events.forEach(eventName => {
wavesurfer.on(eventName, (...args) => {
console.log(`[WaveSurfer Event] ${eventName}:`, args);
});
});
}
// 使用
logAllEvents(wavesurfer);
2. 事件性能监控
javascript
复制代码
// 监控事件触发频率
const eventStats = {};
wavesurfer.on('audioprocess', () => {
const now = Date.now();
const key = 'audioprocess';
if (!eventStats[key]) {
eventStats[key] = { count: 0, lastTime: now };
}
eventStats[key].count++;
// 每秒统计一次
if (now - eventStats[key].lastTime >= 1000) {
console.log(`事件 ${key} 触发频率: ${eventStats[key].count}/秒`);
eventStats[key] = { count: 0, lastTime: now };
}
});
这是完整的事件文档涵盖了 WaveSurfer.js 的所有事件类型,包括核心事件和插件事件,提供了详细的使用示例和最佳实践,帮助你更好地理解和使用 WaveSurfer 的事件系统。