如何合并音频与区域文本文件并在Wavesurfer.js中自动加载区域?
音频文件与区域信息合并及Wavesurfer.js自动加载区域实现方案
完全可行,你可以通过嵌入元数据或打包容器文件两种方式将音频和区域信息合并,加载时自动解析并创建Wavesurfer.js区域,具体实现如下:
一、将区域信息嵌入音频元数据(推荐)
把区域信息写入音频文件的自定义元数据字段,加载时直接读取解析,无需额外文件。
1. 写入元数据
- MP3格式:利用ID3v2自定义标签,可通过ffmpeg命令或Node.js库实现:
- ffmpeg命令行示例:
ffmpeg -i input.mp3 -metadata regions='[{"start":1.2,"end":3.5,"label":"intro"},{"start":5.1,"end":8.3,"label":"verse"}]' output.mp3 - Node.js代码示例(使用
music-metadata库):const mm = require('music-metadata'); const fs = require('fs'); // 定义区域信息 const regions = JSON.stringify([ {start: 1.2, end: 3.5, label: "intro"}, {start: 5.1, end: 8.3, label: "verse"} ]); async function embedRegions() { const metadata = await mm.parseFile('input.mp3'); metadata.common.regions = regions; const updatedBuffer = await mm.writeMetadata('input.mp3', metadata, {format: 'mp3'}); fs.writeFileSync('output.mp3', updatedBuffer); } embedRegions();
- ffmpeg命令行示例:
- WAV格式:可写入WAV的INFO chunk,同样可通过
music-metadata库操作,逻辑和MP3一致。
2. Wavesurfer.js加载时解析并创建区域
加载音频后读取元数据,解析区域信息并调用addRegion()创建:
const wavesurfer = WaveSurfer.create({ container: '#waveform', waveColor: 'violet', progressColor: 'purple' }); wavesurfer.load('output.mp3').then(async () => { const audioBlob = await fetch(wavesurfer.getAudio().src).then(res => res.blob()); const metadata = await mm.parseBlob(audioBlob); const regions = JSON.parse(metadata.common.regions); // 批量创建区域 regions.forEach(region => { wavesurfer.addRegion({ start: region.start, end: region.end, label: region.label, color: 'rgba(255, 0, 0, 0.1)' }); }); });
二、备选:打包为ZIP容器文件
如果不想修改音频元数据,可将音频文件和区域信息JSON(把原txt转成JSON更易解析)打包成ZIP文件,加载时先解压读取:
1. 打包文件
将audio.mp3和regions.json(内容为区域数组)压缩成audio_with_regions.zip。
2. Wavesurfer.js加载解析
使用jszip库解压并处理:
const JSZip = require('jszip'); const wavesurfer = WaveSurfer.create({ container: '#waveform', waveColor: 'violet', progressColor: 'purple' }); async function loadZippedAudio(zipUrl) { const response = await fetch(zipUrl); const zip = await JSZip.loadAsync(await response.blob()); // 读取音频和区域文件 const audioBlob = await zip.file('audio.mp3').async('blob'); const regionsJson = await zip.file('regions.json').async('text'); const regions = JSON.parse(regionsJson); // 加载音频并创建区域 wavesurfer.load(URL.createObjectURL(audioBlob)).then(() => { regions.forEach(region => { wavesurfer.addRegion({ start: region.start, end: region.end, label: region.label, color: 'rgba(255, 0, 0, 0.1)' }); }); }); } // 调用加载 loadZippedAudio('audio_with_regions.zip');
内容的提问来源于stack exchange,提问作者woka
相关产品推荐
相关产品推荐

