Giter VIP home page Giter VIP logo

sound's Introduction

πŸ”Š @vueuse/sound

npm npm Netlify Status

  • πŸ‘‚ Lets your website communicate using 2 human senses instead of 1
  • πŸ”₯ Built with Vue Composition API
  • βœ… Supports Vue 2 & 3 using vue-demi
  • 🚚 Supports Nuxt 2 & 3 using @vueuse/sound/nuxt
  • ⚑️ <1kb bytes (gzip) in your bundle! ~10kb loaded async.
  • ✨ Built with TypeScript
  • πŸ—£ Uses a powerful, battle-tested audio utility: Howler.js

If you want to take a quick look at the composable in effect, you should visit the 🌍 demo.

This package is a Vue version of the useSound React hook by joshwcomeau.

Installation

Package can be added using yarn:

yarn add @vueuse/sound

Or, use NPM:

npm install @vueuse/sound

Examples

Play a sound on click

This is the most basic example of how fast you can implement sounds in your app using @vueuse/sound.

<template>
  <button @click="play">Play a sound</button>
</template>

<script>
import { useSound } from '@vueuse/sound'
import buttonSfx from '../assets/sounds/button.mp3'

export default {
  setup() {
    const { play } = useSound(buttonSfx)

    return {
      play,
    }
  },
}
</script>

Playing on hover

This example is shown in the demo.

Increase pitch on every click

This example is shown in the demo.

Usage Notes

No sounds immediately after load

For the user's sake, browsers don't allow websites to produce sound until the user has interacted with them (eg. by clicking on something). No sound will be produced until the user clicks, taps, or triggers something.

useSound takes advantage of this: because we know that sounds won't be needed immediately on-load, we can lazy-load a third-party dependency.

useSound will add about 1kb gzip to your bundle, and will asynchronously fetch an additional package after load, which clocks in around 9kb gzip.

If the user does happen to click with something that makes noise before this dependency has been loaded and fetched, it will be a no-op (everything will still work, but no sound effect will play). In my experience this is exceedingly rare.

Reactive configuration

Consider the following snippet of code:

const playbackRate = ref(0.75)

const { play } = useSound('/path/to/sound', { playbackRate })

playbackRate doesn't just serve as an initial value for the sound effect. If playbackRate changes, the sound will immediately begin playing at a new rate. This is true for all options passed to the useSound composable.

API Documentation

The useSound composable takes two arguments:

  • A URL to the sound that it wil load
  • A config object (ComposableOptions)

It produces an array with two values:

  • A function you can call to trigger the sound
  • An object with additional data and controls (ExposedData)

When calling the function to play the sound, you can pass it a set of options (PlayOptions).

Let's go through each of these in turn.

ComposableOptions

When calling useSound, you can pass it a variety of options:

Name Value
volume number
playbackRate number
interrupt boolean
soundEnabled boolean
sprite SpriteMap
[delegated] β€”
  • volume is a number from 0 to 1, where 1 is full volume and 0 is comletely muted.
  • playbackRate is a number from 0.5 to 4. It can be used to slow down or speed up the sample. Like a turntable, changes to speed also affect pitch.
  • interrupt specifies whether or not the sound should be able to "overlap" if the play function is called again before the sound has ended.
  • soundEnabled allows you to pass a value (typically from context or redux or something) to mute all sounds. Note that this can be overridden in the PlayOptions, see below
  • sprite allows you to use a single useSound composable for multiple sound effects. See β€œSprites” below.

[delegated] refers to the fact that any additional argument you pass in ComposableOptions will be forwarded to the Howl constructor. See "Escape hatches" below for more information.

The play function

When calling the composable, you get back a play function as the first item in the tuple:

const { play } = useSound('/meow.mp3')
//      ^ What we're talking about

You can call this function without any arguments when you want to trigger the sound. You can also call it with a PlayOptions object:

Name Value
id string
forceSoundEnabled boolean
playbackRate number
  • id is used for sprite identification. See β€œSprites” below.
  • forceSoundEnabled allows you to override the soundEnabled boolean passed to ComposableOptions. You generally never want to do this. The only exception I've found: triggering a sound on the "Mute" button.
  • playbackRate is another way you can set a new playback rate, same as in ComposableOptions. In general you should prefer to do it through ComposableOptions, this is an escape hatch.

ExposedData

The composable produces a tuple with 2 options, the play function and an ExposedData object:

const [play, exposedData] = useSound('/meow.mp3')
//                ^ What we're talking about
Name Value
stop function ((id?: string) => void)
pause function ((id?: string) => void)
isPlaying boolean
duration number (or null)
sound Howl (or null)
  • stop is a function you can use to pre-emptively halt the sound.
  • pause is like stop, except it can be resumed from the same point. Unless you know you'll want to resume, you should use stop; pause hogs resources, since it expects to be resumed at some point.
  • isPlaying lets you know whether this sound is currently playing or not. When the sound reaches the end, or it's interrupted with stop or paused, this value will flip back to false. You can use this to show some UI only while the sound is playing.
  • duration is the length of the sample, in milliseconds. It will be null until the sample has been loaded. Note that for sprites, it's the length of the entire file.
  • sound is an escape hatch. It grants you access to the underlying Howl instance. See the Howler documentation to learn more about how to use it. Note that this will be null for the first few moments after the component mounts.

