A React Hook for playing sound effects

Overview

useSound

A React Hook for Sound Effects

The web needs more (tasteful) sounds!

  • 👂 Lets your website communicate using 2 human senses instead of 1
  • 🔥 Declarative Hooks API
  • ⚡️ <1kb bytes (gzip) in your bundle! ~10kb loaded async.
  • Built with Typescript
  • 🗣 Uses a powerful, battle-tested audio utility: Howler.js

Minified file size License: MIT NPM version Code of Conduct

This library only works with React DOM, but @remigallego created an alternative for React Native! Check out react-native-use-sound.


Status

This project is “semi-maintained” 😅

I don't have the bandwidth right now to look into edge-case issues or help troubleshoot, but I plan on keeping it up-to-date with major React releases, and fixing issues that are both serious and common.

If you have ideas for features, or run into strange quirks, I thoroughly recommend forking the project and making it your own! It might seem intimidating, but the source isn't as complex as many other NPM packages; I defer all the hard audio work to Howler). If you've been using React for a while and are comfortable with hooks, you should feel right at home with this package's code.


Installation

Package can be added using yarn:

yarn add use-sound

Or, use NPM:

npm install use-sound

UMD build available on unpkg.


Demo

The tutorial includes many demos, as well as instructions for finding and preparing sound effects. It's a great place to start.

You can also view the storybook, which includes lots of quick examples.


Examples

Play sound on click

import useSound from 'use-sound';

import boopSfx from '../../sounds/boop.mp3';

const BoopButton = () => {
  const [play] = useSound(boopSfx);

  return <button onClick={play}>Boop!</button>;
};

Playing on hover

This demo only plays the sound while hovering over an element. The sound pauses when the mouse leaves the element:

NOTE: Many browsers disable sounds until the user has clicked somewhere on the page. If you're not hearing anything with this example, try clicking anywhere and trying again.

🎺 ); }; ">
import useSound from 'use-sound';

import fanfareSfx from '../../sounds/fanfare.mp3';

const FanfareButton = () => {
  const [play, { stop }] = useSound(fanfareSfx);

  return (
    <button onMouseEnter={() => play()} onMouseLeave={() => stop()}>
      <span role="img" aria-label="trumpet">
        🎺
      </span>
    </button>
  );
};

Increase pitch on every click

With the playbackRate option, you can change the speed/pitch of the sample. This example plays a sound and makes it 10% faster each time:

🗣 ); }; ">
import useSound from 'use-sound';

import glugSfx from '../../sounds/glug.mp3';

export const RisingPitch = () => {
  const [playbackRate, setPlaybackRate] = React.useState(0.75);

  const [play] = useSound(glugSfx, {
    playbackRate,
    // `interrupt` ensures that if the sound starts again before it's
    // ended, it will truncate it. Otherwise, the sound can overlap.
    interrupt: true,
  });

  const handleClick = () => {
    setPlaybackRate(playbackRate + 0.1);
    play();
  };

  return (
    <Button onClick={handleClick}>
      <span role="img" aria-label="Person with lines near mouth">
        🗣
      </span>
    </Button>
  );
};

