一、前言
上期推荐了文本标注poplar-annotation用法,这期针对音视频标注推荐wavesurfer.js库;
Wavesurfer.js 是一个基于Web Audio API 和HTML5 Canvas的开源音频可视化库,用于创建可交互、可定制的波形。同时拥有众多插件库。
二、demo效果
可以实现音视频播放暂停、指定区域播放循环暂停、创建标注区域、标注区域文字编辑、标注区域拖拉拽、时间交互效果等;
三、官网
四、使用
1.下载
-
npm install wavesurfer.js
-
或者引入(不推荐)外部地址不安全
<script src="https://unpkg.com/wavesurfer.js"></script>
2.WaveSurfer 挂载、创建、销毁
useWavesurfer
的Hook封装
import React, { useState, useEffect } from "react";
import WaveSurfer from "wavesurfer.js";
const useWavesurfer = (containerRef, options) => {
const [wavesurfer, setWavesurfer] = useState(null)
useEffect(() => {
if (!containerRef.current) return
const ws = WaveSurfer.create({
...options,//WaveSurfer的配置项
container: containerRef.current,//WaveSurfer需要挂载的容器也是dom节点
})
setWavesurfer(ws)
//销毁
return () => {
ws.destroy()
}
}, [options, containerRef])
return wavesurfer
}
export default useWavesurfer
3.WaveSurferPlayer
组件
import React, { useState, useRef, useEffect, useCallback } from "react";
import useWavesurfer from './useWavesurfer.js'
const WaveSurferPlayer = ({plugins}) => {
const regions=plugins[0]
const containerRef = useRef()
const [isPlaying, setIsPlaying] = useState(false)
const [currentTime, setCurrentTime] = useState(0)
const wavesurfer = useWavesurfer(containerRef, props)
const onPlayClick = useCallback(() => {
wavesurfer.isPlaying() ? wavesurfer.pause() : wavesurfer.play()
}, [wavesurfer])
useEffect(() => {
if (!wavesurfer) return
setCurrentTime(0)
setIsPlaying(false)
const subscriptions = [
wavesurfer.on('play', () => setIsPlaying(true)),
wavesurfer.on('pause', () => setIsPlaying(false)),
wavesurfer.on('timeupdate', (currentTime) => setCurrentTime(currentTime)),
wavesurfer.on('ready',()=>{
regions.enableDragSelection({
color: 'rgba(255, 0, 0, 0.1)',
resize:false,
drag:false,
})
regions.on('region-created', (region) => {
console.log('region-created', region)
})
regions.on('region-clicked', (region, e) => {
e.stopPropagation()
if(!region)return
region.remove()
console.log('region-remove', region)
})
}),
wavesurfer.on('finish', () => {
wavesurfer.setTime(0)
})
]
return () => {
//在 useEffect 的清理阶段(即返回的函数),遍历 subscriptions 数组,其中包含了所有的事件监听器。对每一个监听器调用 unsub(),移除事件监听器,确保内存得到释放。
subscriptions.forEach((unsub) => unsub())
}
}, [wavesurfer])
return (
<>
<div ref={containerRef} style={{ minHeight: '120px' }} />
<button onClick={onPlayClick} style={{ marginTop: '50px',marginLeft:'600px' }}>
{isPlaying ? 'Pause' : 'Play'}
</button>
<p>Seconds played: {currentTime}</p>
</>
)
}
export default WaveSurferPlayer
每个区域的创建,对应着一个’region-created’,包含id,起始时间,结束时间等;
4.使用组件
import WaveSurferPlayer from './WaveSurferPlayer.js'
import React, { useState } from "react";
/**regions区域交互插件 */
import RegionsPlugin from 'wavesurfer.js/dist/plugins/regions.esm.js'
/**Timeline时间轴插件 */
import Timeline from 'wavesurfer.js/dist/plugins/timeline.esm.js'
/**Hover时间交互插件 */
import Hover from 'wavesurfer.js/dist/plugins/hover.esm.js'
function App() {
const [audioUrl, setAudioUrl] = useState(require('./music01.mp3'))//require绝对路径
return <WaveSurferPlayer
height={200}
waveColor='#A8DBA8'
progressColor='#3B8686'
url={audioUrl}
backend="MediaElement"
plugins={
[RegionsPlugin.create(),
Timeline.create({}),
Hover.create({
lineColor: '#000',
lineWidth: 2,
labelBackground: '#555',
labelColor: '#fff',
labelSize: '11px',
}),
]}
/>
}
export default App
五、相关问题及解决
1.WaveSurfer.create()重复创建、重复挂载的问题
记得要使用WaveSurfer的destroy属性销毁
//销毁
return () => {
ws.destroy()
}
2.资源路径url地址引入的问题
记得引入绝对路径
require('./music01.mp3')
3.插件引入的地址
一定要看官网的地址,很多博主引入的地址都是老版本的
标签:return,音频,js,import,wavesurfer,const,region From: https://blog.csdn.net/weixin_56048772/article/details/141181452