Advanced

Sprites

An audio sprite is a single audio file that holds multiple samples. Instead of loading many individual sounds, you can load a single file and slice it up into multiple sections which can be triggered independently.

There can be a performance benefit to this, since it's less parallel network requests, but it can also be worth doing this if a single component needs multiple samples. See the Drum Machine component for an example.

For sprites, we'll need to define a SpriteMap. It looks like this:

const spriteMap = {
  laser: [0, 300],
  explosion: [1000, 300],
  meow: [2000, 75],
}

SpriteMap is an object. The keys are the ids for individual sounds. The value is a tuple (array of fixed length) with 2 items:

  • The starting time of the sample, in milliseconds, counted from the very beginning of the sample
  • The length of the sample, in milliseconds.

This visualization might make it clearer:

Waveform visualization showing how each sprite occupies a chunk of time, and is labeled by its start time and duration

We can pass our SpriteMap as one of our ComposableOptions:

const { play } = useSound('/path/to/sprite.mp3', {
  sprite: {
    laser: [0, 300],
    explosion: [1000, 300],
    meow: [2000, 75],
  },
})

To play a specific sprite, we'll pass its id when calling the play function:

<button
  @click="play({id: 'laser'})"
>

Escape hatches

Howler is a very powerful library, and we've only exposed a tiny slice of what it can do in useSound. We expose two escape hatches to give you more control.

First, any unrecognized option you pass to ComposableOptions will be delegated to Howl. You can see the full list of options in the Howler docs. Here's an example of how we can use onend to fire a function when our sound stops playing:

const { play } = useSound('/thing.mp3', {
  onend: () => {
    console.info('Sound ended!')
  },
})

If you need more control, you should be able to use the sound object directly, which is an instance of Howler.

For example: Howler exposes a fade method, which lets you fade a sound in or out. You can call this method directly on the sound object:

<template>
    <button
      @click={sound.fade(0, 1, 1000)}
    >
      Click to win
    </button>
</template>

<script>
import { useSound } from '@vueuse/sound'

export default {
    setup() {
        const { play, sound } = useSound('/win-theme.mp3')

        return {
            sound
        }
    }
}
</script>

Vite

If you are using Vite, you should add the following to your defineConfig options in vite.config.js:

optimizeDeps: {
  exclude: ['vue-demi']
}

Nuxt

If you use Nuxt 2, you must have @nuxt/bridge setup in your project.

Once you installed it, add @vueuse/sound/nuxt dependency to your project.

Add @vueuse/sound/nuxt to the modules section of your nuxt.config:

defineNuxtConfig({
  modules: ['@vueuse/sound/nuxt']
})

Configure your sounds πŸ₯:

defineNuxtConfig({
  sound: {
    sounds: {
      back: {
        src: "/back.wav",
        options: {
          volume: 0.25
        }
      }
    }
  }
})

You can also automatically scan an generate typings for your sounds in public/sounds directory by using scan feature:

defineNuxtConfig({
  sound: {
    sounds: {
      scan: true
    }
  }
})

Then move your sounds into public/sounds directory, and get autocompletion on useSound({url}).

Credits

All the credit behind this idea goes to Josh W. Comeau.

The documentation of this package has only been updated for Vue Composition API instead of React Hooks.

If you like this package, consider following me on GitHub and on Twitter.

sound's People

Contributors

antfu avatar ericwaetke avatar p-james avatar tahul avatar yunyoujun avatar yyqqing avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

sound's Issues

Playing Multiple Sounds

How can i use multiple sound source without using sprites?
Different buttons can be play different sounds

Could not find a declaration file for module '@vueuse/sound'

I have the following compilation error when running npm run build in a fresh Vue app:

src/App.vue:21:26 - error TS7016: Could not find a declaration file for module '@vueuse/sound'. 'C:/[...redacted...]/node_modules/@vueuse/sound/dist/index.mjs' implicitly has an 'any' type.
  There are types at 'C:/[...redacted...]/node_modules/@vueuse/sound/dist/index.d.ts', but this result could not be resolved when respecting package.json "exports". The '@vueuse/sound' library may need to update its package.json or typings.

21 import { useSound } from '@vueuse/sound';
                            ~~~~~~~~~~~~~~~


Found 1 error in src/App.vue:21

ERROR: "type-check" exited with 2.

The error goes away if I manually delete the exports key in package.json:

  "exports": {
    ".": {
      "require": "./dist/index.cjs",
      "import": "./dist/index.mjs"
    },
    "./nuxt": {
      "require": "./dist/nuxt.cjs",
      "import": "./dist/nuxt.mjs"
    }
  },

