npm package: @picovoice/porcupine-vue
Description: Vue binding for Porcupine Web SDK
Author: Picovoice Inc
Latest version: 3.0.3
Deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

# Porcupine Binding for Vue

## Porcupine wake word engine

Made in Vancouver, Canada by [Picovoice](https://picovoice.ai)

Porcupine is a highly accurate and lightweight wake word engine. It enables building always-listening voice-enabled
applications using cutting edge voice AI.

Porcupine is:

- private and offline
- [accurate](https://github.com/Picovoice/wake-word-benchmark)
- [resource efficient](https://www.youtube.com/watch?v=T0tAnh8tUQg) (runs even on microcontrollers)
- data efficient (wake words can be easily generated by simply typing them, without needing thousands of hours of
  bespoke audio training data and manual effort)
- scalable to many simultaneous wake-words / always-on voice commands
- cross-platform

## Framework Compatibility

- Vue.js 2.6.11+
- Vue.js 3.0.0+

## Browser Compatibility

- Chrome / Edge
- Firefox
- Safari

### Restrictions

IndexedDB and WebWorkers are required to use `Porcupine Vue`. Browsers without support (i.e. Firefox Incognito Mode) 
should use the [`PorcupineWeb binding`](https://github.com/Picovoice/porcupine/tree/master/binding/web) main thread method.

## Installation

### Package

Using `Yarn`:

```console
yarn add @picovoice/porcupine-vue @picovoice/web-voice-processor
```

or using `npm`:

```console
npm install --save @picovoice/porcupine-vue @picovoice/web-voice-processor
```

### AccessKey

Porcupine requires a valid Picovoice `AccessKey` at initialization. `AccessKey` acts as your credentials when using
Porcupine SDKs.
You can get your `AccessKey` for free. Make sure to keep your `AccessKey` secret.
Signup or Login to [Picovoice Console](https://console.picovoice.ai/) to get your `AccessKey`.

## Usage

There are two methods to initialize Porcupine:

### Public Directory

**NOTE**: Due to modern browser limitations of using a file URL, this method does __not__ work if used without hosting a
server.

This method fetches [the model file](https://github.com/Picovoice/porcupine/blob/master/lib/common/porcupine_params.pv)
from the public directory and feeds it to Porcupine.
Copy the model file into the public directory:

```console
cp ${PORCUPINE_MODEL_FILE} ${PATH_TO_PUBLIC_DIRECTORY}
```

### Base64

**NOTE**: This method works without hosting a server, but increases the size of the model file roughly by 33%.

This method uses a base64 string of the model file and feeds it to Porcupine. Use the built-in script `pvbase64` to
base64 your model file:

```console
npx pvbase64 -i ${PORCUPINE_MODEL_FILE} -o ${OUTPUT_DIRECTORY}/${MODEL_NAME}.js
```

The output will be a js file which you can import into any file of your project. For detailed information
about `pvbase64`,
run:

```console
npx pvbase64 -h
```

### Porcupine Model

Porcupine saves and caches your parameter model file (`.pv`) in IndexedDB to be used by Web Assembly.
Use a different `customWritePath` variable to hold multiple model values and set the `forceWrite` value to true to force
re-save the model file.
If the model file changes, `version` should be incremented to force the cached models to be updated.
Either `base64` or `publicPath` must be set to instantiate Porcupine. If both are set, Porcupine will use the `base64`
model.

```typescript
// Model (.pv)
const porcupineModel = {
  publicPath: ${MODEL_RELATIVE_PATH},
  // or
  base64: ${MODEL_BASE64_STRING},

  // Optional
  customWritePath: 'custom_model',
  forceWrite: true,
  version: 1,
}
```

### Initialize Porcupine

Use `usePorcupine` and `init` to initialize `Porcupine`.

In case of any errors, watch for `state.error` to check the error message, otherwise watch `state.isLoaded` to check if `Porcupine` has loaded.

#### Porcupine in Vue 2

**NOTE**: If you need to call `usePorcupine` outside of `data`, make sure to add observer property via `Vue.set` or `observable`.

```vue
<script lang='ts'>
import Vue, { VueConstructor } from 'vue';
import { BuiltInKeyword } from '@picovoice/porcupine-web';
import { PorcupineVue, usePorcupine } from '@picovoice/porcupine-vue';

// Use Vue.extend for JavaScript
export default (Vue as VueConstructor<Vue & PorcupineVue>).extend({
  data() {
    const {
      state,
      init,
      start,
      stop,
      release
    } = usePorcupine();

    init(
      ${ACCESS_KEY},
      [BuiltInKeyword.Porcupine],
      porcupineModel
    );
    
    return {
      state,
      start,
      stop,
      release
    }
  },
  watch: {
    "state.keywordDetection": function (keyword) {
      if (keyword !== null) {
        console.log(keyword.label);
      }
    },
    "state.isLoaded": function (isLoaded) {
      console.log(isLoaded)
    },
    "state.isListening": function (isListening) {
      console.log(isListening)
    },
    "state.error": function (error) {
      console.error(error)
    },
  },
  onBeforeDestroy() {
    this.release();
  },
});
</script>
```

#### Porcupine in Vue 3

In Vue 3, we take advantage of the [Composition API](https://vuejs.org/api/composition-api-setup.html), especially the use of `reactive`.

```vue
<script lang='ts'>
import { defineComponent, onBeforeUnmount, watch } from 'vue';
import { BuiltInKeyword } from '@picovoice/porcupine-web';
import { usePorcupine } from '@picovoice/porcupine-vue';

// Use Vue.extend for JavaScript
export default defineComponent({
  setup() {
    const { 
      state,
      init,
      start,
      stop,
      release
    } = usePorcupine();
    
    watch(() => state.isLoaded, (newVal) => {
      console.log(newVal);
    });

    watch(() => state.isListening, (newVal) => {
      console.log(newVal);
    });

    watch(() => state.keywordDetection, (keyword) => {
      if (keyword !== null) {
        console.log(keyword.label);
      }
    });
    
    watch(() => state.error, (err) => {
      if (err) {
        console.error(err);
      }
    });

    onBeforeUnmount(() => {
      release();
    });
    
    init(
      ${ACCESS_KEY},
      [BuiltInKeyword.Porcupine],
      porcupineModel
    )
    
    return {
      start,
      stop,
      release
    }
  }
});
</script>
```

### Process Audio Frames

Porcupine Vue binding uses [WebVoiceProcessor](https://github.com/Picovoice/web-voice-processor) to record audio.
To start detecting wake word, run the `start` function:

```typescript
await this.start();
```

If `WebVoiceProcessor` has started correctly, `state.isListening` will be set to true. Watch `state.keywordDetection` to get keyword detection results.

### Stop

Run `stop` to stop keyword detection:

```typescript
await this.stop();
```

If `WebVoiceProcessor` has stopped correctly, `state.isListening` will be set to false.

### Release

Run release explicitly to clean up all resources used by `Porcupine` and `WebVoiceProcessor`:

```typescript
this.release();
```

This will set `state.isLoaded` and `state.isListening` to false.

## Custom Keywords

Create custom keywords using the [Picovoice Console](https://console.picovoice.ai/).
Train and download a Porcupine keyword model (`.ppn`) for the target platform `Web (WASM)`.
This model file can be used directly with `publicPath`, but, if `base64` is preferable, convert the `.ppn` file to a base64
JavaScript variable using the built-in `pvbase64` script:

```console
npx pvbase64 -i ${KEYWORD_FILE}.ppn -o ${KEYWORD_BASE64}.js -n ${KEYWORD_BASE64_VAR_NAME}
```

Similar to the model file (`.pv`), keyword files (`.ppn`) are saved in IndexedDB to be used by Web Assembly.
Either `base64` or `publicPath` must be set for each keyword to instantiate Porcupine.
If both are set, Porcupine will use the `base64` model.
An arbitrary `label` is required to identify the keyword once the detection occurs.

```typescript
// custom keyword (.ppn)
const keywordModel = {
  publicPath: ${KEYWORD_RELATIVE_PATH},
  // or
  base64: ${KEYWORD_BASE64_STRING},
  label: ${KEYWORD_LABEL},
  // Optional
  customWritePath: 'custom_keyword',
  forceWrite: true,
  version: 1,
}
```

Then, initialize an instance of `Porcupine`:

```typescript
this.init(
  ${ACCESS_KEY},
  [BuiltInKeyword.Porcupine],
  keywordModel, // porcupine model
);
```

## Non-English Languages

In order to detect non-English wake words you need to use the corresponding model file (`.pv`). The model files for all
supported languages are available [here](https://github.com/Picovoice/porcupine/tree/master/lib/common).

## Demo

For example usage refer to our [Vue Demo application](https://github.com/Picovoice/porcupine/tree/master/demo/vue).