javascriptangulartypescriptaudio-playerwavesurfer.js

How to get a Waveform Music Player with Angular/Typescript


My goal is to set up a simple music player in my angular 8 project, that displays the inserted music in static wave form, similar to soundclouds player:

enter image description here

According to my search, this can be done with either:

Peaks JS: https://medium.com/better-programming/peaks-js-interact-with-audio-waveforms-b7cb5bd3939a
Amplitude JS : https://521dimensions.com/open-source/amplitudejs/docs/configuration/
or Wavesurfer JS: https://wavesurfer-js.org/

Unfortunately, none of them has a decent documentation on how to import this properly to angular or typescript in general.

I tried it with Wavesurfer JS but failed.

component.ts :

 import { WaveSurfer } from 'wavesurfer.js';

    export class MusicComponent {

    public wavesurfer

      constructor() {

        this.wavesurfer = WaveSurfer.create({
          container: '#waveform',
          waveColor: 'violet',
          progressColor: 'purple'
        });

        this.wavesurfer.load('./assets/img/hollywood.wav');



      }

    }

html

 <div id="waveform"></div>

The questions are now:
1. Is there some other good practice on how to implement such a player with angular, that i didnt find.
2. Is there a way to make wavesurf work in Angular, or is my code wrong.


Solution

  • Yes, it's possible, I did it. Check the code below (.ts):

    import {Component, OnInit, ViewChild, ElementRef, AfterViewInit, ChangeDetectorRef} from '@angular/core';
    import WaveSurfer from 'wavesurfer.js';
    import TimelinePlugin from 'wavesurfer.js/dist/plugin/wavesurfer.timeline.min.js';
    import Regions from 'wavesurfer.js/dist/plugin/wavesurfer.regions.min.js';
    
    @Component({
      selector: 'app-graph',
      templateUrl: './graph.component.html',
      styleUrls: ['./graph.component.css']
    })
    
    export class GraphComponent implements OnInit, AfterViewInit {
    
      wave: WaveSurfer = null;
      url = '../../assets/sinus.wav';
      public graph = undefined;
    
    
      constructor( private cdr: ChangeDetectorRef) {
      }
    
    
      ngOnInit(): void {
    
    
      }
    
      onPreviewPressed(): void {
        if (!this.wave) {
          this.generateWaveform();
        }
    
        this.cdr.detectChanges();
    
        Promise.resolve().then(() => this.wave.load(this.url));
      }
    
      onStopPressed(): void {
        this.wave.stop();
      }
    
      generateWaveform(): void {
        Promise.resolve(null).then(() => {
          this.wave = WaveSurfer.create({
            container: '#waveform',
            waveColor: 'violet',
            progressColor: 'purple',
            plugins: [
              TimelinePlugin.create({
                container: '#wave-timeline'
              }),
              Regions.create({
                regions: [
                  {
                    start: 1,
                    end: 3,
                    loop: false,
                    color: 'hsla(400, 100%, 30%, 0.5)'
                  }, {
                    start: 5,
                    end: 7,
                    loop: false,
                    color: 'hsla(200, 50%, 70%, 0.4)'
                  }
                ],
                dragSelection: {
                  slop: 5
                }
              })
            ]
          });
    
          this.wave.on('ready', () => {
            alert('I\'m ready');
            this.wave.play();
          });
        });
      }
    }
    

    And on the HTML file:

      <div id="waveform"></div>
      <div id="wave-timeline"></div>
      <div *ngIf="wave" class="controls">
        <button (click)="onStopPressed()">Stop</button>
      </div>
      <button (click)="onPreviewPressed()">Click me</button>