Do you have any clue to solve it?

TypeError: HowlConstructor.value is not a constructor

I just tried to use vueuse/sound in my Nuxt 3 project like so:

const {play} = useSound("/sounds/alert.mp3");

I am getting the following error:

Uncaught (in promise) TypeError: HowlConstructor.value is not a constructor

which is raised here.

@vueuse/sound version: 2.0.0
The howler version installed by my package manager is: 2.2.3.

Dependency Conflict in Nuxt3

My project is written using Nuxt3 and my project dependencies in package.json is shown as following

{
  "name": "nuxt-app",
  "private": true,
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "devDependencies": {
    "@nuxt/devtools": "latest",
    "@nuxtjs/color-mode": "^3.3.0",
    "@nuxtjs/supabase": "^0.3.8",
    "@pinia-plugin-persistedstate/nuxt": "^1.1.1",
    "@pinia/nuxt": "^0.4.11",
    "@types/node": "^18",
    "autoprefixer": "^10.4.14",
    "nuxt": "^3.5.2",
    "nuxt-icon": "^0.4.1",
    "postcss": "^8.4.24",
    "prettier": "^3.0.1",
    "prettier-plugin-tailwindcss": "^0.5.2",
    "tailwindcss": "^3.3.2"
  },
  "dependencies": {
    "@headlessui/vue": "^1.7.14",
    "@heroicons/vue": "^2.0.18",
    "@vueuse/core": "^10.2.1",
    "@vueuse/nuxt": "^10.3.0",
    "nuxt-headlessui": "^1.1.4",
    "nuxt-storage": "^1.2.2",
    "pinia": "^2.1.4"
  }
}

I tried install this using the following command

npm install @vueuse/sound

It returned following error (this is a full log file)

'Log files:
C:\Users\admin\AppData\Local\npm-cache\_logs\2023-08-22T08_43_25_691Z-debug-0.log

# npm resolution error report

