0

We are creating a library of sounds with a waveform plaver using Wavesurf JS. In order to optimize the loading time we are saving the waveforms generated in the canvas as an image so we don't have to generate it every time the sound is loaded, and so far it works great.

But in order to save the image we need to wait for the canvas to load and the only way we have found is by using setTimeout.

wavediv = WaveSurfer.create({
    container: '#canvasRender',
    waveColor: '#FFFFFF',
    progressColor: '#000000',
    cursorColor:'rgba(0,0,0,0)',
    splitChannels: true,
    height : 75,
    plugins: [
]
});

wavediv.load("sounds/test.mp3");
window.setTimeout(function(){
    var dataImg = wavediv.exportImage('image/png');
    saveWave(dataImg);
},600);

saveWave() is just a function that calls an AJAX and sends the data to the server and we save it, that works great. The issue is that we don't want to rely on window.setTimeout() because we a are limited to 0.6s seconds as we have in this example (600) and if the rendering takes more than 0.6s then it saves an empty image.

So I am looking for some kind of callback function or listener that will trigger saveWave() only when the waveform has finished loading.

example:

wavediv.load("sounds/test.mp3", function(){
   var dataImg = wavediv.exportImage('image/png');
   saveWave(dataImg);
});

or

wavediv.ready(function () {
    var dataImg = wavediv.exportImage('image/png');
    saveWave(dataImg);
});

I found something similar in another post but it didn't work :

wavediv.on("ready", function () {
    var dataImg = wavediv.exportImage('image/png');
    saveWave(dataImg);
});

Same issue here: https://github.com/katspaugh/wavesurfer.js/issues/1727 and was only solved with setTimeout() :(

multimediaxp
  • 9,348
  • 13
  • 49
  • 80

1 Answers1

0

use my function checkIfDrawed(wavesurferDivID)

it is a promise that check if the canvas is empty or not

exemple:

arg 100 is the time in millisecond to check if the wave was drawed or not

waveSurferID is the ID of the div that has the wavesurfer

checkIfDrawed("waveSurferID", 100).then(value=>{ /*your code here*/ })

function checkIfDrawed(wsDivID, milliesecond){
    
        function isCanvasEmpty(canvas) {

            const context = canvas.getContext('2d');
            const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
            const data = imageData.data;

            console.log("imageData", imageData)
            
            // Iterate through the pixel data and check for non-transparent pixels
            for (let i = 0; i < data.length; i += 4) {

                if (data[i + 3] !== 0) {

                    return false; // Found a non-transparent pixel, canvas is not empty

                }

            }
            
            return true; // No non-transparent pixels found, canvas is empty
        }

        let thread = undefined

        let wasDrawed = undefined

        function backgroundRunner(){

            let parents = document.getElementById(wsDivID).childNodes

            wasDrawed = false

            for(node of parents){

                // console.log(node)

                if(node.tagName == "WAVE"){

                    // console.log("wave")

                    let waveNode = node.childNodes

                    for(subNodes of waveNode){

                        // console.log(subNodes)

                        if(subNodes.tagName == "CANVAS"){

                            // console.log("canvas")

                            if (isCanvasEmpty(subNodes)) {

                                console.log('The canvas is empty.');

                                wasDrawed = false

                            } else {

                                console.log('The canvas is full.');

                                wasDrawed = true  

                                clearInterval(thread)
                            
                            }

                        }

                    }
                    
                }

            }

        }

        return new Promise(resolve=>{

            thread = setInterval(backgroundRunner, milliesecond);

            const checkWasDrawedStatus = setInterval(()=>{

                if(wasDrawed){

                    console.log("wasDrawed", wasDrawed)

                    clearInterval(checkWasDrawedStatus)

                    resolve(wasDrawed)

                }

            }, milliesecond)

        }) 

    
    }

   
        
        

let ws = WaveSurfer.create({

            container: '#waveSurferID',
            waveColor: '#cd2df1',
            progressColor: '#1AAFFF',
            height:50,
            scrollParent:false

});

ws.load("music.mp3")
        
checkIfDrawed("waveSurferID", 100).then(value=>{

        console.log("value", value)

    })
        
<script src="https://unpkg.com/wavesurfer.js"></script>

<div id="waveSurferID"></div>
Kamal Zaitar
  • 101
  • 1
  • 3