Socket
Socket
Sign inDemoInstall

react-use-audio-player

Package Overview
Dependencies
4
Maintainers
1
Versions
37
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.0-alpha.0 to 2.0.0

1

dist/audioPlayerState.d.ts

@@ -22,2 +22,3 @@ import { Howl } from "howler";

toggleValue?: boolean;
debugId?: string;
}

@@ -24,0 +25,0 @@ export interface ErrorEvent {

10

dist/react-use-audio-player.cjs.development.js

@@ -74,2 +74,7 @@ 'use strict';

case ActionTypes.ON_LOAD:
// in React 18 there is a weird race condition where ON_LOAD receives a Howl object that has been unloaded
// if we detect this case just return the existing state to wait for another action
if (action.howl.state() === "unloaded") {
return state;
}
return initStateFromHowl(action.howl);

@@ -225,3 +230,2 @@ case ActionTypes.ON_ERROR:

var wrappedDispatch = react.useRef(function (action) {
// TODO: THIS START_LOAD will never be called if the howl if already loaded when the state is initialized
if (action.type === "START_LOAD") {

@@ -454,3 +458,3 @@ var howl = action.howl;

var useGlobalAudioPlayer = function useGlobalAudioPlayer() {
function useGlobalAudioPlayer() {
var howlManager = react.useRef(HowlInstanceManagerSingleton.getInstance());

@@ -593,3 +597,3 @@ var _useHowlEventSync = useHowlEventSync(howlManager.current, react.useReducer(reducer, howlManager.current.getHowl(), initStateFromHowl)),

});
};
}

@@ -596,0 +600,0 @@ exports.useAudioPlayer = useAudioPlayer;

@@ -1,2 +0,2 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),o=require("howler");function t(){return(t=Object.assign?Object.assign.bind():function(e){for(var o=1;o<arguments.length;o++){var t=arguments[o];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}function n(e){if(void 0===e)return{src:null,isReady:!1,looping:!1,duration:0,rate:1,volume:1,muted:!1,playing:!1,paused:!1,stopped:!1,error:null};var o=e.seek(),t=e.playing();return{isReady:"loaded"===e.state(),src:e._src,looping:e.loop(),duration:e.duration(),rate:e.rate(),volume:e.volume(),muted:!1,playing:t,paused:!t,stopped:!t&&0===o,error:null}}function l(e,o){switch(o.type){case"START_LOAD":return e;case"ON_LOAD":return n(o.howl);case"ON_ERROR":return t({},n(),{error:o.message});case"ON_PLAY":return t({},e,{playing:!0,paused:!1,stopped:!1});case"ON_PAUSE":return t({},e,{playing:!1,paused:!0});case"ON_STOP":return t({},e,{playing:!1,paused:!1,stopped:!0});case"ON_END":return t({},e,{playing:e.looping,stopped:!e.looping});case"ON_MUTE":var l;return t({},e,{muted:null!==(l=o.howl.mute())&&void 0!==l&&l});case"ON_RATE":var r,u;return t({},e,{rate:null!==(r=null===(u=o.howl)||void 0===u?void 0:u.rate())&&void 0!==r?r:1});case"ON_VOLUME":var a,i;return t({},e,{volume:null!==(a=null===(i=o.howl)||void 0===i?void 0:i.volume())&&void 0!==a?a:1});case"ON_LOOP":var s=o.toggleValue,c=void 0!==s&&s;return o.howl.loop(c),t({},e,{looping:c});default:return e}}function r(o,t){var n=t[0],l=t[1],r=e.useCallback((function(){var e=o.getHowl();l({type:"ON_LOAD",howl:e})}),[l,o]),u=e.useCallback((function(e,o){l({type:"ON_ERROR",message:o})}),[l]),a=e.useCallback((function(){var e=o.getHowl();l({type:"ON_PLAY",howl:e})}),[l,o]),i=e.useCallback((function(){var e=o.getHowl();l({type:"ON_PAUSE",howl:e})}),[l,o]),s=e.useCallback((function(){var e=o.getHowl();l({type:"ON_END",howl:e})}),[l,o]),c=e.useCallback((function(){var e=o.getHowl();l({type:"ON_STOP",howl:e})}),[l,o]),f=e.useCallback((function(){var e=o.getHowl();l({type:"ON_MUTE",howl:e})}),[l,o]),v=e.useCallback((function(){var e=o.getHowl();l({type:"ON_VOLUME",howl:e})}),[l,o]),p=e.useCallback((function(){var e=o.getHowl();l({type:"ON_RATE",howl:e})}),[l,o]);return e.useEffect((function(){return function(){var e=o.getHowl();null==e||e.off("loaderror",u),null==e||e.off("playerror",u),null==e||e.off("play",a),null==e||e.off("pause",i),null==e||e.off("end",s),null==e||e.off("stop",c),null==e||e.off("mute",f),null==e||e.off("volume",v),null==e||e.off("rate",p)}}),[]),[n,e.useRef((function(e){if("START_LOAD"===e.type){var o=e.howl;o.once("load",r),o.on("loaderror",u),o.on("playerror",u),o.on("play",a),o.on("pause",i),o.on("end",s),o.on("stop",c),o.on("mute",f),o.on("volume",v),o.on("rate",p)}l(e)})).current]}var u=function(){function e(){this.callbacks=new Map,this.howl=void 0,this.options={},this.subscriptionIndex=0}var t=e.prototype;return t.subscribe=function(e){var o=(this.subscriptionIndex++).toString();return this.callbacks.set(o,e),o},t.unsubscribe=function(e){this.callbacks.delete(e)},t.getHowl=function(){return this.howl},t.getNumberOfConnections=function(){return this.callbacks.size},t.createHowl=function(e){this.destroyHowl(),this.options=e;var t=new o.Howl(e);return this.callbacks.forEach((function(e){return e({type:"START_LOAD",howl:t})})),this.howl=t,t},t.destroyHowl=function(){var e,o,t,n,l,r;this.options.onload&&(null===(o=this.howl)||void 0===o||o.off("load",this.options.onload)),this.options.onend&&(null===(t=this.howl)||void 0===t||t.off("end",this.options.onend)),this.options.onplay&&(null===(n=this.howl)||void 0===n||n.off("play",this.options.onplay)),this.options.onpause&&(null===(l=this.howl)||void 0===l||l.off("pause",this.options.onpause)),this.options.onstop&&(null===(r=this.howl)||void 0===r||r.off("stop",this.options.onstop)),null===(e=this.howl)||void 0===e||e.unload()},t.broadcast=function(e){this.callbacks.forEach((function(o){return o(e)}))},e}(),a=function(){function e(){}return e.getInstance=function(){return void 0===this.instance&&(e.instance=new u),e.instance},e}();a.instance=void 0,exports.useAudioPlayer=function(){var o=e.useRef(new u),a=r(o.current,e.useReducer(l,o.current.getHowl(),n)),i=a[0],s=a[1];e.useEffect((function(){return function(){o.current.destroyHowl()}}),[]);var c=e.useCallback((function(){for(var e=arguments.length,n=new Array(e),l=0;l<e;l++)n[l]=arguments[l];var r=n[0],u=n[1],a=void 0===u?{}:u,i=o.current.createHowl(t({src:r},a));s({type:"START_LOAD",howl:i})}),[]),f=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.seek(e)}),[]),v=e.useCallback((function(){var e,t=o.current.getHowl();return void 0===t?0:null!==(e=t.seek())&&void 0!==e?e:0}),[]),p=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.play()}),[]),d=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.pause()}),[]),w=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&(i.playing?e.pause():e.play())}),[i]),g=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.stop()}),[]),h=e.useCallback((function(e,t,n){var l=o.current.getHowl();void 0!==l&&l.fade(e,t,n)}),[]),b=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.rate(e)}),[]),y=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.volume(e)}),[]),O=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.mute(e)}),[]),k=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&s({type:"ON_LOOP",howl:t,toggleValue:e})}),[]);return t({},i,{load:c,seek:f,getPosition:v,play:p,pause:d,togglePlayPause:w,stop:g,mute:O,fade:h,setRate:b,setVolume:y,loop:k})},exports.useGlobalAudioPlayer=function(){var o=e.useRef(a.getInstance()),u=r(o.current,e.useReducer(l,o.current.getHowl(),n)),i=u[0],s=u[1];e.useEffect((function(){var e=o.current.getHowl();void 0!==e&&(s({type:"START_LOAD",howl:e}),"loaded"===e.state()&&s({type:"ON_LOAD",howl:e}));var t=o.current.subscribe((function(e){s(e)}));return function(){o.current.unsubscribe(t)}}),[]);var c=e.useCallback((function(){for(var e=arguments.length,n=new Array(e),l=0;l<e;l++)n[l]=arguments[l];var r=n[0],u=n[1],a=void 0===u?{}:u;o.current.createHowl(t({src:r},a))}),[]),f=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.seek(e)}),[]),v=e.useCallback((function(){var e,t=o.current.getHowl();return void 0===t?0:null!==(e=t.seek())&&void 0!==e?e:0}),[]),p=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.play()}),[]),d=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.pause()}),[]),w=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&(i.playing?e.pause():e.play())}),[i]),g=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.stop()}),[]),h=e.useCallback((function(e,t,n){var l=o.current.getHowl();void 0!==l&&l.fade(e,t,n)}),[]),b=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.rate(e)}),[]),y=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.volume(e)}),[]),O=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.mute(e)}),[]),k=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&o.current.broadcast({type:"ON_LOOP",howl:t,toggleValue:e})}),[]);return t({},i,{load:c,seek:f,getPosition:v,play:p,pause:d,togglePlayPause:w,stop:g,mute:O,fade:h,setRate:b,setVolume:y,loop:k})};
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),o=require("howler");function t(){return(t=Object.assign?Object.assign.bind():function(e){for(var o=1;o<arguments.length;o++){var t=arguments[o];for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}).apply(this,arguments)}function n(e){if(void 0===e)return{src:null,isReady:!1,looping:!1,duration:0,rate:1,volume:1,muted:!1,playing:!1,paused:!1,stopped:!1,error:null};var o=e.seek(),t=e.playing();return{isReady:"loaded"===e.state(),src:e._src,looping:e.loop(),duration:e.duration(),rate:e.rate(),volume:e.volume(),muted:!1,playing:t,paused:!t,stopped:!t&&0===o,error:null}}function l(e,o){switch(o.type){case"START_LOAD":return e;case"ON_LOAD":return"unloaded"===o.howl.state()?e:n(o.howl);case"ON_ERROR":return t({},n(),{error:o.message});case"ON_PLAY":return t({},e,{playing:!0,paused:!1,stopped:!1});case"ON_PAUSE":return t({},e,{playing:!1,paused:!0});case"ON_STOP":return t({},e,{playing:!1,paused:!1,stopped:!0});case"ON_END":return t({},e,{playing:e.looping,stopped:!e.looping});case"ON_MUTE":var l;return t({},e,{muted:null!==(l=o.howl.mute())&&void 0!==l&&l});case"ON_RATE":var r,u;return t({},e,{rate:null!==(r=null===(u=o.howl)||void 0===u?void 0:u.rate())&&void 0!==r?r:1});case"ON_VOLUME":var a,i;return t({},e,{volume:null!==(a=null===(i=o.howl)||void 0===i?void 0:i.volume())&&void 0!==a?a:1});case"ON_LOOP":var s=o.toggleValue,c=void 0!==s&&s;return o.howl.loop(c),t({},e,{looping:c});default:return e}}function r(o,t){var n=t[0],l=t[1],r=e.useCallback((function(){var e=o.getHowl();l({type:"ON_LOAD",howl:e})}),[l,o]),u=e.useCallback((function(e,o){l({type:"ON_ERROR",message:o})}),[l]),a=e.useCallback((function(){var e=o.getHowl();l({type:"ON_PLAY",howl:e})}),[l,o]),i=e.useCallback((function(){var e=o.getHowl();l({type:"ON_PAUSE",howl:e})}),[l,o]),s=e.useCallback((function(){var e=o.getHowl();l({type:"ON_END",howl:e})}),[l,o]),c=e.useCallback((function(){var e=o.getHowl();l({type:"ON_STOP",howl:e})}),[l,o]),f=e.useCallback((function(){var e=o.getHowl();l({type:"ON_MUTE",howl:e})}),[l,o]),v=e.useCallback((function(){var e=o.getHowl();l({type:"ON_VOLUME",howl:e})}),[l,o]),p=e.useCallback((function(){var e=o.getHowl();l({type:"ON_RATE",howl:e})}),[l,o]);return e.useEffect((function(){return function(){var e=o.getHowl();null==e||e.off("loaderror",u),null==e||e.off("playerror",u),null==e||e.off("play",a),null==e||e.off("pause",i),null==e||e.off("end",s),null==e||e.off("stop",c),null==e||e.off("mute",f),null==e||e.off("volume",v),null==e||e.off("rate",p)}}),[]),[n,e.useRef((function(e){if("START_LOAD"===e.type){var o=e.howl;o.once("load",r),o.on("loaderror",u),o.on("playerror",u),o.on("play",a),o.on("pause",i),o.on("end",s),o.on("stop",c),o.on("mute",f),o.on("volume",v),o.on("rate",p)}l(e)})).current]}var u=function(){function e(){this.callbacks=new Map,this.howl=void 0,this.options={},this.subscriptionIndex=0}var t=e.prototype;return t.subscribe=function(e){var o=(this.subscriptionIndex++).toString();return this.callbacks.set(o,e),o},t.unsubscribe=function(e){this.callbacks.delete(e)},t.getHowl=function(){return this.howl},t.getNumberOfConnections=function(){return this.callbacks.size},t.createHowl=function(e){this.destroyHowl(),this.options=e;var t=new o.Howl(e);return this.callbacks.forEach((function(e){return e({type:"START_LOAD",howl:t})})),this.howl=t,t},t.destroyHowl=function(){var e,o,t,n,l,r;this.options.onload&&(null===(o=this.howl)||void 0===o||o.off("load",this.options.onload)),this.options.onend&&(null===(t=this.howl)||void 0===t||t.off("end",this.options.onend)),this.options.onplay&&(null===(n=this.howl)||void 0===n||n.off("play",this.options.onplay)),this.options.onpause&&(null===(l=this.howl)||void 0===l||l.off("pause",this.options.onpause)),this.options.onstop&&(null===(r=this.howl)||void 0===r||r.off("stop",this.options.onstop)),null===(e=this.howl)||void 0===e||e.unload()},t.broadcast=function(e){this.callbacks.forEach((function(o){return o(e)}))},e}(),a=function(){function e(){}return e.getInstance=function(){return void 0===this.instance&&(e.instance=new u),e.instance},e}();a.instance=void 0,exports.useAudioPlayer=function(){var o=e.useRef(new u),a=r(o.current,e.useReducer(l,o.current.getHowl(),n)),i=a[0],s=a[1];e.useEffect((function(){return function(){o.current.destroyHowl()}}),[]);var c=e.useCallback((function(){for(var e=arguments.length,n=new Array(e),l=0;l<e;l++)n[l]=arguments[l];var r=n[0],u=n[1],a=void 0===u?{}:u,i=o.current.createHowl(t({src:r},a));s({type:"START_LOAD",howl:i})}),[]),f=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.seek(e)}),[]),v=e.useCallback((function(){var e,t=o.current.getHowl();return void 0===t?0:null!==(e=t.seek())&&void 0!==e?e:0}),[]),p=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.play()}),[]),d=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.pause()}),[]),w=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&(i.playing?e.pause():e.play())}),[i]),g=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.stop()}),[]),h=e.useCallback((function(e,t,n){var l=o.current.getHowl();void 0!==l&&l.fade(e,t,n)}),[]),b=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.rate(e)}),[]),y=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.volume(e)}),[]),O=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.mute(e)}),[]),k=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&s({type:"ON_LOOP",howl:t,toggleValue:e})}),[]);return t({},i,{load:c,seek:f,getPosition:v,play:p,pause:d,togglePlayPause:w,stop:g,mute:O,fade:h,setRate:b,setVolume:y,loop:k})},exports.useGlobalAudioPlayer=function(){var o=e.useRef(a.getInstance()),u=r(o.current,e.useReducer(l,o.current.getHowl(),n)),i=u[0],s=u[1];e.useEffect((function(){var e=o.current.getHowl();void 0!==e&&(s({type:"START_LOAD",howl:e}),"loaded"===e.state()&&s({type:"ON_LOAD",howl:e}));var t=o.current.subscribe((function(e){s(e)}));return function(){o.current.unsubscribe(t)}}),[]);var c=e.useCallback((function(){for(var e=arguments.length,n=new Array(e),l=0;l<e;l++)n[l]=arguments[l];var r=n[0],u=n[1],a=void 0===u?{}:u;o.current.createHowl(t({src:r},a))}),[]),f=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.seek(e)}),[]),v=e.useCallback((function(){var e,t=o.current.getHowl();return void 0===t?0:null!==(e=t.seek())&&void 0!==e?e:0}),[]),p=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.play()}),[]),d=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.pause()}),[]),w=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&(i.playing?e.pause():e.play())}),[i]),g=e.useCallback((function(){var e=o.current.getHowl();void 0!==e&&e.stop()}),[]),h=e.useCallback((function(e,t,n){var l=o.current.getHowl();void 0!==l&&l.fade(e,t,n)}),[]),b=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.rate(e)}),[]),y=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.volume(e)}),[]),O=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&t.mute(e)}),[]),k=e.useCallback((function(e){var t=o.current.getHowl();void 0!==t&&o.current.broadcast({type:"ON_LOOP",howl:t,toggleValue:e})}),[]);return t({},i,{load:c,seek:f,getPosition:v,play:p,pause:d,togglePlayPause:w,stop:g,mute:O,fade:h,setRate:b,setVolume:y,loop:k})};
//# sourceMappingURL=react-use-audio-player.cjs.production.min.js.map