While resolving: nuxt-app@undefined
Found: [email protected]
node_modules/vue
  peer vue@"^3.2.0" from @headlessui/[email protected]
  node_modules/@headlessui/vue
    @headlessui/vue@"^1.0.0" from [email protected]
    node_modules/nuxt-headlessui
      nuxt-headlessui@"^1.1.4" from the root project
    @headlessui/vue@"^1.7.14" from the root project
  peer vue@">= 3" from @heroicons/[email protected]
  node_modules/@heroicons/vue
    @heroicons/vue@"^2.0.18" from the root project
  peer vue@">=3" from @iconify/[email protected]
  node_modules/@iconify/vue
    @iconify/vue@"^4.1.1" from [email protected]
    node_modules/nuxt-icon
      dev nuxt-icon@"^0.4.1" from the root project
  peer vue@"^3.3.4" from @nuxt/[email protected]
  node_modules/@nuxt/vite-builder
    @nuxt/vite-builder@"3.6.5" from [email protected]
    node_modules/nuxt
      peer nuxt@"^3.6.1" from @nuxt/[email protected]
      node_modules/@nuxt/devtools
        dev @nuxt/devtools@"latest" from the root project
      peer nuxt@"^3.6.1" from @nuxt/[email protected]
      node_modules/@nuxt/devtools-kit
        @nuxt/devtools-kit@"0.6.7" from @nuxt/[email protected]
        node_modules/@nuxt/devtools
          dev @nuxt/devtools@"latest" from the root project
      nuxt@"^3.6.5" from @vueuse/[email protected]
      node_modules/@vueuse/nuxt
        @vueuse/nuxt@"^10.3.0" from the root project
      dev nuxt@"^3.5.2" from the root project
  peer vue@">=2.7 || >=3" from @unhead/[email protected]
  node_modules/@unhead/vue
    @unhead/vue@"^1.1.30" from [email protected]
    node_modules/nuxt
      peer nuxt@"^3.6.1" from @nuxt/[email protected]
      node_modules/@nuxt/devtools
        dev @nuxt/devtools@"latest" from the root project
      peer nuxt@"^3.6.1" from @nuxt/[email protected]
      node_modules/@nuxt/devtools-kit
        @nuxt/devtools-kit@"0.6.7" from @nuxt/[email protected]
        node_modules/@nuxt/devtools
          dev @nuxt/devtools@"latest" from the root project
      nuxt@"^3.6.5" from @vueuse/[email protected]
      node_modules/@vueuse/nuxt
        @vueuse/nuxt@"^10.3.0" from the root project
      dev nuxt@"^3.5.2" from the root project
  peer vue@"^3.2.25" from @vitejs/[email protected]
  node_modules/@vitejs/plugin-vue
    @vitejs/plugin-vue@"^4.2.3" from @nuxt/[email protected]
    node_modules/@nuxt/vite-builder
      @nuxt/vite-builder@"3.6.5" from [email protected]
      node_modules/nuxt
        peer nuxt@"^3.6.1" from @nuxt/[email protected]
        node_modules/@nuxt/devtools
          dev @nuxt/devtools@"latest" from the root project
        peer nuxt@"^3.6.1" from @nuxt/[email protected]
        node_modules/@nuxt/devtools-kit
          @nuxt/devtools-kit@"0.6.7" from @nuxt/[email protected]
          node_modules/@nuxt/devtools
            dev @nuxt/devtools@"latest" from the root project
        nuxt@"^3.6.5" from @vueuse/[email protected]
        node_modules/@vueuse/nuxt
          @vueuse/nuxt@"^10.3.0" from the root project
        dev nuxt@"^3.5.2" from the root project
  peer vue@"^3.0.0" from @vitejs/[email protected]
  node_modules/@vitejs/plugin-vue-jsx
    @vitejs/plugin-vue-jsx@"^3.0.1" from @nuxt/[email protected]
    node_modules/@nuxt/vite-builder
      @nuxt/vite-builder@"3.6.5" from [email protected]
      node_modules/nuxt
        peer nuxt@"^3.6.1" from @nuxt/[email protected]
        node_modules/@nuxt/devtools
          dev @nuxt/devtools@"latest" from the root project
        peer nuxt@"^3.6.1" from @nuxt/[email protected]
        node_modules/@nuxt/devtools-kit
          @nuxt/devtools-kit@"0.6.7" from @nuxt/[email protected]
          node_modules/@nuxt/devtools
            dev @nuxt/devtools@"latest" from the root project
        nuxt@"^3.6.5" from @vueuse/[email protected]
        node_modules/@vueuse/nuxt
          @vueuse/nuxt@"^10.3.0" from the root project
        dev nuxt@"^3.5.2" from the root project
  peerOptional vue@"^2.7.0 || ^3.2.25" from @vue-macros/[email protected]
  node_modules/@vue-macros/common
    @vue-macros/common@"^1.3.1" from [email protected]
    node_modules/unplugin-vue-router
      unplugin-vue-router@"^0.6.4" from [email protected]
      node_modules/nuxt
        peer nuxt@"^3.6.1" from @nuxt/[email protected]
        node_modules/@nuxt/devtools
          dev @nuxt/devtools@"latest" from the root project
        peer nuxt@"^3.6.1" from @nuxt/[email protected]
        node_modules/@nuxt/devtools-kit
          @nuxt/devtools-kit@"0.6.7" from @nuxt/[email protected]
          node_modules/@nuxt/devtools
            dev @nuxt/devtools@"latest" from the root project
        nuxt@"^3.6.5" from @vueuse/[email protected]
        node_modules/@vueuse/nuxt
          @vueuse/nuxt@"^10.3.0" from the root project
        dev nuxt@"^3.5.2" from the root project
  peer vue@"3.3.4" from @vue/[email protected]
  node_modules/@vue/server-renderer
    @vue/server-renderer@"3.3.4" from [email protected]
  peer vue@"^3.0.0-0 || ^2.6.0" from [email protected]
  node_modules/@vueuse/core/node_modules/vue-demi
    vue-demi@">=0.14.5" from @vueuse/[email protected]
    node_modules/@vueuse/core
      @vueuse/core@"10.3.0" from @vueuse/[email protected]
      node_modules/@vueuse/nuxt
        @vueuse/nuxt@"^10.3.0" from the root project
      @vueuse/core@"^10.2.1" from the root project
  peer vue@"^3.0.0-0 || ^2.6.0" from [email protected]
  node_modules/@vueuse/nuxt/node_modules/vue-demi
    vue-demi@">=0.14.5" from @vueuse/[email protected]
    node_modules/@vueuse/nuxt
      @vueuse/nuxt@"^10.3.0" from the root project
  peer vue@"^3.0.0-0 || ^2.6.0" from [email protected]
  node_modules/@vueuse/shared/node_modules/vue-demi
    vue-demi@">=0.14.5" from @vueuse/[email protected]
    node_modules/@vueuse/shared
      @vueuse/shared@"10.3.0" from @vueuse/[email protected]
      node_modules/@vueuse/core
        @vueuse/core@"10.3.0" from @vueuse/[email protected]
        node_modules/@vueuse/nuxt
          @vueuse/nuxt@"^10.3.0" from the root project
        @vueuse/core@"^10.2.1" from the root project
  vue@"^3.3.4" from [email protected]
  node_modules/nuxt
    peer nuxt@"^3.6.1" from @nuxt/[email protected]
    node_modules/@nuxt/devtools
      dev @nuxt/devtools@"latest" from the root project
    peer nuxt@"^3.6.1" from @nuxt/[email protected]
    node_modules/@nuxt/devtools-kit
      @nuxt/devtools-kit@"0.6.7" from @nuxt/[email protected]
      node_modules/@nuxt/devtools
        dev @nuxt/devtools@"latest" from the root project
    nuxt@"^3.6.5" from @vueuse/[email protected]
    node_modules/@vueuse/nuxt
      @vueuse/nuxt@"^10.3.0" from the root project
    dev nuxt@"^3.5.2" from the root project
  peer vue@"^2.6.14 || ^3.3.0" from [email protected]
  node_modules/pinia
    pinia@">=2.1.0" from @pinia/[email protected]
    node_modules/@pinia/nuxt
      peer @pinia/nuxt@"^0.4.4" from @pinia-plugin-persistedstate/[email protected]
      node_modules/@pinia-plugin-persistedstate/nuxt
        dev @pinia-plugin-persistedstate/nuxt@"^1.1.1" from the root project
      dev @pinia/nuxt@"^0.4.11" from the root project
    peer pinia@"^2.0.0" from [email protected]
    node_modules/pinia-plugin-persistedstate
      pinia-plugin-persistedstate@">=3.1.0" from @pinia-plugin-persistedstate/[email protected]
      node_modules/@pinia-plugin-persistedstate/nuxt
        dev @pinia-plugin-persistedstate/nuxt@"^1.1.1" from the root project
    pinia@"^2.1.4" from the root project
  peer vue@"^3.0.0-0 || ^2.6.0" from [email protected]
  node_modules/pinia/node_modules/vue-demi
    vue-demi@">=0.14.5" from [email protected]
    node_modules/pinia
      pinia@">=2.1.0" from @pinia/[email protected]
      node_modules/@pinia/nuxt
        peer @pinia/nuxt@"^0.4.4" from @pinia-plugin-persistedstate/[email protected]
        node_modules/@pinia-plugin-persistedstate/nuxt
          dev @pinia-plugin-persistedstate/nuxt@"^1.1.1" from the root project
        dev @pinia/nuxt@"^0.4.11" from the root project
      peer pinia@"^2.0.0" from [email protected]
      node_modules/pinia-plugin-persistedstate
        pinia-plugin-persistedstate@">=3.1.0" from @pinia-plugin-persistedstate/[email protected]
        node_modules/@pinia-plugin-persistedstate/nuxt
          dev @pinia-plugin-persistedstate/nuxt@"^1.1.1" from the root project
      pinia@"^2.1.4" from the root project
  peer vue@"^3.2.0" from [email protected]
  node_modules/vue-router
    vue-router@"^4.2.4" from [email protected]
    node_modules/nuxt
      peer nuxt@"^3.6.1" from @nuxt/[email protected]
      node_modules/@nuxt/devtools
        dev @nuxt/devtools@"latest" from the root project
      peer nuxt@"^3.6.1" from @nuxt/[email protected]
      node_modules/@nuxt/devtools-kit
        @nuxt/devtools-kit@"0.6.7" from @nuxt/[email protected]
        node_modules/@nuxt/devtools
          dev @nuxt/devtools@"latest" from the root project
      nuxt@"^3.6.5" from @vueuse/[email protected]
      node_modules/@vueuse/nuxt
        @vueuse/nuxt@"^10.3.0" from the root project
      dev nuxt@"^3.5.2" from the root project
    peerOptional vue-router@"^4.1.0" from [email protected]
    node_modules/unplugin-vue-router
      unplugin-vue-router@"^0.6.4" from [email protected]
      node_modules/nuxt
        peer nuxt@"^3.6.1" from @nuxt/[email protected]
        node_modules/@nuxt/devtools
          dev @nuxt/devtools@"latest" from the root project
        peer nuxt@"^3.6.1" from @nuxt/[email protected]
        node_modules/@nuxt/devtools-kit
          @nuxt/devtools-kit@"0.6.7" from @nuxt/[email protected]
          node_modules/@nuxt/devtools
            dev @nuxt/devtools@"latest" from the root project
        nuxt@"^3.6.5" from @vueuse/[email protected]
        node_modules/@vueuse/nuxt
          @vueuse/nuxt@"^10.3.0" from the root project
        dev nuxt@"^3.5.2" from the root project

