angulartypescripthtml5-audiovideogular

Audio player with a playlist using buttons


I'm attempting to make a sound board app with Angular 6 and Electron. I'm trying to use Videogular 2 for the audio player. My github repo can be found here https://github.com/benhalverson/electron-angular-soundapp

HTML

  <div>
     <div>
        <button mat-raised-button *ngFor="let item of playlist; let $index = index" (click)="onClickPLaylistItem(item, $index)">
          {{ item.title }}

        </button>
      </div>
    </div>

    <vg-player style="height: 50px;" (onPlayerReady)="onPlayerReady($event)">
      <vg-controls>
        <vg-play-pause></vg-play-pause>
        <vg-playback-button></vg-playback-button>
      </vg-controls>

      <audio #media [vgMedia]="playlist" preload="auto">
        <source *ngFor="let audio of playlist" [src]="audio.src" [type]="audio.type">
      </audio>
    </vg-player>

home.component.ts

import { Component, OnInit, Input, ViewChild } from '@angular/core';
import { ElectronService } from '../../providers/electron.service';
import { VgAPI } from 'videogular2/core';
export interface IMedia {
  title: string;
  src: string;
  type: string;
}
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
  constructor(private _electronService: ElectronService) {}
  playlist: Array<IMedia> = [
    {
      title: 'Bell',
      src: localStorage.audio1 || './assets/audio/bell-3.wav',
      type: 'audio/wav'
    },
    {
      title: 'compact car',
      src: localStorage.audio2 || './assets/audio/compact-car-screeching.wav',
      type: 'audio/wav'
    },
    {
      title: 'crowd awww',
      src: localStorage.audio3 || './assets/audio/crowd-aww.wav',
      type: 'audio/wav'
    },
    {
      title: 'crowd bravo',
      src: localStorage.audio4 || './assets/audio/crowd-bravo.wav',
      type: 'audio/wav'
    },
    {
      title: 'cround count down 10 - 1 ',
      src:
        localStorage.audio5 || './assets/audio/crowd-countdown-ten-to-one.wav',
      type: 'audio/wav'
    },
    {
      title: 'crowd painful ohhhh',
      src: localStorage.audio6 || './assets/audio/crowd-painful-ohh.wav',
      type: 'audio/wav'
    },
    {
      title: 'harp spell classic',
      src: localStorage.audio7 || './assets/audio/harp-spell-classic.wav',
      type: 'audio/wav'
    },
    {
      title: 'huge long ovation male crowd',
      src:
        localStorage.audio8 ||
        './assets/audio/huge-long-ovation-male-crowd.wav',
      type: 'audio/wav'
    },
    {
      title: 'police bull horn pull over',
      src:
        localStorage.audio9 || './assets/audio/police-bull-horn-pull-over.wav',
      type: 'audio/wav'
    },
    {
      title: 'police siren',
      src: localStorage.audio10 || './assets/audio/police-siren.wav',
      type: 'audio/wav'
    },
    {
      title: 'car crash',
      src: localStorage.audio10 || './assets/audio/sfx-car-crash.wav',
      type: 'audio/wav'
    },
    {
      title: 'spring 3',
      src: localStorage.audio10 || './assets/audio/spring-3.wav',
      type: 'audio/wav'
    },
    {
      title: 'toilet flush big',
      src: localStorage.audio10 || './assets/audio/toilet-flush-big.wav',
      type: 'audio/wav'
    },
    {
      title: 'train-horn-double',
      src: localStorage.audio10 || './assets/audio/train-horn-double.wav',
      type: 'audio/wav'
    }
  ];

  preload = 'auto';
  currentIndex = 0;
  currentItem: IMedia = this.playlist[this.currentIndex];
  api: VgAPI;
  openMenu() {
    // this.trigger.openMenu();
    // console.log('menu opened');
  }

  onPlayerReady(api: VgAPI): void {
    this.api = api;
    this.api
      .getDefaultMedia()
      .subscriptions.loadedMetadata.subscribe(this.playAudio.bind(this));
  }
  playAudio() {
    this.api.play();
  }

  onClickPLaylistItem(item: IMedia, index: number) {
    this.currentIndex = index;
    this.currentItem = item;
    console.log('current item', this.currentItem);
    console.log('clicked from onclickplaylist');
  }
  ngOnInit() {}
}