Usage Notes

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:

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, 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:

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:

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, setPlaybackRate] = React.useState(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 hook.


API Documentation

The useSound hook takes two arguments:

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

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.

HookOptions

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 hook for multiple sound effects. See “Sprites” below.

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

The play function

When calling the hook, 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 HookOptions. 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 HookOptions. In general you should prefer to do it through HookOptions, this is an escape hatch.

ExposedData

The hook 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 story 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 HookOptions:

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
  onClick={() => 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 HookOptions 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:

const Arcade = () => {
  const [play, { sound }] = useSound('/win-theme.mp3');

  return (
    <button
      onClick={() => {
        // You win! Fade in the victory theme
        sound.fade(0, 1, 1000);
      }}
    >
      Click to win
    </button>
  );
};
Comments
  • Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function

    Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function

    Hey interesting issue - I'm redirecting a user after a sound and it looks like potentially a useEffect within use-sound isn't returning a way to unmount. Thoughts?

      const [play,] = useSound(beepSfx)
      const history = useHistory()
    
      const onBeep = useCallback(() => play())
    
      const onCreate = useCallback(() => {
        onBeep()
        history.push(ROUTES.MANAGE_BRANDS)
      })
    

    Console errors:

    index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
        in WelcomeSelectPage (created by Context.Consumer)
      | console.<computed> | @ | index.js:1
    -- | -- | -- | --
      | r | @ | react_devtools_backend.js:6
      | printWarning | @ | react-dom.development.js:88
      | error | @ | react-dom.development.js:60
      | warnAboutUpdateOnUnmountedFiberInDEV | @ | react-dom.development.js:23192
      | scheduleUpdateOnFiber | @ | react-dom.development.js:21200
      | dispatchAction | @ | react-dom.development.js:15682
      | (anonymous) | @ | index.ts:105
      | (anonymous) | @ | howler.js:1856
      | setTimeout (async) |   |  
      | _emit | @ | howler.js:1855
      | _ended | @ | howler.js:1920
      | setTimeout (async) |   |  
      | playWebAudio | @ | howler.js:843
      | play | @ | howler.js:855
      | (anonymous) | @ | index.ts:103
      | (anonymous) | @ | select.js:37
    

    Line 37 is onBeep declaration

    opened by azz0r 11
  • Compatible 2.0.1 -> 2.0.2 version breaks require support in webpack build

    Compatible 2.0.1 -> 2.0.2 version breaks require support in webpack build

    Our package.json uses the compatible flag:

    "use-sound": "^2.0.1",

    Upon running the built module, we get the error:

    ± |feat-pixi-canvas-fallback {3} U:2 ✗| → node dist/server.js
    node:internal/modules/cjs/loader:1125
          throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
          ^
    
    Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/ljp/dev/pdm/ruthless-server/node_modules/use-sound/dist/index.js
    require() of ES modules is not supported.
    require() of /home/ljp/dev/pdm/ruthless-server/node_modules/use-sound/dist/index.js from /home/ljp/dev/pdm/ruthless-server/dist/server.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
    Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /home/ljp/dev/pdm/ruthless-server/node_modules/use-sound/package.json.
    
        at new NodeError (node:internal/errors:278:15)
        at Object.Module._extensions..js (node:internal/modules/cjs/loader:1125:13)
        at Module.load (node:internal/modules/cjs/loader:973:32)
        at Function.Module._load (node:internal/modules/cjs/loader:813:14)
        at Module.require (node:internal/modules/cjs/loader:997:19)
        at require (node:internal/modules/cjs/helpers:92:18)
        at Object.use-sound (/home/ljp/dev/pdm/ruthless-server/dist/server.js:5224:18)
        at __webpack_require__ (/home/ljp/dev/pdm/ruthless-server/dist/server.js:5291:42)
        at eval (webpack-internal:///./app/src/notification/components/NotificationSystem.js:11:67)
        at Module../app/src/notification/components/NotificationSystem.js (/home/ljp/dev/pdm/ruthless-server/dist/server.js:906:1) {
      code: 'ERR_REQUIRE_ESM'
    }
    

    Though the NotificationSystem.js module uses import syntax and works on a dev server, in the build it fails I guess because of some webpack internal using a require statement instead.

    I believe this is due to this change #71 d7d9ef921f36aa7f4a4d3d2bf7572b32d5e97f90

    Now, this likely points to a lurking issue in my webpack config which can probably be fixed, and a quick workaround is just to specifically use 2.0.1 as the package version, however I'm not sure that changing that flag (type: "module") is truly a compatible, minor change (as well, I feel that that particular change should have bumped the version number which was changed a couple of commits prior).

    opened by lewiji 10
  • rerender for each instance of use-sound

    rerender for each instance of use-sound

    When using multiple use-sound instances, the page re-renders its content depending on how many hooks are used.

    F.e.:

    const Page = () => {
      const sound1 = useSound(sample1)
      const sound2 = useSound(sample2)
      const sound3 = useSound(sample3)
    
      console.log('render')
      return (<>hello</>)
    }
    

    will log render like 14 times. See this codesandbox.

    Is this the expected behaviour?

    opened by martinjuhasz 10
  • Help, how to use with React + Typescript

    Help, how to use with React + Typescript

    Hello,

    I would love to use this amazing tool, but I'm not able to use with React+Typescript (I've just started to learn them). Tried multiple times, but I've encountered with 2 main error.

    1. I'm not able to import from my folder the mp3 as I get this TS error : Cannot find module or its corresponding type declarations.ts(2307)

    2. type 'PlayFunction' is not assignable to type 'MouseEventHandler'

    I hope someone can help me

    Thanks! :) @joshwcomeau

    opened by webdiego 7
  • TypeError: HowlConstructor.current is not a constructor

    TypeError: HowlConstructor.current is not a constructor

    I am having the error mentioned above while using use-sound with Vite and React.

    • Howler JS is being loaded, in the networks panel in devtools
    • Error is here: image

    Pls help. Thank you

    opened by PuruVJ 7
  • The AudioContext was not allowed to start

    The AudioContext was not allowed to start

    I get a warning on page load even when I haven't actually called play() yet. It seems like this is an issue in howler because they call new AudioContext() immediately.

    Is it possible to somehow workaround this in use-sound?

    opened by feross 7
  • How to use with Next.js?

    How to use with Next.js?

    Hi, l'm trying to use this in TypeScript with Next.js. I'm getting,

    TS2307: Cannot find module '../../../public/sfx/correct-answer/test.mp3' or its corresponding type declarations.

    I know my path is right. I don't know if I can get a webpack file-loader configured but even if I did, would I still get this TypeScript error?

    Your library looks really cool and I'd like to use it so would appreciate any help. I couldn't find much by searching the web.

    opened by abcd-ca 6
  • Allow hook options to be extended with HowlOptions

    Allow hook options to be extended with HowlOptions

    Issue: https://github.com/joshwcomeau/use-sound/issues/18

    Versions: Tested in my project on the following lib versions

    • Typescript: 4.0.5
    • React: 17.0.1
    • use-sound: latest

    Description: This fix does not change the default hook behavior, however, it allows to specify set of options from HowlOptions and enables IDE support for them

    Usage:

    import useSound from 'use-sound';
    import {HowlOptions} from "howler";
    
    import soundfile from './assets/sounds/test.ogg';
    
    const Player = ({url, volume}: PlayerProps) => {
      const [play, {isPlaying, pause}] = useSound<HowlOptions>(url, {
        volume: volume,
        loop: true,
        onend: () => {console.log('===== ENDED');}
      });
    
      return <div className='player'>
        {isPlaying ?
            <PauseImg onClick={() => pause()}/> :
            <PlayImg onClick={() => play()} />
        }
      </div>
    };
    
    ...
    
    <Player url={soundfile} volume={0.2}/>
    

    It's still usable w/o any extensions

    const [play] = useSound(soundfile);
    

    NOTE: exporting hook not only as module default will allow to augment and add overrides to the hook if needed

    opened by TamoshaytisV 6
  • 3.0.0 breaks saying

    3.0.0 breaks saying "Must use import to load ES Module"

    Full error in Next.js (10.1.3)
    Server Error
    Error: Must use import to load ES Module: /Users/path/to/node_modules/use-sound/dist/index.js
    require() of ES modules is not supported.
    require() of /Users/path/to/node_modules/use-sound/dist/index.js from /Users/path/to/.next/server/pages/landing.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
    Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/path/to/node_modules/use-sound/package.json.
    

    FWIW: It starts working as expected when I remove "type": "module" from the package.json

    opened by KarandikarMihir 5
  • Add support for multiple sources (proxy to Howl)

    Add support for multiple sources (proxy to Howl)

    Issue: https://github.com/joshwcomeau/use-sound/issues/17

    Description: This PR allows passing multiple source files to the Howl constructor (see howler.src)

    Usage:

    import soundfile1 from './assets/sounds/test.ogg';
    import soundfile2 from './assets/sounds/test.mp3';
    
    const Player = () => {
      const [play] = useSound([soundfile1, soundfile2]);
    
      return <div onClick={() => play()}>Play</div>;
    };
    
    ...
    
    <Player />
    

    Old behavior stays and prev codebase should not be affected

    const [play] = useSound(soundfile1);
    
    opened by TamoshaytisV 4
  • Add isMounted ref to suppress async state setter functions

    Add isMounted ref to suppress async state setter functions

    @joshwcomeau I think this is what you were getting at. I'm having a hell of a time trying to test this locally though, due the following error:

    Screen Shot 2020-11-21 at 1 41 45 PM

    Fixes #14

    opened by curt-tophatter 4
  • Bump decode-uri-component from 0.2.0 to 0.2.2

    Bump decode-uri-component from 0.2.0 to 0.2.2

    Bumps decode-uri-component from 0.2.0 to 0.2.2.

    Release notes

    Sourced from decode-uri-component's releases.

    v0.2.2

    • Prevent overwriting previously decoded tokens 980e0bf

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.1...v0.2.2

    v0.2.1

    • Switch to GitHub workflows 76abc93
    • Fix issue where decode throws - fixes #6 746ca5d
    • Update license (#1) 486d7e2
    • Tidelift tasks a650457
    • Meta tweaks 66e1c28

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.1

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Sound not playing on Recat-typescript

    Sound not playing on Recat-typescript

    Hello,

    I would love to use this amazing tool, but I'm not able to use with React+Typescript (I've just started to learn them). Tried multiple times, but I've encountered with 2 main error.

    I'm not able to import from my folder the mp3 as I get this TS error : Cannot find module or its corresponding type declarations.ts(2307)

    And after assigning audio its not playing

    code......................

    import useSound from "use-sound"; import notificationSoundmp3 from "../../Utils/assets/sound/notification.mp3";

    const [play] = useSound(notificationSoundmp3, { volume: 0.5 });

    const handleTestButton = () => { setOpenTestModal(!openTestModal); play(); };

    I hope someone can help me

    opened by Souravrao-31 1
  • stop or pause not working

    stop or pause not working

    import { useEffect, useState } from "react";
    import { SpeakerWaveIcon, SpeakerXMarkIcon } from "@heroicons/react/24/outline";
    import useSound from "use-sound";
    
    export const AudioPlayer = ({ url }) => {
      const [isPlaying, setIsPlaying] = useState(false);
      const [play, { sound, stop }] = useSound(url);
    
      useEffect(() => {
        sound?.on("play", () => setIsPlaying(true));
        sound?.on("stop", () => setIsPlaying(false));
        sound?.on("end", () => setIsPlaying(false));
        sound?.on("pause", () => setIsPlaying(false));
      }, [sound]);
    
      return (
        <button className="flex gap-x-2" onClick={isPlaying ? stop : play}>
          {isPlaying ? (
            <SpeakerWaveIcon className="w-6 h-auto" />
          ) : (
            <SpeakerXMarkIcon className="w-6 h-auto" />
          )}
          {isPlaying ? "Pause" : "Play"}
        </button>
      );
    };
    
    

    I definitely see sound being exported in the types but doens't seem to work. Using the latest version: 4.0.1. any suggestions?

    opened by artivilla 0
  • ReferenceError: HowlerGlobal is not defined (Parcel 2)

    ReferenceError: HowlerGlobal is not defined (Parcel 2)

    Just randomly started getting this error from parcel after we updated the parcel package to v2. Posting here incase anyone has anymore information on it or also runs into this. Updating the howler version fixed it for me!

    My current workaround: I added howler with the lastest version (2.2.3) and used that package version for use-sound's howler import and it seemingly fixes this.

    within package.json: "alias": { "howler": "howler/dist/howler.core.min.js" }

    image

    opened by tpudel 0
Releases(4.0.0)
  • 4.0.0(Jun 4, 2021)

    This breaking release removes the isPlaying boolean; tracking that state was causing additional re-renders, which could pile up when using multiple instances of the hook.

    If you were relying on this prop, you can implement it yourself using the onplay and onend events from Howler. An example is shown here: https://github.com/joshwcomeau/use-sound/blob/master/stories/demos/ShowWhilePlaying.js

    Source code(tar.gz)
    Source code(zip)
Owner
Joshua Comeau
Software developer. Makes stuff.
Joshua Comeau
📺 Playing around Html 5 Video API

?? Playing with Html5 Video API LIVE DEMO This project was bootstrapped with Create React App. Below you will find some information on how to perform

Ion Drimba Filho 1 Apr 30, 2021
A mobile app for playing music on Resonate, an open source music streaming co-op

A mobile app for playing music on Resonate, an open source music streaming co-op. Built with TypeScript and React Native.

Resonate 8 Nov 17, 2022
A package with Optimized and Supercharged React hook to play audio without any DOM element 💪🎧

react-awesome-audio Optimized and Supercharged React hook to play audio without any DOM element ?? ?? Find the npm package here Star the GitHub repo t

Niloy Sikdar 28 Oct 7, 2022
A Youtube search function clone project built with React, TypeScript, React-Router, TailwindCSS, and React-Infinite-Scroller

demo.mp4 A Youtube search function clone project built with React, TypeScript, React-Router, TailwindCSS, and React-Infinite-Scroller. Users can searc

null 1 Jun 9, 2022
🎶 A SoundCloud Client in React + Redux running in production. Live Demo and Source Code to explore React + Redux as a beginner.

?? A SoundCloud Client in React + Redux running in production. Live Demo and Source Code to explore React + Redux as a beginner.

Robin Wieruch 1.6k Nov 21, 2022
react-tv: React Renderer for low memory applications.

react-tv: React Renderer for low memory applications.

Raphael Amorim 2k Nov 29, 2022
Find & watch all React conference talks, built for all React developers!

ReactConf.TV is a place where passionate React developers are able to search & watch organized and up-to-date react conference videos

RevtelTech 忻旅科技 26 Nov 30, 2022
React components that makes it easier to use LiveKit in a React app.

LiveKit React Component Library This package provides React components that makes it easier to use LiveKit in a React app. Install npm install --save

LiveKit 149 Nov 25, 2022
Party line: Audio-only demos for React, React Native, iOS, and Android

Party line: Audio-only demos for React, React Native, iOS, and Android Built by and with Daily Multi-platform audio-only demos, for React, React Nativ

Open Sauced 6 Apr 21, 2022
Example of using react-multimedia-capture to capture Video/Audio from React

react-multimedia-capture Example Example of react-multimedia-capture. Steps install dependencies. $ npm install Build resources $ gulp Run the server.

.modernator 14 Aug 27, 2020
Aframe-react-mirror - A-Frame React Immersive Stereoscopic Video Component

A-Frame React Immersive Stereoscopic Video Component Languages 한국어 | English Int

Belivvr INC 2 Jan 19, 2022
React Tuby - A React video player library with YouTube-like UI

React Tuby - A React video player library with YouTube-like UI

Phong Nguyen 103 Dec 3, 2022
Dailymotion player component for React.

react-dailymotion Dailymotion player component for React. Install - Usage - Demo - Props Install npm install --save react-dailymotion Usage Demo - De

üWave 14 Jul 21, 2022
📻 Create custom web audio players with React

react-soundplayer Create highly-customizable SoundCloud (or any audio) players with React.js. Documentation Install npm install react-soundplayer --sa

KOSMETISM 1.5k Dec 4, 2022
react.js powered YouTube player component

react-youtube Simple React component acting as a thin layer over the YouTube IFrame Player API Features url playback playback event bindings customiza

tjallingt 1.6k Nov 29, 2022
A web video player built for the HTML5 world using React library.

video-react Video.React is a web video player built from the ground up for an HTML5 world using React library. Installation Install video-react and pe

null 2.4k Nov 30, 2022
Audio player react component for material ui design

Material UI Audio Player Audio player for material ui design developed with react.js. Requires Material UI 4 version. Demo: https://werter12.github.io

Oleksandr Samofan 61 Oct 7, 2022
A static site generator powered by Deno + React

A static site generator powered by Deno + React

xcatliu 1.5k Nov 30, 2022
a collection of simple demos of React.js

This is a collection of simple demos of React.js. These demos are purposely written in a simple and clear style. You will find no difficulty in following them to learn the powerful library.

Ruan YiFeng 16k Nov 28, 2022