Could not resolve dependency:
@vueuse/sound@"*" from the root project

Conflicting peer dependency: [email protected]
node_modules/vue
  peer vue@">= 2.5 < 2.7" from @vue/[email protected]
  node_modules/@vue/composition-api
    peerOptional @vue/composition-api@"^1.0.0-rc.1" from @vueuse/[email protected]
    node_modules/@vueuse/sound
      @vueuse/sound@"*" from the root project

Fix the upstream dependency conflict, or retry
this command with --force or --legacy-peer-deps
to accept an incorrect (and potentially broken) dependency resolution.

Have you previously encountered this issue, or would you happen to possess insights on its resolution? Thank you in advance!

duration always 0

I think this code is wrong.

duration.value = duration.value ? duration.value * 1000 : 0

Sounds are not played in Safari

Hello,

Sound are not played in Safari but all works fine in chrome and firefox, do you have an idea to resolve this problem ?

<template>
  <button @mousedown="playSound($event)"></button>
</template>

<script>
import { useSound } from "@vueuse/sound";

export default {
  name: "Pad",
  setup(props) {
    const { play, stop } = useSound(props.soundURL, { interrupt: true });

    return {
      play,
      stop,
    };
  },
  methods: {
    playSound(event) {
      if (!event.repeat) {
        this.play();
      }
    },
  },
  props: ["soundURL"],
  beforeUnmount() {
    this.stop();
  },
};
</script>

