📢 Version 2.0.0-alpha.0 ready to test! #108
Replies: 2 comments 1 reply
-
This is fantastic @E-Kuerschner! Will there be an
Does v2 take care of those issues? Cheers! |
Beta Was this translation helpful? Give feedback.
-
Thank you so much for the great work, @E-Kuerschner ! I've set up my app using the global player, and it works as a charm! One major issue remaining: I would like to have duration of each track in my playlist, and to get that I need to It is obviously an alternative to use a single player for each track, but then I miss the very simple way of implementing a control component outside the list, and need to add a lot of props and callbacks up and down, I guess, to achieve the same. I added an const { duration } = useGlobalAudioPlayer()
const { // remapping names to avoid conflict with the global player props
load: singleLoad,
duration: singleDuration,
isReady: singleIsReady,
isLoading: singleIsLoading,
error: singleError,
} = useAudioPlayer()
useEffect(() => {
const getAudioDuration = async (audioUrl) => {
return new Promise((resolve, reject) => {
singleLoad(audioUrl, {
onload: () => {
console.log(
'onload called',
track.index,
'- isLoading?',
singleIsLoading,
'isReady?',
singleIsReady,
'duration:',
singleDuration,
'error?',
singleError
)
if (singleError) {
console.error('error', audioUrl, singleError)
reject(singleError)
}
resolve(singleDuration)
},
})
})
}
if (
track.duration === undefined &&
!getDurationInProgress &&
trackDuration === undefined
) {
setGetDurationInProgress(true)
getAudioDuration(track.audio)
.then((value) => {
setTrackDuration(value)
updateTrack({ ...track, duration: value })
})
.catch((err) => {
console.error('failed to get duration for', track.audio, err)
setGetDurationInProgress(false)
})
}
}, [track]) Here is a screenshot of the console output: I would kind of expect I also tried your sample hook useAudioTime, but it seems to cause a lot of load, but I haven't spent much time looking at it yet. EDIT: To map to your examples, what I am looking for is a way to show duration for each element in the list of the /globalAudio/library application. |
Beta Was this translation helpful? Give feedback.
-
Hey all! I just published an alpha version
2.0.0-alpha.0
which should be ready to test against your use cases! Please feel free to leave feedback in the thread here or create an Issue with the tagv2-alpha-feedback
.Installation
You can install the version by running:
(yarn add | npm i) react-use-audio-player@alpha
Examples
If you prefer, you can use the examples already built out in this repository as a starting point for your experimentation. Just make sure to checkout the tag for this alpha version!
To run the examples please clone the repository and change directories inside:
cd examples
yarn | npm i
yarn start | npm run start
You can then navigate to localhost:1234 in your browser to play with the example applications.
alpha.0 git tag: https://github.com/E-Kuerschner/useAudioPlayer/tree/v2.0.0-alpha.0
Documentation
The official documentation for v2 isn't quite ready but here is a rough work in progress that should get you by! Please ask any questions as they come up!
react-use-audio-player
Typescript package exporting custom React hooks for controlling audio in the browser. Built on top of the amazing howler.js library.
The intent of this package is to provide an idiomatic was to create and manipulate sounds in a React application.
Install
Usage
To play a sound, import either
useAudioPlayer
oruseGlobalAudioPlayer
into a React component. Grab theload
function from its return and get jamming!Why Two Hooks?
useAudioPlayer
anduseGlobalAudioPlayer
share a lot of similarities. In fact, they return the sameAudioPlayer
interface.Your use-case will determine which is the most appropriate for you to use.
useGlobalAudioPlayer
has some unique functionality. It's purpose is to manage a single, global sound across your entire app.The inspiration for this came from a desire to easily build applications like SoundCloud or Spotify where no matter where you are in the app you can access and control the sound.
When you are using this hook you can call it from anywhere in your component tree and it will synchronize with the same audio source as every other instance of useGlobalAudioPlayer.
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
to start and stop the same song previously loaded by Playlist.
To quickly decide if you should use useGlobalAudioPlayer, ask yourself these two questions:
If the answer is yes to both of these, then useGlobalAudioPlayer is the right choice.
useAudioPlayer
is the best choice for when you have a simple use-case. Each instance of the useAudioPlayer hook represents its own sound.This means that you can load and play multiple sounds from the same component.
For example, you could add separate, unique sound effects for the success and error responses of a fetch request.
useGlobalAudioPlayer and useAudioPlayer can be used simultaneously without one affecting the other.
AudioPlayer (interface)
This is the interface returned from both useAudioPlayer and useGlobalAudioPlayer.
The interface provides all the state and methods listed below:
State
boolean
(will the audio loop)boolean
(is the sound loaded and ready to play)boolean
(is the sound paused)boolean
(is the sound stopped)boolean
(is the sound playing)number
(the length in seconds)boolean
(is the sound muted)number
(the playback rate)number
(the volume level 0 - 1.0)string
(error message if any after attemped load)Methods
play (
() => void
)pause (
() => void
)togglePlayPause (
() => void
)stop (
() => void
)mute (
(muted?: boolean) => void
)setVolume (
(volume: number) => void
)fade (
(from: number, to: number, duration: number) => void
)setRate (
(speed: number) => void
)seek (
(seconds: number) => void
)getPosition (
() => number
)load (
(src: string, options?: AudioLoadOptions) => void
)Quick Recipes & Gotchas
Recipe: Switching between sounds on a single audio player
Switching from one sound the next is a common use-case (i.e. a playlist queue). This can be done in a couple of different ways:
Alternatively, you can queue up the next song to play when the current sound ends. You can see a full, working example of this in the
AutoPlayNextSong
component in /examples.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.
When streaming or working with large files make sure to use the
html5
option of the#load
function.Also, if your sound src string does not contain an extension (like if you are fetching a stream from an API), be sure to set it with the
format
option of the#load
function.More information in this Howler thread
Beta Was this translation helpful? Give feedback.
All reactions