UNPKG

@omnimedia/omnitool

Version:

open source video processing tools

63 lines (50 loc) 1.56 kB
import WaveSurfer from "wavesurfer.js" import {context} from "../../context.js" import {DecoderSource} from "../../driver/fns/schematic.js" export class Waveform { wavesurfer: WaveSurfer constructor(peaks: number[], container: HTMLElement, duration: number) { this.wavesurfer = WaveSurfer.create({ container, waveColor: 'rgb(200, 0, 200)', progressColor: 'rgb(100, 0, 100)', barWidth: 10, barRadius: 10, barGap: 2, peaks: [peaks], duration }) } static async init(source: DecoderSource, container: HTMLElement) { const driver = await context.driver const reader = driver.decode({ source }).audio.getReader() const peaks: number[] = [] let buffer: number[] = [] const samplesPerPeak = 1024 const duration = await driver.getAudioDuration(source) while (true) { const {done, value: audioData} = await reader.read() if (done) break const frames = audioData.numberOfFrames const plane = new Float32Array(frames) audioData.copyTo(plane, {planeIndex: 0}) // Use left channel only for (let i = 0; i < plane.length; i++) { buffer.push(plane[i]) if (buffer.length >= samplesPerPeak) { const chunk = buffer.splice(0, samplesPerPeak) const min = Math.min(...chunk) const max = Math.max(...chunk) peaks.push(min, max) } } audioData.close() } return new Waveform(peaks, container, duration ?? 0) } // set zoom(value: number) { // this.wavesurfer.zoom(value) // } set width(value: number) { this.wavesurfer.setOptions({width: value}) } }