To do Audio visualization, to do some really cool things you need to use some methods called AudioContext that the Web Audio API provides.

  • The AudioContext interface represents an audio processing diagram built from audio modules that are linked together, each represented by an AudioNode. The audio context controls the creation of the nodes it contains and the execution of the audio processing or decoding.

  • Before you do anything else, you need to create an AudioContext object, because everything happens in context. It is recommended that you create an AudioContext object and reuse it, rather than initializing a new AudioContext object each time, and that you can use one AudioContext object simultaneously for multiple different audio sources and pipes.

Prepare the Audio and Canvas tags

<audio class="audio" ref='audio' :src='tune' @ended='ended'></audio>
<canvas ref='canvas' width='300px' height='300px'></canvas>
Copy the code

Create and return a new AudioContext object.

const ctx = new AudioContext();
Copy the code

Create a new MediaElementAudioSourceNode object

  • AudioContextOf the interfaceThe createMediaElementSource() method creates a new oneMediaElementAudioSourceNodeObject to enter an existing HTMLor‘element, the corresponding audio can be played or modified.
const audioSrc = ctx.createMediaElementSource(this.audioElement);
Copy the code

Create an AnalyserNode object

  • AudioContextcreateAnalyser()The method can create aAnalyserNode, can be used to obtain audio time and frequency data, as well as data visualization.
const analyser = ctx.createAnalyser();
Copy the code

Set the fftSize property

  • The value of the fftSize attribute of the AnalyserNode interface is an unsigned long integer that represents the window size of the sample. These samples are used to obtain frequency-domain data when performing the Fast Fourier Transfor (FFT).

  • The value of the fftSize attribute must be a nonzero power of 2 in the range 32 to 32768; The default value is 2048.

analyser.fftSize = 512;
Copy the code

AudioSrc and Analyser link

The Connect () method of the AudioNode interface enables you to connect the output of a node to a specified destination, The specified target may be another AudioNode (thus directing the audio data to the next specified node) or an AudioParam so that the output data from the previous node automatically changes the value of the next parameter over time.

audioSrc.connect(analyser);
Copy the code

Analyser and ctx.destination are linked

  • AudioContextdestinationProperty returns aAudioDestinationNodeRepresents the ultimate destination node for all audio (nodes) in the context, typically an audio rendering device such as a speaker.
analyser.connect(ctx.destination)
Copy the code

The song is in progress

  • Uint8Array array type represents an array of 8-bit unsigned integers that are initialized to 0 when created. Once created, you can refer to the elements of the array as objects or by using an array subscript index.
  • AnalyserNodeOf the interfacegetByteFrequencyData()The Uint8Array (unsigned byte array) method copies the current frequency data into the passed Uint8Array.
  • If the length of the array is less thanAnalyserNode.frequencyBinCount, the extra Analyser element is removed. If it is greater than, excess elements in the array are ignored.
visualization() {
    const arr = new Uint8Array(this.analyser.frequencyBinCount);
    this.analyser.getByteFrequencyData(arr);
    this.draw(arr);
},
Copy the code

Draw an audio map using a Canvas

  • HTMLCanvasElement.getContext()Method returnscanvasIs returned if the context is not definednull .
  • 2dTo establish aCanvasRenderingContext2D2d rendering context.
this.canvas = this.$refs.canvas.getContext('2d');draw(arr) {    canvas.clearRect(0.0.document.body.clientWidth, this.canvasHeight);    const start = ((document.body.clientWidth / 2) - ((arr.length / 2) * 3));    arr.forEach((item, index) = > {        this.canvas.beginPath();        this.canvas.strokeStyle = '#B2AFF4';        this.canvas.lineWidth = 3;        this.canvas.moveTo(start + (index * 4), this.canvasHeight);        this.canvas.lineTo(start + (index * 4), this.canvasHeight - item / 2);        this.canvas.stroke(); }); }Copy the code

Results show