12

On my server I use Audiowaveform to generate JSON data from my audio files.

On frontend I use Wavesurfer-JS to draw the waveform based on previous JSON data.

The problem is that on page ready the Wavesurfer-JS download on background the audio file all the time (and not only when the user hit the play button).

This is my try.

This is the salient part:

<div id="waveform">
    <audio id="song" style="display: none" preload="false" src="http://api.soundcloud.com/tracks/45398925/stream?client_id=fa791b761f68cafa375ab5f7ea51927a"></audio>
</div>

<script>
    var wavesurfer = WaveSurfer.create({
      container: '#waveform',
      waveColor: 'grey',
      backend: 'MediaElement',
      mediaType:'audio',
      progressColor: 'red',
      cursorColor: '#fff',
      normalize: true,
      barWidth: 3
    });

    wavesurfer.load(document.querySelector('#song'), ['.$json.']);
</script>

So basically I need to focus on wavesurfer.load and add a new function to this Javascript to only draw from peaks(JSON data) the waveform and don't download audio file on page load but only when the user hit the play button.

How can I achieve it?

Legionar
  • 7,472
  • 2
  • 41
  • 70
  • 2
    So basically you want it to draw a waveform but only download the song when the playbutton is clicked? This is not part of waveform.js for some cray reason, let's see if I can write a hook or some implementation to make it draw without downloading the music. – seahorsepip Aug 18 '16 at 02:58

2 Answers2

18

Took me a while to hack around the wavesurfer js code to find out how I can make it draw without loading the song already :P

Setting the peaks in the backend variable and calling drawBuffer did the trick, combining that with some play button logic and we get the following code:

//Create new wavesurfer
wavesurfer = WaveSurfer.create({
    container: '#waveform',
    backend: 'MediaElement',
    mediaType:'audio',
    normalize: true,
    barWidth: 3
});

//Set song
wavesurfer.song = "http://www.stephaniequinn.com/Music/Allegro%20from%20Duet%20in%20C%20Major.mp3"

//Set peaks
wavesurfer.backend.peaks = [0.0218, 0.0183, 0.0165, 0.0198, 0.2137, 0.2888, 0.2313, 0.15, 0.2542, 0.2538, 0.2358, 0.1195, 0.1591, 0.2599, 0.2742, 0.1447, 0.2328, 0.1878, 0.1988, 0.1645, 0.1218, 0.2005, 0.2828, 0.2051, 0.1664, 0.1181, 0.1621, 0.2966, 0.189, 0.246, 0.2445, 0.1621, 0.1618, 0.189, 0.2354, 0.1561, 0.1638, 0.2799, 0.0923, 0.1659, 0.1675, 0.1268, 0.0984, 0.0997, 0.1248, 0.1495, 0.1431, 0.1236, 0.1755, 0.1183, 0.1349, 0.1018, 0.1109, 0.1833, 0.1813, 0.1422, 0.0961, 0.1191, 0.0791, 0.0631, 0.0315, 0.0157, 0.0166, 0.0108];

//Draw peaks
wavesurfer.drawBuffer();

//Variable to check if song is loaded
wavesurfer.loaded = false;

//Load song when play is pressed
wavesurfer.on("play", function () {
    if(!wavesurfer.loaded) {
        wavesurfer.load(wavesurfer.song, wavesurfer.backend.peaks);
    }
});

//Start playing after song is loaded
wavesurfer.on("ready", function () {
    if(!wavesurfer.loaded) {
        wavesurfer.loaded = true;
        wavesurfer.play();
    }
});

Make sure to remove the unnecessary<audio> tag from the html, browsers seem to download all audio files in those tags on load and attributes like preload=false seem to be ignored...

seahorsepip
  • 4,519
  • 1
  • 19
  • 30
  • Thanks for your time, I tried your solution but as you can see from [here](http://codepen.io/drhouse7x/pen/mEokPW) it downloads the mp3 media file again on background. Am I missing something? –  Aug 18 '16 at 09:23
  • 1
    The html5 audio tag seems to download in the background on load in the most browsers. I edited the answer to solve this. – seahorsepip Aug 18 '16 at 10:35
  • 1
    I'm speechless, after spending a whole week torturing myself finally you did it :D thank you so much! –  Aug 18 '16 at 11:55
  • According to my testing this will redraw waveform once you can load method, which doesnt seem useful since waveform is already draw. Can you just load and play without redrawing waveform? – Toniq Oct 04 '16 at 14:41
  • @Toniq sadly not as far I know without modifying the plugin itself which is a bad idea. – seahorsepip Oct 05 '16 at 00:30
  • 1
    @Toniq I found a solution for that. Inseat of wavesurfer.load you just need to you wavesurfer.loadMediaElement(wavesurfer.song, wavesurfer.backend.peaks, true, wavesurfer.getDuration()); Kudos to aburai https://github.com/katspaugh/wavesurfer.js/issues/1732 – diegoiglesias Sep 05 '19 at 22:47
  • preload="false" is not a valid option and hence default option will be used which is preload="auto". If you don't want the audio to be downloaded add the preload="none" attribute in the audio tag which will not download the audio until the play button is pressed. – Naresh Bisht Sep 05 '21 at 09:43
0

WaveSurfer object have native variable named "wavesurfer.isReady"

if(wavesurfer.isReady){
..
}
Uxoos
  • 11
  • 2