Gathering detailed insights and metrics for @raffaelesgarro/vue-use-sound
Gathering detailed insights and metrics for @raffaelesgarro/vue-use-sound
Gathering detailed insights and metrics for @raffaelesgarro/vue-use-sound
Gathering detailed insights and metrics for @raffaelesgarro/vue-use-sound
npm install @raffaelesgarro/vue-use-sound
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
500 Stars
146 Commits
26 Forks
4 Watching
1 Branches
19 Contributors
Updated on 28 Nov 2024
Minified
Minified + Gzipped
TypeScript (90.83%)
JavaScript (9.17%)
Cumulative downloads
Total Downloads
Last day
-33.4%
608
Compared to previous day
Last week
-19.5%
3,749
Compared to previous week
Last month
1,170.1%
11,685
Compared to previous month
Last year
4,680.5%
16,923
Compared to previous year
2
@vueuse/sound/nuxt
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.
Package can be added using yarn:
1yarn add @vueuse/sound
Or, use NPM:
1npm install @vueuse/sound
This is the most basic example of how fast you can implement sounds in your app using @vueuse/sound.
1<template> 2 <button @click="play">Play a sound</button> 3</template> 4 5<script> 6import { useSound } from '@vueuse/sound' 7import buttonSfx from '../assets/sounds/button.mp3' 8 9export default { 10 setup() { 11 const { play } = useSound(buttonSfx) 12 13 return { 14 play, 15 } 16 }, 17} 18</script>
This example is shown in the demo.
This example is shown in the demo.
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.
Consider the following snippet of code:
1const playbackRate = ref(0.75)
2
3const { 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.
The useSound
composable takes two arguments:
ComposableOptions
)It produces an array with two values:
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.
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 belowsprite
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.
play
functionWhen calling the composable, you get back a play function as the first item in the tuple:
1const { play } = useSound('/meow.mp3') 2// ^ 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.The composable produces a tuple with 2 options, the play function and an ExposedData
object:
1const [play, exposedData] = useSound('/meow.mp3') 2// ^ 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.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:
1const spriteMap = { 2 laser: [0, 300], 3 explosion: [1000, 300], 4 meow: [2000, 75], 5}
SpriteMap
is an object. The keys are the id
s for individual sounds. The value is a tuple (array of fixed length) with 2 items:
This visualization might make it clearer:
We can pass our SpriteMap as one of our ComposableOptions:
1const { play } = useSound('/path/to/sprite.mp3', { 2 sprite: { 3 laser: [0, 300], 4 explosion: [1000, 300], 5 meow: [2000, 75], 6 }, 7})
To play a specific sprite, we'll pass its id
when calling the play
function:
1<button 2 @click="play({id: 'laser'})" 3>
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:
1const { play } = useSound('/thing.mp3', { 2 onend: () => { 3 console.info('Sound ended!') 4 }, 5})
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:
1<template> 2 <button 3 @click={sound.fade(0, 1, 1000)} 4 > 5 Click to win 6 </button> 7</template> 8 9<script> 10import { useSound } from '@vueuse/sound' 11 12export default { 13 setup() { 14 const { play, sound } = useSound('/win-theme.mp3') 15 16 return { 17 sound 18 } 19 } 20} 21</script>
If you are using Vite, you should add the following to your defineConfig options in vite.config.js:
1optimizeDeps: { 2 exclude: ['vue-demi'] 3}
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
:
1defineNuxtConfig({
2 modules: ['@vueuse/sound/nuxt']
3})
Configure your sounds 🥁:
1defineNuxtConfig({ 2 sound: { 3 sounds: { 4 back: { 5 src: "/back.wav", 6 options: { 7 volume: 0.25 8 } 9 } 10 } 11 } 12})
You can also automatically scan an generate typings for your sounds in public/sounds
directory by using scan feature:
1defineNuxtConfig({ 2 sound: { 3 sounds: { 4 scan: true 5 } 6 } 7})
Then move your sounds into public/sounds
directory, and get autocompletion on useSound({url})
.
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.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 5/30 approved changesets -- score normalized to 1
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
38 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More