app.module.ts

import 'zone.js/dist/zone-mix';
import 'reflect-metadata';
import '../polyfills';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { HttpClientModule, HttpClient } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { ElectronService } from './providers/electron.service';
import { WebviewDirective } from './directives/webview.directive';
import { AppComponent } from './app.component';
import { HomeComponent } from './components/home/home.component';
import { SettingsComponent } from './components/settings/settings.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule, MatCheckboxModule } from '@angular/material';
import { MatMenuModule } from '@angular/material/menu';
import { MatGridListModule } from '@angular/material/grid-list';
import { NgxElectronModule } from 'ngx-electron';
import { VgCoreModule } from 'videogular2/core';
import { VgControlsModule } from 'videogular2/controls';
import { VgOverlayPlayModule } from 'videogular2/overlay-play';
import { VgBufferingModule } from 'videogular2/buffering';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    WebviewDirective,
    SettingsComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    AppRoutingModule,
    MatButtonModule,
    MatCheckboxModule,
    MatMenuModule,
    MatGridListModule,
    NgxElectronModule,
    BrowserAnimationsModule,
    VgCoreModule,
    VgControlsModule,
    VgOverlayPlayModule,
    VgBufferingModule
  ],
  providers: [ElectronService],
  bootstrap: [AppComponent]
})
export class AppModule {}

The error I'm getting is when I first load the app. When I clear the error in devtools the error doesn't come back and I see these two logs but dont hear any sounds.

    console.log('current item', this.currentItem);
    console.log('clicked from onclickplaylist');

The error is to long to post here. You can see it on the github issue I also posted. https://github.com/videogular/videogular2/issues/786


Solution

  • This is my working code:

    audioplayer.ts

    import { Component, OnInit } from '@angular/core';
    import { VgAPI } from 'videogular2/core';
    export interface IMedia {
      title: string;
      src: string;
      type: string;
    }
    @Component({
      selector: 'app-audio-player',
      templateUrl: './audio-player.component.html',
      styleUrls: ['./audio-player.component.css']
    })
    export class AudioPlayerComponent implements OnInit {
      playlist: Array <IMedia> = [
       {
          title: 'Bell',
          src: './assets/audio/bell-3.wav',
          type: 'audio/wav'
        },
        {
          title: 'compact car',
          src: './assets/audio/compact-car-screeching.wav',
          type: 'audio/wav'
        }
      ];
    
      currentIndex = 0;
      currentItem: IMedia = this.playlist[ this.currentIndex ];
      api: VgAPI;
      public name: string;
      controls: boolean = false;
      autoplay: boolean = true;
      loop: boolean = false;
      preload: string = 'auto';
    
      constructor() { }
    
    
      onClickPLaylistItem(item: IMedia, index: number) {
        this.currentIndex = index;
        this.currentItem = item;
      }
    
      onPlayerReady(api: VgAPI) {
        this.api = api;
    
        this.api.getDefaultMedia().subscriptions.ended.subscribe(
            () => {
                // Set the video to the beginning
                this.api.getDefaultMedia().currentTime = 0;
            }
        );
    
    }
    
      ngOnInit() {}
    }
    

    audioplayer.html

    <div class="buttons">
    <button mat-raised-button (click)="onClickPLaylistItem(item, $index); api.play()" *ngFor="let item of playlist; let $index = index" >
        {{ item.title }}
    
      </button>
    <vg-player (onPlayerReady)="onPlayerReady($event)">
    
      <vg-controls>
        <vg-play-pause></vg-play-pause>
    
      </vg-controls>
      <audio #media [vgMedia]="media" [src]="currentItem.src" id="modalPlayer" preload="none"></audio>
    </vg-player>