@@ -70,2 +70,7 @@ import { useCallback, useEffect, useRef, useReducer } from 'react';

case ActionTypes.ON_LOAD:
// in React 18 there is a weird race condition where ON_LOAD receives a Howl object that has been unloaded
// if we detect this case just return the existing state to wait for another action
if (action.howl.state() === "unloaded") {
return state;
}
return initStateFromHowl(action.howl);

@@ -221,3 +226,2 @@ case ActionTypes.ON_ERROR:

var wrappedDispatch = useRef(function (action) {
// TODO: THIS START_LOAD will never be called if the howl if already loaded when the state is initialized
if (action.type === "START_LOAD") {

@@ -450,3 +454,3 @@ var howl = action.howl;

var useGlobalAudioPlayer = function useGlobalAudioPlayer() {
function useGlobalAudioPlayer() {
var howlManager = useRef(HowlInstanceManagerSingleton.getInstance());

@@ -589,5 +593,5 @@ var _useHowlEventSync = useHowlEventSync(howlManager.current, useReducer(reducer, howlManager.current.getHowl(), initStateFromHowl)),

});
};
}
export { useAudioPlayer, useGlobalAudioPlayer };
//# sourceMappingURL=react-use-audio-player.esm.js.map
import { AudioPlayer } from "./types";
export declare const useGlobalAudioPlayer: () => AudioPlayer;
export declare function useGlobalAudioPlayer(): AudioPlayer;
{
"name": "react-use-audio-player",
"version": "2.0.0-alpha.0",
"version": "2.0.0",
"description": "React hook for building custom audio playback controls",

@@ -51,3 +51,4 @@ "main": "dist/index.js",

"husky": "^3.1.0",
"react": "^17",
"react": "^18",
"react-dom": "^18",
"react-test-renderer": "^16.12.0",

@@ -54,0 +55,0 @@ "tsdx": "^0.13.1",

@@ -5,3 +5,3 @@ # react-use-audio-player

The intent of this package is to provide an idiomatic was to create and manipulate sounds in a React application.
The intent of this package is to provide an idiomatic way to create and manipulate sounds in a React application.

@@ -13,2 +13,10 @@ ![Version](https://img.shields.io/npm/v/react-use-audio-player)

## [Version 2.0](https://github.com/E-Kuerschner/useAudioPlayer/discussions/106) Upgrade/Migration Guide
Note that v2 is a major upgrade and thus contains breaking changes for your applications. Overall the migration to v2 will involve you taking a few refactoring steps:
1. remove all uses of `useAudioPosition` and replace it with your own implementation (see the examples/recipes section below)
2. replace all uses of `useAudioPlayer` with `useGlobalAudioPlayer` which is exported from the v2 package (alongside a net-new hook using the old name of `useAudioPlayer` - more on that below)
3. check the docs for `useGlobalAudioPlayer` below since some API improvements have been made. Most notably, the hook is no longer called with any load arguments/options and instead returns an explicit `load` function that you must use.
## Install

@@ -37,4 +45,4 @@

## Why Two Hooks?
`useAudioPlayer` and `useGlobalAudioPlayer` share a lot of similarities. In fact, they return the same `AudioPlayer` interface.
Your use-case will determine which is the most appropriate for you to use.
`useAudioPlayer` and `useGlobalAudioPlayer` share a lot of similarities. In fact, they return the same `AudioPlayer` interface (see details below).
Your use-case will determine which hook is the most appropriate for you to use.

@@ -46,9 +54,9 @@ `useGlobalAudioPlayer` has some unique functionality. It's purpose is to manage a single, global sound across your entire app.

For example, you could write a _Playlist_ component where clicking a track loads that song and begins playback.
Then on a totally different branch in your component tree, write a _PlaybackControls_ component which calls useGlobalAudioPlayer and selects its _play_ and _pause_ members
Then, on a totally different branch in your component tree, write a _PlaybackControls_ component which calls useGlobalAudioPlayer and uses its _play_ and _pause_ members
to start and stop the same song previously loaded by _Playlist_.
To quickly decide if you should use useGlobalAudioPlayer, ask yourself these two questions:
1. **Does your app only need to play a single sound at a time?**
To quickly determine if useGlobalAudioPlayer is right for you, ask yourself these two questions:
1. **Does your app only need to play a single sound at any given time?**
2. **Do you want to be able to control this sound from anywhere in your component tree?**
If the answer is yes to both of these, then useGlobalAudioPlayer is the right choice.
If the answer is yes to both of these questions, then useGlobalAudioPlayer is the right choice for your application.

@@ -59,5 +67,5 @@ `useAudioPlayer` is the best choice for when you have a simple use-case. Each instance of the useAudioPlayer hook represents its own sound.

TODO: The sound will stop when the hook unmounts
**Note:** Unlike useGlobalAudioPlayer, when the component which initialized the hook unmounts the sound will stop.
useGlobalAudioPlayer and useAudioPlayer can be used simultaneouly without one affecting the other.
useGlobalAudioPlayer and useAudioPlayer can be used simultaneously without one affecting the other.

@@ -67,10 +75,11 @@

This is the interface returned from both useAudioPlayer and useGlobalAudioPlayer.
The interface provides all the state and methods listed below:
This is the interface implemented by the returned object of both _useAudioPlayer_ and _useGlobalAudioPlayer_.
The interface defines all the state for a sound and a set of methods to manipulate the state/sound.
#### State
- loop: `boolean` (will the audio loop)
- src: `string` (the src used to load the audio)
- looping: `boolean` (is the audio looping)
- isReady: `boolean` (is the sound loaded and ready to play)
- paused: `boolean` (is the sound paused)
- stopped: `boolean` (is the sound stopped)
- stopped: `boolean` (is the sound stopped i.e. not playing & position 0)
- playing: `boolean` (is the sound playing)

@@ -81,63 +90,60 @@ - duration: `number` (the length in seconds)

- volume: `number` (the volume level 0 - 1.0)
- error: `string` (error message if any after attemped load)
- error: `string | null` (error message if any, after attempted load)
#### Methods
#### play (`() => void`)
> Plays the loaded sound. You must invoke this to start playback if `autoplay` was set to false
#### play `() => void`
Plays the loaded sound. You must invoke this to start playback if `autoplay` was set to false
#### pause (`() => void`)
> Pauses the loaded sound.
#### pause `() => void`
Pauses the playing sound
#### togglePlayPause (`() => void`)
> Toggle play/pause state.
#### togglePlayPause `() => void`
Toggles the play/pause state
#### stop (`() => void`)
> Stops the loaded sounds and resets the position to 0.
#### stop `() => void`
Stops the playing sound and resets the position to 0.
#### mute (`(muted?: boolean) => void`)
> Mutes/unmutes the loaded sound.
#### setVolume `(volume: number) => void`
Sets the volume level of the loaded audio. Accepts a floating point number between 0 and 1.0 (muted to loudest)
#### setVolume (`(volume: number) => void`)
> Sets the volume level of the loaded audio. Accepts a floating point number between 0 and 1.0.
#### mute `(muteOnOff: boolean) => void`
Mutes/unmutes the loaded sound
#### fade (`(from: number, to: number, duration: number) => void`)
> Fades the sounds volume level from the value of the first argument to the value of the second over a number of seconds defined by the final argument.
#### fade `(from: number, to: number, duration: number) => void`
Fades the sound's volume level from the value of the first argument to the value of the second, over a number of seconds as set by the final argument
#### setRate (`(speed: number) => void`)
> Sets the playback speed of the loaded sound. Accepts a floating point value between 0.5 and 2.0.
#### setRate `(speed: number) => void`
Sets the playback speed of the loaded sound. Accepts a floating point value between 0.5 and 2.0. Currently half speed is the slowest and double is the fastest supported rates
#### seek (`(seconds: number) => void`)
> Sets the playback position of the loaded sound to the position passed in.
#### seek `(position: number) => void`
Sets the playback position of the loaded sound to the argument. The position argument is floating point number representing the time the audio should move to
#### getPosition (`() => number`)
> Returns the current position of the loaded sound.
#### loop `(loopOnOff: boolean) => void`
Sets or unsets whether the sound should loop once it ends
#### load (`(src: string, options?: AudioLoadOptions) => void`)
> Downloads/loads a new sound. The first argument is a URI of the sound to be downloaded. The second argument is a set of options.
> sdsflkjalskfj
> asdlfkjsd
> alksdjfldaskjf
> lakjsdflj
> ```tsx
> interface AudioLoadOptions
>
> Members:
>
> - loop (`boolean`)
> - autoplay (`boolean`)
> - initialVolume (`number`)
> - initialMute (`number`)
> - initialRate (`number`)
> - format (`string`)
> - html5 (`boolean`)
> - onstop (`() => void`)
> - onpause (`() => void`)
> - onload (`() => void`)
> - onend (`() => void`)
> - onplay (`() => void`)
>```
#### getPosition `() => number`
Returns the current position of the loaded sound as a floating point number
#### load `(src: string, options?: AudioLoadOptions) => void`
Downloads and loads a new sound. The first argument, src is a URI of the sound to be played. The second argument is a set of options applied to the sound once it loads.
These options can be used to initialize certain pieces of state on the `AudioPlayer` interface or be used to set up lifecycle callbacks if needed.
`AudioLoadOptions`
- loop?: boolean (sets the initial loop state once the sound loads)
- autoplay?: boolean (sets if the sound will automatically begin playing after load)
- initialVolume?: number (sets the initial volume level once the sound loads)
- initialMute?: number (sets the initial mute state once the sound loads)
- initialRate?: number (sets the initial playback rate once the sound loads)
- format?: string (sets the format of the loaded sound - should be set if your URI does not contain an extension)
- html5?: boolean (loads the sound in an HTML5 audio tag as opposed to using the Web Audio API)
- onplay?: () => void (callback for when audio begins playing)
- onstop?: () => void (callback for when audio is stopped)
- onpause?: () => void (callback for when audio is paused)
- onload?: () => void (callback for when audio finishes loading)
- onend?: () => void (callback for when audio has reached its end)
## Quick Recipes & Gotchas
For full, example applications see the [runnable examples](https://github.com/E-Kuerschner/useAudioPlayer/tree/main/examples) in the repo.
Below are a few snippets to help with some of the trickier use-cases.

@@ -175,10 +181,39 @@ ### Recipe: Switching between sounds on a single audio player

### Recipe: Creating a seek bar
### Recipe: Syncing React state to live audio position
TODO
In previous 1.x versions of the library, a separate hook was exported from the package which tracked state representing the current seek time of a playing sound.
While this was helpful it ultimately fell outside the scope of the hook as the v2 rewrite took shape.
This is mainly due to the difficulty of supporting the feature for both forms of the hook useAudioPlayer/useGlobalAudioPlayer.
Luckily, even without a dedicated hook, it is trivial to implement the same functionality yourself. Below is one method for how you might write your own hook for tracking seek time.
```tsx
function useAudioTime() {
const frameRef = useRef<number>()
const [pos, setPos] = useState(0)
const { getPosition } = useGlobalAudioPlayer()
useEffect(() => {
const animate = () => {
setPos(getPosition())
frameRef.current = requestAnimationFrame(animate)
}
frameRef.current = window.requestAnimationFrame(animate)
return () => {
if (frameRef.current) {
cancelAnimationFrame(frameRef.current)
}
}
}, [getPosition])
return pos;
}
```
### Gotcha: Streaming audio
To stream or play large audio files, the audio player must be forced to use HTML5 as opposed to the Web Audio API which is Howler's default.
This is because the Web Audio API must download the entirety of the sound before playing.
This is because the Web Audio API must download the entirety of the sound before playing anything.

@@ -185,0 +220,0 @@ When streaming or working with large files make sure to use the `html5` option of the `#load` function.

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc