Socket
Socket
Sign inDemoInstall

react-use-audio-player

Package Overview
Dependencies
Maintainers
1
Versions
37
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-use-audio-player - npm Package Compare versions

Comparing version 0.0.6 to 0.0.7

33

dist/index.d.ts
/// <reference types="howler" />
import React from "react";
declare const noop: () => void;
interface AudioSrcProps {
src: string;
format?: string;
autoplay?: boolean;
}
interface AudioPlayer {
player: Howl | null;
load: (args: AudioSrcProps) => void;
error: Error | null;
loading: boolean;
loadAudio: (url: string) => void;
playbackReady: boolean;
error: Error;
play: () => void;
isPlaying: () => boolean;
pause: () => void;
stop: () => void;
seek: (pos: number) => void;
mute: (muted: boolean) => void;
sound: Howl;
playing: boolean;
stopped: boolean;
ready: boolean;
}
declare type UseAudioPlayer = Omit<AudioPlayer, "player" | "load"> & {
play: Howl["play"] | typeof noop;
pause: Howl["pause"] | typeof noop;
stop: Howl["stop"] | typeof noop;
mute: Howl["mute"] | typeof noop;
seek: Howl["seek"] | typeof noop;
};
interface AudioPlayerProviderProps {

@@ -24,5 +33,5 @@ value?: AudioPlayer;

}
export declare function AudioPlayerProvider(props: AudioPlayerProviderProps): JSX.Element;
export declare const useAudioPlayer: (url?: string) => AudioPlayer;
export declare function AudioPlayerProvider({ children, value }: AudioPlayerProviderProps): JSX.Element;
export declare const useAudioPlayer: (props?: AudioSrcProps) => UseAudioPlayer;
export declare const useAudioPosition: () => AudioPosition;
export {};
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importDefault(require("react"));
const react_1 = __importStar(require("react"));
const howler_1 = require("howler");
const lodash_1 = require("lodash");
const noop = () => { };
const AudioPlayerContext = react_1.default.createContext(null);
function AudioPlayerProvider(props) {
const [playbackReady, setPlaybackReady] = react_1.default.useState(false);
const [loading, setLoading] = react_1.default.useState(false);
const [error, setError] = react_1.default.useState(null);
const player = react_1.default.useRef(null);
const loadAudio = react_1.default.useCallback((src) => {
setError(null);
if (playbackReady && player.current.playing()) {
player.current.unload();
setPlaybackReady(false);
function AudioPlayerProvider({ children, value }) {
const [player, setPlayer] = react_1.useState(null);
const playerRef = react_1.useRef();
const [error, setError] = react_1.useState(null);
const [loading, setLoading] = react_1.useState(true);
const [playing, setPlaying] = react_1.useState(false);
const [stopped, setStopped] = react_1.useState(true);
const load = react_1.useCallback(({ src, format, autoplay = false }) => {
let wasPlaying = false;
if (playerRef.current) {
// don't do anything if we're asked to reload the same source
// @ts-ignore the _src argument actually exists
if (playerRef.current._src === src)
return;
wasPlaying = playerRef.current.playing();
// destroys the previous player
playerRef.current.unload();
}
setLoading(true);
player.current = new howler_1.Howl({
// create a new player
const howl = new howler_1.Howl({
src,
onload() {
setLoading(false);
setPlaybackReady(true);
format,
autoplay: wasPlaying || autoplay,
onload: () => void setLoading(false),
onplay: () => {
// prevents howl from playing the same song twice
if (!howl.playing())
return;
setPlaying(true);
setStopped(false);
},
onloaderror(id, error) {
onpause: () => void setPlaying(false),
onstop: () => {
setStopped(true);
setPlaying(false);
},
onplayerror: (_id, error) => {
setError(new Error("[Play error] " + error));
setPlaying(false);
setStopped(true);
},
onloaderror: (_id, error) => {
setError(new Error("[Load error] " + error));
setLoading(false);
setPlaybackReady(false);
setError(new Error(error));
}
});
}, [player, playbackReady]);
const play = react_1.default.useCallback(() => {
if (!player.current.playing()) {
player.current.play();
}
}, [player]);
const pause = react_1.default.useCallback(() => {
player.current.pause();
}, [player]);
const stop = react_1.default.useCallback(() => {
player.current.stop();
}, [player]);
const seek = react_1.default.useCallback((pos) => {
if (playbackReady) {
player.current.seek(pos);
}
}, [player, playbackReady]);
const isPlaying = react_1.default.useCallback(() => {
if (!playbackReady)
return false;
return player.current.playing();
}, [player, playbackReady]);
const mute = react_1.default.useCallback((muted) => {
if (playbackReady) {
player.current.mute(muted);
}
}, [player, playbackReady]);
const contextValue = react_1.default.useMemo(() => {
return lodash_1.isNil(props.value)
? {
error,
playbackReady,
loading,
loadAudio,
play,
pause,
stop,
seek,
isPlaying,
mute,
sound: player.current
}
: props.value;
}, [
props.value,
playbackReady,
error,
loading,
loadAudio,
play,
pause,
stop,
seek,
mute,
isPlaying,
player
]);
return (react_1.default.createElement(AudioPlayerContext.Provider, { value: contextValue }, props.children));
setPlayer(howl);
playerRef.current = howl;
}, []);
react_1.useEffect(() => {
// unload the player on unmount
return () => {
if (playerRef.current)
playerRef.current.unload();
};
}, []);
const contextValue = value
? value
: {
player,
load,
error,
loading,
playing,
stopped,
ready: !loading && !error
};
return (react_1.default.createElement(AudioPlayerContext.Provider, { value: contextValue }, children));
}
exports.AudioPlayerProvider = AudioPlayerProvider;
// gives programmer access to the audio context
exports.useAudioPlayer = (url) => {
const value = react_1.default.useContext(AudioPlayerContext);
react_1.default.useEffect(() => {
if (url) {
value.loadAudio(url);
}
}, [url, value]);
return value;
exports.useAudioPlayer = (props) => {
const _a = react_1.useContext(AudioPlayerContext), { player, load } = _a, context = __rest(_a, ["player", "load"]);
const { src, format, autoplay } = props || {};
react_1.useEffect(() => {
// if useAudioPlayer is called without arguments
// don't do anything: the user will have access
// to the current context
if (!src)
return;
load({ src, format, autoplay });
}, [src, format, autoplay, load]);
return Object.assign(Object.assign({}, context), { play: player ? player.play.bind(player) : noop, pause: player ? player.pause.bind(player) : noop, stop: player ? player.stop.bind(player) : noop, mute: player ? player.mute.bind(player) : noop, seek: player ? player.seek.bind(player) : noop });
};
// gives current audio position state updates in an animation frame loop for animating visualizations
// gives current audio position state - updates in an animation frame loop for animating audio visualizations
exports.useAudioPosition = () => {
const { sound, playbackReady } = exports.useAudioPlayer();
const [position, setPosition] = react_1.default.useState(0);
const [duration, setDuration] = react_1.default.useState(0);
const frameRequest = react_1.default.useRef();
const animate = react_1.default.useCallback(() => {
if (playbackReady && sound.playing()) {
setPosition(sound.seek());
frameRequest.current = requestAnimationFrame(animate);
const { player, playing } = react_1.useContext(AudioPlayerContext);
const [position, setPosition] = react_1.useState(0);
const [duration, setDuration] = react_1.useState(0);
// sets position and duration on player initialization
react_1.useEffect(() => {
if (player) {
setPosition(player.seek());
setDuration(player.duration());
}
else {
cancelAnimationFrame(frameRequest.current);
}
}, [playbackReady, sound]);
react_1.default.useEffect(() => {
if (playbackReady) {
sound.on("play", () => {
setDuration(sound.duration());
frameRequest.current = requestAnimationFrame(animate);
});
sound.on("pause", () => {
cancelAnimationFrame(frameRequest.current);
});
sound.on("stop", () => {
setPosition(0);
cancelAnimationFrame(frameRequest.current);
});
return () => {
sound.off("play");
sound.off("pause");
sound.off("stop");
};
}
}, [playbackReady, sound, animate]);
return {
position,
duration
};
}, [player]);
// updates position on a one second loop
react_1.useEffect(() => {
let timeout;
if (player && playing)
timeout = window.setInterval(() => setPosition(player.seek()), 1000);
return () => clearTimeout(timeout);
}, [player, playing]);
return { position, duration };
};
//# sourceMappingURL=index.js.map
{
"name": "react-use-audio-player",
"version": "0.0.6",
"version": "0.0.7",
"description": "React hook for building custom audio playback controls",

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

"dependencies": {
"howler": "^2.1.2",
"lodash": "^4.17.15"
"howler": "^2.1.2"
},

@@ -61,0 +60,0 @@ "husky": {

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

This library exports a context Provider and two hooks for controlling the audio source.
This library exports a context Provider and two hooks for controlling an audio source, giving you the tools you need to build you own audio player or visualization.

@@ -57,8 +57,10 @@ <br/>

const AudioPlayer = ({ file }) => {
const { play, pause, playbackReady, loading, isPlaying } = useAudioPlayer(
file
)
const { play, pause, ready, loading, playing } = useAudioPlayer({
src: file,
format: "mp3",
autoplay: false
})
const togglePlay = () => {
if (isPlaying()) {
if (playing) {
pause()

@@ -70,3 +72,3 @@ } else {

if (!playbackReady && !loading) return <div>No audio to play</div>
if (!ready && !loading) return <div>No audio to play</div>
if (loading) return <div>Loading audio</div>

@@ -76,5 +78,3 @@

<div>
<button onClick={togglePlay}>
{isPlaying() ? "Pause" : "Play"}
</button>
<button onClick={togglePlay}>{playing ? "Pause" : "Play"}</button>
</div>

@@ -87,42 +87,44 @@ )

##### `loading: boolean`
#### Arguments
true if audio is being fetched
- `audioPlayerConfig: { src: string, format?: string, autoplay?: boolean }`
<br/>`autoplay` and `format` are optional. `autoplay` will default to false.
##### `playbackReady: boolean`
#### Return Value
true if the audio has been loaded and can be played
`useAudioPlayer` returns a single object containing the following members:
##### `error: Error`
- `load: (config: { src: string, format?: string, autoplay?: boolean }) => void`
<br/>loads an audio file
set when audio has failed to load
- `loading: boolean`
<br/>true if audio is being fetched
##### `play: function`
- `ready: boolean`
<br/>true if the audio has been loaded and can be played
plays the loaded audio
- `playing: boolean`
<br/>true is the audio is currently playing
##### `pause: function`
- `stopped: boolean`
<br/>true if the audio has been stopped
pauses audio
- `error: Error`
<br/>set when audio has failed to load
##### `stop: function`
- `play: () => void`
<br/>plays the loaded audio
stops the audio, returning the position to 0
- `pause: () => void`
<br/>pauses the audio
##### `loadAudio: function(url: string)`
- `stop: () => void`
<br/>stops the audio, returning the position to 0
loads an audio file
- `seek: (position: number) => void`
<br/>sets the position of the audio to position (seconds)
##### `isPlaying: function: boolean`
- `mute: () => void`
<br/>mutes the audio
true is the audio is currently playing
##### `seek: function(position: number)`
sets the position of the audio to position (seconds)
##### `mute: function`
mutes the audio
<br/>

@@ -132,3 +134,3 @@

This hooks exposes the current position and duration of the audio instance as its playing in real time (60 fps via [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)).
This hooks exposes the current position and duration of the audio instance as its playing in real time.
This data may be useful when animating a visualization for your audio like a seek bar.

@@ -156,9 +158,11 @@ A separate hook was created to manage this state in order to avoid many rerenders of components that don't need the live data feed.

##### `position: number`
#### Return Value
the current playback position of the audio in seconds
`useAudioPosition` returns an object containing the following members:
##### `duration: number`
- `position: number`
<br/>the current playback position of the audio in seconds
the total length of the audio in seconds
- `duration: number`
<br/>the total length of the audio in seconds

@@ -165,0 +169,0 @@ ## Examples

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc