useAudio/useVideo play lock resets across renders
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 75/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- react, typescript
Research direction
Start at createHTMLMediaHook and the lockPlay handling described in the issue, then trace the media-event rerender path. Done means the lock survives rerenders until play() settles, with a focused regression test covering the pending-play pause case.
Written by the indexing model from the issue text.
Description
What is the current behavior?
useAudio and useVideo use a lockPlay local variable inside createHTMLMediaHook to avoid calling pause() while a pending HTMLMediaElement.play() promise is still resolving.
Because lockPlay is a plain local variable, it is recreated on every render. Media events such as play, playing, waiting, pause, durationchange, or timeupdate can call setState, causing a rerender before the original play() promise settles. After that rerender, the lock is reset to false, so a new controls.pause() call can run while the earlier play() promise is still pending.
This weakens the Chromium workaround described in the comment above the lock:
Some browsers return
Promiseon.play()and may throw errors if one tries to execute another.play()or.pause()while that promise is resolving.
Expected behavior
The play lock should persist across renders until the pending play() promise resolves or rejects.
Using a ref for the lock would preserve the intended behavior without changing the public API.
Why this matters
In video/audio-heavy UIs, components often call controls.play() and controls.pause() in response to store changes, user interactions, or source changes. If a media event causes a rerender while play() is still pending, the current lock can be lost and the hook can issue a conflicting pause().
Possible fix
Change the local variable:
let lockPlay = false;
to a ref-backed value, for example:
const lockPlay = useRef(false);
and read/write lockPlay.current inside the controls.
I can open a PR with a focused regression test if this direction sounds good.
- Dominant language
- TypeScript
- Stars
- 44k
- Forks
- 3.3k
- PR merge metrics
- No merged PRs in 30d
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from streamich/react-use
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Add Generic Fn for useDebouncePossibly taken @itsmejay80 claimed this 179 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
-
useVideo.story.tsx - sampleVideo can not be loadedMay be free again A pull request for this issue was closed without being merged. Open
Difficulty 1/5 Under an hour Newbie friendliness 62/100
-
useSlider: event callbacks are not updatedPossibly taken @erykpiast claimed this 1826 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
All issues in streamich/react-use
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 82/100
siyuan-note/siyuan#20313 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 92/100
alunduil/projects-v2-sync#14 ·
-
Service process inherits the caller's cwd at first use, holding that folder open on Windows (EBUSY)Open
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
DevTools page styles leak into the host app in developmentPossibly taken @onmax claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
nuxt-modules/better-auth#567 · 1 comment ·
Maintainers usually reply within 1 day