Comparing version 2.0.2 to 2.1.0
import { HookOptions, ReturnedValue } from './types'; | ||
export default function useSound(url: string, { volume, playbackRate, soundEnabled, interrupt, onload, ...delegated }?: HookOptions): ReturnedValue; | ||
export default function useSound<T = any>(src: string | string[], { volume, playbackRate, soundEnabled, interrupt, onload, ...delegated }?: HookOptions<T>): ReturnedValue; | ||
export { useSound }; |
@@ -5,3 +5,3 @@ /// <reference types="howler" /> | ||
}; | ||
export interface HookOptions { | ||
export declare type HookOptions<T = any> = T & { | ||
volume?: number; | ||
@@ -13,3 +13,3 @@ playbackRate?: number; | ||
onload?: () => void; | ||
} | ||
}; | ||
export interface PlayOptions { | ||
@@ -16,0 +16,0 @@ id?: string; |
@@ -66,3 +66,3 @@ 'use strict'; | ||
function useSound(url, _ref) { | ||
function useSound(src, _ref) { | ||
if (_ref === void 0) { | ||
@@ -119,3 +119,3 @@ _ref = {}; | ||
var _sound = new HowlConstructor.current(_extends({ | ||
src: [url], | ||
src: Array.isArray(src) ? src : [src], | ||
volume: volume, | ||
@@ -132,3 +132,3 @@ rate: playbackRate, | ||
}; | ||
}); // When the URL changes, we have to do a whole thing where we recreate | ||
}); // When the `src` changes, we have to do a whole thing where we recreate | ||
// the Howl instance. This is because Howler doesn't expose a way to | ||
@@ -140,3 +140,3 @@ // tweak the sound | ||
setSound(new HowlConstructor.current(_extends({ | ||
src: [url], | ||
src: Array.isArray(src) ? src : [src], | ||
volume: volume, | ||
@@ -147,6 +147,9 @@ onload: handleLoad | ||
// but very specifically I only want to recreate the Howl instance | ||
// when the `url` changes. Other changes should have no effect. | ||
// when the `src` changes. Other changes should have no effect. | ||
// Passing array to the useEffect dependencies list will result in | ||
// ifinite loop so we need to stringify it, for more details check | ||
// https://github.com/facebook/react/issues/14476#issuecomment-471199055 | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [url]); // Whenever volume/playbackRate are changed, change those properties | ||
}, [JSON.stringify(src)]); // Whenever volume/playbackRate are changed, change those properties | ||
// on the sound instance. | ||
@@ -230,2 +233,3 @@ | ||
exports.default = useSound; | ||
exports.useSound = useSound; | ||
//# sourceMappingURL=use-sound.cjs.development.js.map |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=require("react"),n=(e=t)&&"object"==typeof e&&"default"in e?e.default:e;function r(){return(r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}exports.default=function(e,u){void 0===u&&(u={});var o=u.volume,a=void 0===o?1:o,c=u.playbackRate,i=void 0===c?1:c,l=u.soundEnabled,f=void 0===l||l,s=u.interrupt,d=void 0!==s&&s,p=u.onload,v=function(e,t){if(null==e)return{};var n,r,u={},o=Object.keys(e);for(r=0;r<o.length;r++)t.indexOf(n=o[r])>=0||(u[n]=e[n]);return u}(u,["volume","playbackRate","soundEnabled","interrupt","onload"]),b=n.useRef(null),y=n.useRef(!1),O=n.useState(!1),h=O[0],k=O[1],g=n.useState(null),j=g[0],m=g[1],w=n.useState(null),E=w[0],P=w[1],R=function(){"function"==typeof p&&p.call(this),y.current&&m(1e3*this.duration())};t.useEffect((function(){return new Promise((function(e){e(function(e){if(e&&e.__esModule)return e;var t={};return e&&Object.keys(e).forEach((function(n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})})),t.default=e,t}(require("howler")))})).then((function(t){if(!y.current){b.current=t.Howl,y.current=!0;var n=new b.current(r({src:[e],volume:a,rate:i,onload:R},v));P(n)}})),function(){y.current=!1}}),[]),n.useEffect((function(){b.current&&E&&P(new b.current(r({src:[e],volume:a,onload:R},v)))}),[e]),n.useEffect((function(){E&&(E.volume(a),E.rate(i))}),[a,i]);var S=n.useCallback((function(e){void 0===e&&(e={}),E&&(f||e.forceSoundEnabled)&&(d&&E.stop(),e.playbackRate&&E.rate(e.playbackRate),E.play(e.id),y.current&&E.once("end",(function(){E.playing()||k(!1)})),y.current&&k(!0))}),[E,f,d]),_=n.useCallback((function(e){E&&(E.stop(e),y.current&&k(!1))}),[E]),x=n.useCallback((function(e){E&&(E.pause(e),y.current&&k(!1))}),[E]);return[S,{sound:E,stop:_,pause:x,isPlaying:h,duration:j}]}; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=require("react"),r=(e=t)&&"object"==typeof e&&"default"in e?e.default:e;function n(){return(n=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}function u(e,u){void 0===u&&(u={});var o=u.volume,a=void 0===o?1:o,c=u.playbackRate,i=void 0===c?1:c,l=u.soundEnabled,f=void 0===l||l,s=u.interrupt,d=void 0!==s&&s,p=u.onload,v=function(e,t){if(null==e)return{};var r,n,u={},o=Object.keys(e);for(n=0;n<o.length;n++)t.indexOf(r=o[n])>=0||(u[r]=e[r]);return u}(u,["volume","playbackRate","soundEnabled","interrupt","onload"]),y=r.useRef(null),b=r.useRef(!1),O=r.useState(!1),g=O[0],h=O[1],k=r.useState(null),j=k[0],m=k[1],w=r.useState(null),E=w[0],P=w[1],R=function(){"function"==typeof p&&p.call(this),b.current&&m(1e3*this.duration())};t.useEffect((function(){return new Promise((function(e){e(function(e){if(e&&e.__esModule)return e;var t={};return e&&Object.keys(e).forEach((function(r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})})),t.default=e,t}(require("howler")))})).then((function(t){if(!b.current){y.current=t.Howl,b.current=!0;var r=new y.current(n({src:Array.isArray(e)?e:[e],volume:a,rate:i,onload:R},v));P(r)}})),function(){b.current=!1}}),[]),r.useEffect((function(){y.current&&E&&P(new y.current(n({src:Array.isArray(e)?e:[e],volume:a,onload:R},v)))}),[JSON.stringify(e)]),r.useEffect((function(){E&&(E.volume(a),E.rate(i))}),[a,i]);var S=r.useCallback((function(e){void 0===e&&(e={}),E&&(f||e.forceSoundEnabled)&&(d&&E.stop(),e.playbackRate&&E.rate(e.playbackRate),E.play(e.id),b.current&&E.once("end",(function(){E.playing()||h(!1)})),b.current&&h(!0))}),[E,f,d]),x=r.useCallback((function(e){E&&(E.stop(e),b.current&&h(!1))}),[E]),A=r.useCallback((function(e){E&&(E.pause(e),b.current&&h(!1))}),[E]);return[S,{sound:E,stop:x,pause:A,isPlaying:g,duration:j}]}exports.default=u,exports.useSound=u; | ||
//# sourceMappingURL=use-sound.cjs.production.min.js.map |
@@ -40,3 +40,3 @@ import React__default, { useEffect } from 'react'; | ||
function useSound(url, _ref) { | ||
function useSound(src, _ref) { | ||
if (_ref === void 0) { | ||
@@ -93,3 +93,3 @@ _ref = {}; | ||
var _sound = new HowlConstructor.current(_extends({ | ||
src: [url], | ||
src: Array.isArray(src) ? src : [src], | ||
volume: volume, | ||
@@ -106,3 +106,3 @@ rate: playbackRate, | ||
}; | ||
}); // When the URL changes, we have to do a whole thing where we recreate | ||
}); // When the `src` changes, we have to do a whole thing where we recreate | ||
// the Howl instance. This is because Howler doesn't expose a way to | ||
@@ -114,3 +114,3 @@ // tweak the sound | ||
setSound(new HowlConstructor.current(_extends({ | ||
src: [url], | ||
src: Array.isArray(src) ? src : [src], | ||
volume: volume, | ||
@@ -121,6 +121,9 @@ onload: handleLoad | ||
// but very specifically I only want to recreate the Howl instance | ||
// when the `url` changes. Other changes should have no effect. | ||
// when the `src` changes. Other changes should have no effect. | ||
// Passing array to the useEffect dependencies list will result in | ||
// ifinite loop so we need to stringify it, for more details check | ||
// https://github.com/facebook/react/issues/14476#issuecomment-471199055 | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [url]); // Whenever volume/playbackRate are changed, change those properties | ||
}, [JSON.stringify(src)]); // Whenever volume/playbackRate are changed, change those properties | ||
// on the sound instance. | ||
@@ -204,2 +207,3 @@ | ||
export default useSound; | ||
export { useSound }; | ||
//# sourceMappingURL=use-sound.esm.js.map |
@@ -5,3 +5,8 @@ { | ||
"module": "dist/use-sound.esm.js", | ||
"version": "2.0.2", | ||
"type": "module", | ||
"exports": { | ||
"import": "./dist/use-sound.esm.mjs", | ||
"require": "./dist/index.js" | ||
}, | ||
"version": "2.1.0", | ||
"repository": "github:joshwcomeau/use-sound", | ||
@@ -8,0 +13,0 @@ "license": "MIT", |
@@ -133,2 +133,34 @@ # useSound | ||
### Importing/sourcing audio files | ||
`useSound` requires a path to an audio file, and it isn't obvious how to provide one in a React application. | ||
Using `create-react-app`, you can "import" an MP3 file. It will resolve to a dynamically-generated path: | ||
```js | ||
import someAudioFile from '../sounds/sound.mp3'; | ||
console.log(someAudioFile); // “/build/sounds/sound-abc123.mp3” | ||
``` | ||
If you try to pull this trick in another React build system like Next.js, you may get an error like this: | ||
> You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. | ||
The problem is that Webpack (the bundler used under-the-hood to generate JS bundles) doesn't know how to process an MP3 file. | ||
If you have access to the Webpack config, you can update it to use [file-loader](https://webpack.js.org/loaders/file-loader/), which will create a dynamic, publicly-accessible path to the file. | ||
Alternatively, most tools will give you a "public" (create-react-app, Next.js) or a "static" (Gatsby) folder. You can drop your audio files in there, and then use a string path: | ||
```js | ||
const someAudioFile = '/public/sounds/sound.mp3'; | ||
``` | ||
The sound files you'll use with `use-sound` follow the same rules as other static assets like images or fonts. Follow the guides for your meta-framework of choice: | ||
- [create-react-app](https://create-react-app.dev/docs/adding-images-fonts-and-files/) | ||
- [Next.js](https://nextjs.org/docs/basic-features/static-file-serving) | ||
- [Gatsby](https://www.gatsbyjs.com/docs/how-to/images-and-media/static-folder/) | ||
### No sounds immediately after load | ||
@@ -135,0 +167,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
56084
405
353
Yes