# Full implementation of WaveSurver Spectrogram

**URL:** https://support.prodi.gy/t/full-implementation-of-wavesurver-spectrogram/7433
**Category:** Uncategorized
**Created:** [November 18, 2024, 6:34pm UTC](https://support.prodi.gy/t/full-implementation-of-wavesurver-spectrogram/7433 "2024-11-18T18:34:36Z")
**Posts on this page:** 1
**Showing post:** 2

<div class="post-metadata">

### Author: ![cbjrobertson](https://avatars.discourse-cdn.com/v4/letter/c/87869e/32.png) [@cbjrobertson](https://support.prodi.gy/u/cbjrobertson)
#### Post date: [December 2, 2024, 5:05pm UTC](https://support.prodi.gy/t/full-implementation-of-wavesurver-spectrogram/7433/2 "2024-12-02T17:05:42Z")

</div>

Answering my own question. Based on [this](https://support.prodi.gy/t/wavesurfer-spectrogram/4993) answer, with some serious help from front end friend, we got a spectrogram to load. However, we weren't able to append it to the existing `wavesurfer` instance available on `window.prodigy.wavesurfer` (not sure why, and I'm sure it should be possible, but we didn't have the time). We had to create a new `wavesurfer` instance and add a spectrogram to it, then associate them with separate windows, and then make the second `wavesurfer` waveform invisible (otherwise there were two).

See below for full hackery, including re-loading the base64 file as a Blob, and altering the height param (endless css commands did nothing).

```javascript
function base64ToBlob(base64, contentType = "", sliceSize = 512) {
    const byteCharacters = atob(base64.split(",")[1]);
    const byteArrays = [];

    for (let offset = 0; offset < byteCharacters.length;
        offset += sliceSize) {
        const slice = byteCharacters.slice(
            offset, offset + sliceSize);

        const byteNumbers = new Array(slice.length);
        for (let i = 0; i < slice.length; i++) {
            byteNumbers[i] = slice.charCodeAt(i);
        }

        const byteArray = new Uint8Array(byteNumbers);
        byteArrays.push(byteArray);
    }

    const blob = new Blob(byteArrays, { type: contentType });
    return blob;
}

var createSpectro = async function() {
    const spectrogramContainer = document.querySelector('#spectogram-123');
    if (spectrogramContainer.firstChild) {
        spectrogramContainer.removeChild(spectrogramContainer.firstChild);
    }
    const { default: Spectrogram } = await import('https://unpkg.com/wavesurfer.js@7.8.9/dist/plugins/spectrogram.js');
    var wavesurfer = WaveSurfer.create({
        container: '#waveform-123',
        waveColor: '#0078ff',
        progressColor: '#005bb5',
        height: 0,
        responsive: true,
        plugins: [Spectrogram.create({
            labels: true,
            fftSamples: 1024,
            wavesurfer: window.wavesurfer,
            container: '#spectogram-123',
            height: 1024,
        })]
    });
    wavesurfer.loadBlob(base64ToBlob(window.prodigy.content.audio))
        .then(() => {
            document.querySelector('#spectogram-123').children[0].style.height = "256px";
        });
}

function loadScript(url, callback, type) {
    var head = document.head;
    var script = document.createElement('script');
    script.type = type;
    script.src = url;
    script.onreadystatechange = callback;
    script.onload = callback;
    head.appendChild(script);
}

function handleSpectrogramEvent(event) {
    loadScript("https://unpkg.com/wavesurfer.js@7.8.9/dist/wavesurfer.min.js", createSpectro, 'text/javascript');
    console.log(`Spectrogram updated due to event: ${event.type}`);
}

document.addEventListener('prodigyanswer', handleSpectrogramEvent)
document.addEventListener('prodigymount', handleSpectrogramEvent)

```

```html
<div id="spectogram-123"></div>
<div id="waveform-123" style="height: 0; visibility: hidden;"></div>

```

This worked for us. I surely think a Prodigy native support for a spectrogram would be very useful, especially for phonetic annotation tasks!

EDIT: Original answer wasn't updating with new tasks, so I've added event listeners and deleted any existing `spectrogramContainer.firstChild` instance (otherwise, it was appending new spectrograms underneath existing ones).

---

_[View the full topic](https://support.prodi.gy/t/full-implementation-of-wavesurver-spectrogram/7433)._
