edimuj / cordova-plugin-audioinput

This iOS/Android Cordova/PhoneGap plugin enables audio capture from the device microphone, by in near real-time forwarding audio to the web layer of your application. A typical usage scenario for this plugin would be to use the captured audio as source for a web audio node chain, where it then can be analyzed, manipulated and/or played.

Home Page:https://github.com/edimuj/app-audioinput-demo

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ionic 4 - Basic Example

DanielTizon opened this issue · comments

Hi,
There is a issue related to this, but at the moment that issue is closed, and I didn't find the answer that I need, so I am opening a new issue related to this issue:

https://github.com/edimuj/cordova-plugin-audioinput/issues/66

I'm trying to use this plugin with Ionic 4, but I am not able to find an basic example with all the steps needed to run this plugin in Ionic.

It has been my attempt to use cordova-plugin-audioinput in one Ionic 4 project. First I created a blank ionic project:

ionic start myproject blank

After that, I installed this plugin:

ionic cordova plugin add https://github.com/edimuj/cordova-plugin-audioinput.git

And then, I tried use this plugin in app.component.ts:

declare let audioinput: any;

import { Component } from '@angular/core';

import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html'
})
export class AppComponent {
  constructor(
    private platform: Platform,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar
  ) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();
      audioinput.checkMicrophonePermission(function (hasPermission) {
        if (hasPermission) {
          console.log("We already have permission to record.");
          this.startCapture();
        }
        else {
          // Ask the user for permission to access the microphone
          audioinput.getMicrophonePermission(function (hasPermission, message) {
            if (hasPermission) {
              console.log("User granted us permission to record.");
              this.startCapture();
            } else {
              console.warn("User denied permission to record.");
            }
          });
        }
      });
    });
  }

  public startCapture() {
    audioinput.start({
      streamToWebAudio: true
    });

    // Connect the audioinput to the device speakers in order to hear the captured sound.
    audioinput.connect(audioinput.getAudioContext().destination);
  }
}

But when I use ionic serve to run it in my browser I get the next error:

ERROR Error: "Uncaught (in promise): ReferenceError: audioinput is not defined
./src/app/app.component.ts/AppComponent.prototype.initializeApp/<@http://localhost:8100/main.js:980:13
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invoke@http://localhost:8100/polyfills.js:2749:17
onInvoke@http://localhost:8100/vendor.js:51136:24
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invoke@http://localhost:8100/polyfills.js:2748:37
./node_modules/zone.js/dist/zone.js/</Zone.prototype.run@http://localhost:8100/polyfills.js:2508:24
scheduleResolveOrReject/<@http://localhost:8100/polyfills.js:3247:29
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:8100/polyfills.js:2781:17
onInvokeTask@http://localhost:8100/vendor.js:51127:24
./node_modules/zone.js/dist/zone.js/</ZoneDelegate.prototype.invokeTask@http://localhost:8100/polyfills.js:2780:41
./node_modules/zone.js/dist/zone.js/</Zone.prototype.runTask@http://localhost:8100/polyfills.js:2553:28
drainMicroTaskQueue@http://localhost:8100/polyfills.js:2959:25

Anybody could help to have a basic example about how to use this plugin with Ionic?

Thanks!

commented

Good question, I think it is good that you opened a new issue for this, since #66 is specifically for Ionic 3. I, myself, doesn't use Ionic, so I hope somebody else may be able to help you. Keeping this issue opened until then. If you manage to solve this yourself, I would be grateful if you update this issue with the solution and close it. Thanks!

I got some advances. It is needed to run it with:

ionic cordova run browser

But I am not able to get fired the audioinput event when I am recording. I am using the next code:

declare let audioinput: any;

import { Component } from '@angular/core';

import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { File } from '@ionic-native/file/ngx';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html'
})
export class AppComponent {

  audioContext: AudioContext = new AudioContext();