File-Loader

This isn't strictly speaking an issue with the package, I'm just really struggling here, and I could imagine others too!

I'm currently not as experienced as I probably should be with anything regarding webpack/babel etc. Therefore, I have no Idea how to fix following issue

Module parse failed: Unexpected token (34:28)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|     };
|     watch(() => [url], () => {
>         if (HowlConstructor?.value && sound?.value) {
|             sound.value = new HowlConstructor.value({
|                 src: [url],

 @ ./node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/App.vue?vue&type=script&lang=js 3:0-37 14:12-20
 @ ./src/App.vue?vue&type=script&lang=js
 @ ./src/App.vue
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.178.20:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

I've tried installing the webpack file-loader, but that failed since I don't think I use Webpack but Babel in Vue 3. (Also my first Vue 3 project, I've only worked in Vue 2 before)

I've tried babel-plugin-file-loader with this configuration (basically the standard one with mp3 added as extensions)

"plugins": [
    [
      "file-loader",
      {
        "name": "[hash].[ext]",
        "extensions": ["png", "jpg", "jpeg", "gif", "svg", "mp3"],
        "publicPath": "/public",
        "outputPath": "/public",
        "context": "/src",
        "limit": 0
      }
    ]
  ]

But the error still occurs. I'm honestly just really lost with this whole loader thing, if you could include an example loader-config or something like that when you have time, that'd be awesome!

Fade is not a function

Trying to access the method "fade" out of the "sound" object doesnt work, as the "fade" is undefined

The AudioContext was not allowed to start

Using the vue setup composition api here:

<script setup lang="ts">
import ping from './assets/ping.wav';
import { useSound } from '@vueuse/sound';

const pingSound = useSound(ping);

async function clickTheButton() {
    pingSound.play();
}
</script>

Everything works as it should but the console leaves a warning on loading the component (clickTheButton is not yet triggered):

The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.

Using Vue3.2.45 and Vite 4.1.0

Is there a way to avoid these warnings?

error in vue2 with typescript

Thank you to share this amazing project. But I got some problems with setup on my vue2 project.

ERROR in /Users/---/Developer/**/node_modules/@vueuse/sound/dist/esm/src/types.d.ts
1:35 Could not find a declaration file for module 'howler'. '/Users/---/Developer/---/node_modules/howler/dist/howler.js' implicitly has an 'any' type.
Try npm install @types/howler if it exists or add a new declaration (.d.ts) file containing declare module 'howler';

1 | import { Howl, HowlOptions } from 'howler';
| ^
2 | import { ComputedRef, Ref } from 'vue-demi';
3 | export interface HowlStatic {
4 | new (properties: HowlOptions): Howl;
No lint errors found

Bump vue to vue 3.0.4

Please bump vue to the latest version. Right now it does not wanna install in my vue 3 project!

TypeError: Cannot read properties of undefined (reading 'version')

I'm getting this error when trying to use in my Vue3 project. Anybody encountered this before?

TypeError: Cannot read properties of undefined (reading 'version')
at eval (index.mjs?4c81:15)
at Module../node_modules/@vueuse/sound/node_modules/vue-demi/lib/index.mjs (home.js:59)
at webpack_require (app.js:854)
at fn (app.js:151)
at eval (index.js?af75:1)
at Module../node_modules/@vueuse/sound/dist/esm/index.js (home.js:35)
at webpack_require (app.js:854)
at fn (app.js:151)
at eval (cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader-v16/dist/index.js?!./src/views/Game.vue?vue&type=script&lang=js:3)
at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader-v16/dist/index.js?!./src/views/Game.vue?vue&type=script&lang=js (home.js:131)

Basically, what I'm trying to achieve is to play the audio when user clicks 'yes' on the <Modal /> component which emits startGame

Here is the code:

<template>
  <Modal @startGame="startGame" />
</template>

<script>
import { useSound } from '@vueuse/sound'
import bgAudio from '@/assets/audio/stranger-things.mp3'

export default {
  setup() {
      const { play } = useSound(bgAudio)

     const startGame = () => {
        /* other codes here */
        play()
    }
    return {
      startGame
    }
  }
}
</script>

Doesn't work in production mode

I'm using this lib and work perfectly in local development mode, but when i deployed to netlify the sound doesn't work with no error. Does anybody have the same issue?

Problem when deploying to firebase

<template>   
  <nav @click="doorSoundPlay()" id="nav" class="flex items-center">     
        <router-link to="/">Bridge</router-link>
        <router-link @click="doorSoundPlay()"  to="/worlds">Research Lab</router-link>
        <router-link to="/formssummary">Mission Deck</router-link>
        <router-link  to="/dashboard">Resource Library</router-link>
      </nav>
</template>
<script>
import { useSound } from '@vueuse/sound';
import doorsFx from '../assets/sound/filename.mp3';

 setup() {
    const { doorSound } = useSound(doorsFx)

    return {
     doorSound,
    }
  },
  methods: {
    signOut() {
      firebase
        .auth()
        .signOut()
        .then(() => {
          this.$router.replace("sign-in");
        });
    },
     doorSoundPlay(){
            console.log(this.doorSound)
       this.doorSound.play();
       }
  }
</script>

works fine with yarn serve but after I deploy it, doorSound returns undefined. any ideas? Thank you in advance for this great package.

Cannot use import statement outside a module

Hi !
Jest raises an error when I try to run my test with npm run test:unit :

   /home/nicolas/repo/smooth-pomodoro/node_modules/@vueuse/sound/dist/index.mjs:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { ref, onMounted, unref, watch } from 'vue-demi';

      SyntaxError: Cannot use import statement outside a module                                 

If you want to reproduce, here is the link of the project, the branch is use-vueuse-for-sound

PS : thanks for the module, it's super cool !

no effect

ex:

const props = defineProps(['url'])
const { duration } = useSound(props.url)

when url change, the duration still old

δΈ€δΈͺθ­¦ε‘Š

dependencies:

  • @vueuse/sound 1.1.7
  • lingo3d-vue 1.0.49
  • vue 3.2.33

devDependencies:

  • @vitejs/plugin-vue 2.3.2
  • typescript 4.6.4
  • vite 2.9.8
  • vue-tsc 0.29.8

 WARN  Issues with peer dependencies found
.
└─┬ @vueuse/sound
└─┬ @vue/composition-api
└── βœ• unmet peer vue@">= 2.5 < 3": found 3.2.3

Reactive Volume

Reactive Playback-Rate works perfectly fine.

The reactive volume should work too, since it uses the same watcher and is updated/set the same way as the playbackRate, I do however get following error

Uncaught (in promise) TypeError: AudioParam.setValueAtTime: Argument 1 is not a finite floating-point value.

The error occurs right on load, I can't even update the volume ref.

const volume = ref(0.5);
const [press] = useSound(buttonPress, {volume})

I don't see what's the difference between the playbackRate value and the volume value, and I haven't looked into this further yet, so I don't know what's causing this error.

[Suggestion] Replace Vue demi with native Vue 3 composition api

It seems the package from the standard npm install is broken in two places as mentioned in the other issues before.

Since Nuxt 3 and Vue 3 are now the default version people would work/start working with I think Vue demi can be replaced with native Vue 3 (with <script setup>).

Not work with vite 2

erro:

onMounted is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup().

Type errors when using Ref<number> for volume

I'm likely doing something wrong, or it is an unrelated IDE issue. I am getting an error: Type Ref<number> is not assignable to type '(MaybeRef<number> & number) | undefined when I do the following:

const systemSoundVolume = ref(0.5)
const notification = useSound('url-to-asset', {
volume: systemSoundVolume // error here
})

Any ideas?

For additional context, I manage all the app audio in an audioStore using pinia. So, this is not in the setup function of a component.

The sound need stop automatically

Now, if i play a sound with the loop option, i have to stop it manually when my component unmount.
I think the current howl object should be unload when the url update or the component unmount.

howler.default is undefined

Uncaught (in promise) TypeError:

My code:

<script setup lang="ts">
import { useSound } from "@vueuse/sound";

const { play } = useSound("pop.mp3");
</script>

<template>
<button
  @click="play()"
>
</template>

my nuxt.config.ts:

export default defineNuxtConfig({
  css: ["@/assets/css/main.css"],
  devtools: {
    enabled: true,
  },
  components: [{ path: "@/components/home", prefix: "Home" }, "~/components"],

  modules: [
    "@vueuse/nuxt",
    "@vueuse/motion/nuxt",
    "@vueuse/sound/nuxt",]

  sound: {
    scan: "~/assets/sounds",
  },

  runtimeConfig: {
    public: {
      baseURL: process.env.BASE_URL,
    },
  },

  app: {
    head: {
      link: [{ rel: "icon", type: "image/png", href: "/logo.png" }],
    },
  },
});

My package.json:

{
  "name": "mob-website",
  "type": "module",
  "private": true,
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare",
    "lint": "eslint .",
    "lint:fix": "eslint . --fix"
  },
  "dependencies": {
    "@formkit/icons": "^0.19.3",
    "@formkit/nuxt": "^0.19.3",
    "@formkit/themes": "^0.19.3",
    "@nuxt/image": "^1.0.0-rc.1",
    "@nuxtjs/eslint-module": "^4.1.0",
    "@pinia/nuxt": "^0.4.11",
    "@vee-validate/nuxt": "^4.11.2",
    "@vee-validate/yup": "^4.11.2",
    "@vueuse/motion": "^2.0.0",
    "@vueuse/sound": "^2.0.1",
    "eslint-plugin-tailwindcss": "^3.13.0",
    "flipbook-vue": "^1.0.0-beta.4",
    "nuxt-gtag": "^0.6.1",
    "nuxt-icon": "^0.5.0",
    "nuxt-storage": "^1.2.2",
    "nuxt-swiper": "^1.2.0",
    "nuxt-viewport": "^2.0.6",
    "vee-validate": "^4.11.2",
    "vue3-google-map": "^0.17.1",
    "yup": "^1.2.0"
  },
  "devDependencies": {
    "@nuxt/devtools": "^0.8.2",
    "@nuxt/eslint-config": "^0.1.1",
    "@nuxtjs/google-fonts": "^3.0.2",
    "@nuxtjs/i18n": "8.0.0-rc.3",
    "@types/node": "^18.17.3",
    "@types/qs": "^6.9.7",
    "@typescript-eslint/eslint-plugin": "^6.4.0",
    "@typescript-eslint/parser": "^6.4.0",
    "@vueuse/core": "^10.3.0",
    "@vueuse/nuxt": "^10.3.0",
    "autoprefixer": "^10.4.15",
    "eslint": "^8.47.0",
    "eslint-plugin-vue": "^9.17.0",
    "nuxt": "^3.6.5",
    "postcss": "^8.4.28",
    "tailwindcss": "^3.3.3"
  },
  "overrides": {
    "vue": "latest"
  }
}

I got error npm ERR! Conflicting peer dependency: [email protected]

This library seems useful for my project then I using Vue 3 Composition API which version is 3.2.31 and also Vite version 2.5.4. My Install got problem and return this error code:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/vue
npm ERR!   peer vue@">= 3.0.0 < 4" from @fortawesome/[email protected]
npm ERR!   node_modules/@fortawesome/vue-fontawesome
npm ERR!     @fortawesome/vue-fontawesome@"^3.0.0-5" from the root project
npm ERR!   peer vue@"next" from @handsontable/[email protected]
npm ERR!   node_modules/@handsontable/vue3
npm ERR!     @handsontable/vue3@"^12.3.0" from the root project
npm ERR!   28 more (@highlightjs/vue-plugin, @kyvg/vue3-notification, ...)
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! @vueuse/sound@"*" from the root project
npm ERR! 
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/vue
npm ERR!   peer vue@">= 2.5 < 2.7" from @vue/[email protected]
npm ERR!   node_modules/@vue/composition-api
npm ERR!     peerOptional @vue/composition-api@"^1.0.0-rc.1" from @vueuse/[email protected]
npm ERR!     node_modules/@vueuse/sound
npm ERR!       @vueuse/sound@"*" from the root project
npm ERR! 
julapps@Juls-Air gundu % npm install @vueuse/sound
npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/vue
npm ERR!   peer vue@">= 3.0.0 < 4" from @fortawesome/[email protected]
npm ERR!   node_modules/@fortawesome/vue-fontawesome
npm ERR!     @fortawesome/vue-fontawesome@"^3.0.0-5" from the root project
npm ERR!   peer vue@"next" from @handsontable/[email protected]
npm ERR!   node_modules/@handsontable/vue3
npm ERR!     @handsontable/vue3@"^12.3.0" from the root project
npm ERR!   28 more (@highlightjs/vue-plugin, @kyvg/vue3-notification, ...)
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! @vueuse/sound@"*" from the root project
npm ERR! 
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/vue
npm ERR!   peer vue@">= 2.5 < 2.7" from @vue/[email protected]
npm ERR!   node_modules/@vue/composition-api
npm ERR!     peerOptional @vue/composition-api@"^1.0.0-rc.1" from @vueuse/[email protected]
npm ERR!     node_modules/@vueuse/sound
npm ERR!       @vueuse/sound@"*" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /Users/julapps/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/julapps/.npm/_logs/2023-04-15T01_58_25_131Z-debug-0.log

Anyone can Help?

Not work in Vuejs 3

Failed to compile.

./node_modules/@vueuse/sound/dist/index.mjs 11:52
Module parse failed: Unexpected token (11:52)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| if (typeof onload === "function")
| onload.call(this);

duration.value = (duration.value || sound.value?.duration() || 0) * 1e3;

| if (autoplay === true) {
| isPlaying.value = true;

Nuxt not working with sound

Hi @Tahul ,

You asked for my experience with nuxt and this package. I tried to get it to work after the latest update, but it seems like it doesn't work. I have a sound in my public folder like this : public/sounds/back.wav

image

`<script setup>
import { useSound } from '@vueuse/sound'

const { play, sound } = useSound('/sounds/back.wav')
</script>

test `

This is my test component

modules: ['@vueuse/sound/nuxt'] sound: { sounds: { scan: true, }, },

Did I have something wrong or do I need to change something to get it to work?

Thanks in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.