  constructor(private platform: Platform, private splashScreen: SplashScreen, private statusBar: StatusBar, private file: File) {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();

      window.addEventListener('audioinput', (event) => {
        console.log("EVENT: " + JSON.stringify(event));
      }, false);

      audioinput.checkMicrophonePermission((hasPermission) => {
        if (hasPermission) {
          console.log("We already have permission to record.");
          this.startCapture();
        }
        else {
          // Ask the user for permission to access the microphone
          audioinput.getMicrophonePermission((hasPermission, message) => {
            if (hasPermission) {
              console.log("User granted us permission to record.");
              this.startCapture();
            } else {
              console.warn("User denied permission to record.");
            }
          });
        }
      });
    });
  }


  public startCapture() {
    this.file.createFile(this.file.dataDirectory, "test.wav", true).then((result) => {
      audioinput.start({
        bufferSize: 8192,
        fileUrl: this.file.dataDirectory + '/test.wav'
      });
    });
  }


  public stopCapture() {
    if (audioinput && audioinput.isCapturing()) {
      audioinput.stop();
    }
    console.log("Stopped!");
  };
}

And I am getting the message to get permission to use mic, and this log, but no event fired:

adding proxy for AudioInputCapture cordova.js:1024:9
adding proxy for StatusBar cordova.js:1024:9
adding proxy for Device cordova.js:1024:9
adding proxy for SplashScreen cordova.js:1024:9
adding proxy for File cordova.js:1024:9
StatusBar is not supported StatusBarProxy.js:23:5
Angular is running in the development mode. Call enableProdMode() to enable the production mode. core.js:16828
Ionic Native: deviceready event fired after 305 ms bootstrap.js:10
StatusBar is not supported StatusBarProxy.js:23:5
AudioInputCaptureProxy: checkMicrophonePermission AudioInputCaptureProxy.js:75:5
AudioInputCaptureProxy: getMicrophonePermission AudioInputCaptureProxy.js:80:5
AudioInputCaptureProxy: initAudio AudioInputCaptureProxy.js:137:5
navigator.mozGetUserMedia ha sido reemplazado por navigator.mediaDevices.getUserMedia AudioInputCaptureProxy.js:147:4
AudioInputCaptureProxy: gotStream AudioInputCaptureProxy.js:166:5
AudioInputCaptureProxy: creating audioRecorder AudioInputCaptureProxy.js:194:5
User granted us permission to record. app.component.ts:36:14
AudioInputCaptureProxy: start: [44100,8192,1,"PCM_16BIT",0,"file:///persistent//test.wav"] AudioInputCaptureProxy.js:90:5
AudioInputCaptureProxy: start - fileUrl: file:///persistent//test.wav

And, I thought that I didn't need to use fileUrl, but If I don't use fileUrl, I get the next error:

Exception calling native with command :: AudioInputCapture :: start ::exception=TypeError: fileUrl is null

@edimuj can you gimme any tip?

Thanks!

Finally, I got it working. It doesn't work on browsers, so you must use a device.

declare let audioinput: any;

import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { File } from '@ionic-native/file/ngx';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html'
})
export class AppComponent {

  BUFFER_SIZE: number = 16384;

  constructor(private platform: Platform, private splashScreen: SplashScreen, private statusBar: StatusBar, private file: File) {}

  ngOnInit() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();

      window.addEventListener('audioinput', (event: any) => {        
        alert(JSON.stringify(event.data));
      }, false);

      audioinput.checkMicrophonePermission((hasPermission) => {
        if (hasPermission) {
          console.log("We already have permission to record.");
          this.startCapture();
        }
        else {
          // Ask the user for permission to access the microphone
          audioinput.getMicrophonePermission((hasPermission, message) => {
            if (hasPermission) {
              console.log("User granted us permission to record.");
              this.startCapture();
            } else {
              console.warn("User denied permission to record.");
            }
          });
        }
      });
    });
  }

  public startCapture() {
    audioinput.start({
      bufferSize: this.BUFFER_SIZE,
      streamToWebAudio: false,
      normalize: true,
      channels: audioinput.CHANNELS.MONO,
      sampleRate: audioinput.SAMPLERATE.CD_AUDIO_44100Hz,
    });
  }
}
commented

Thank you @DanielTizon !

Thank you @DanielTizon is worked for me as well!

what is this event.data ? how to save this?

I think it is a string of comma separate numbers represent the audio signal. You can see it similar to a wave file payload in csv format.

commented

Exactly @FelixQuehl, the data is in raw PCM format, like a WAV file but without the WAV header.

@zhaoxu666 This issue is closed and your question is certainly not related to "Ionic 4 - Basic example". I saw that you asked the same question in #92. Let us continue the discussion there instead.