Skip to content

Commit

Permalink
fix(useScreenCapture): update the hook's states
Browse files Browse the repository at this point in the history
  • Loading branch information
malkiii committed Jul 25, 2024
1 parent d8298f3 commit 01ea90a
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 34 deletions.
2 changes: 1 addition & 1 deletion packages/hooks/src/useMediaDevices/index.page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function Camera() {
return (
<div className="demo">
<div className="w-fit max-w-md mx-auto *:justify-center">
<video autoPlay muted className="w-full min-h-60 rounded-md border" />
<video autoPlay playsInline muted className="w-full min-h-60 rounded-md border" />
{media.stream ? (
<button className="border mt-4 w-full justify-center" onClick={() => media.stop()}>
Stop
Expand Down
21 changes: 12 additions & 9 deletions packages/hooks/src/useScreenCapture/index.page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,26 @@ export function ScreenCapture() {
const capture = useScreenCapture({ video: true });

React.useEffect(() => {
if (capture.isEnabled) {
const video = document.querySelector('video');
video.srcObject = capture.streamRef.current;
}
}, [capture.isEnabled]);
const video = document.querySelector('video');
video.srcObject = capture.stream;
}, [capture.stream]);

return (
<div className="demo">
<div className="w-fit max-w-lg mx-auto *:justify-center">
<video autoPlay muted className="w-full min-h-60 rounded-md border" />
{capture.isEnabled ? (
<video autoPlay playsInline muted className="w-full min-h-60 rounded-md border" />
{capture.stream ? (
<button className="border mt-4 w-full justify-center" onClick={() => capture.stop()}>
Stop
</button>
) : (
<button className="primary mt-4 w-full" onClick={() => capture.start()}>
Start
<button
className="primary mt-4 w-full transition-all"
disabled={capture.isPending}
style={{ opacity: capture.isPending ? 0.5 : 1 }}
onClick={() => capture.start()}
>
{capture.isPending ? 'Loading...' : 'Start'}
</button>
)}
</div>
Expand Down
43 changes: 19 additions & 24 deletions packages/hooks/src/useScreenCapture/index.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,34 @@
import { useCallback, useRef, useState } from 'react';
import { useCallback, useState } from 'react';

/**
* @see {@link https://malkiii.github.io/react-pre-hooks/docs/hooks/useScreenCapture | useScreenCapture} hook.
*/
export const useScreenCapture = (options: DisplayMediaStreamOptions = {}) => {
const streamRef = useRef<MediaStream>();
const [isEnabled, setIsEnabled] = useState<boolean>(false);
const [stream, setStream] = useState<MediaStream | null>(null);
const [isPending, setIsPending] = useState(false);

const startStreaming = useCallback(async () => {
streamRef.current?.getTracks().forEach(t => t.stop());
setIsPending(true);
stream?.getTracks().forEach(t => t.stop());

try {
streamRef.current = await navigator.mediaDevices.getDisplayMedia(options);
const videoTrack = streamRef.current.getVideoTracks().at(0);
if (videoTrack) videoTrack.onended = () => setIsEnabled(false);
const newStream = await navigator.mediaDevices.getDisplayMedia(options);
const videoTrack = newStream.getVideoTracks()[0];
if (videoTrack) videoTrack.onended = () => setStream(null);

setIsEnabled(true);
} catch (error) {
setIsEnabled(false);
throw error;
setStream(newStream);
setIsPending(false);

return newStream;
} finally {
setIsPending(false);
}
}, []);
}, [stream]);

const stopStreaming = useCallback(() => {
streamRef.current?.getTracks().forEach(t => t.stop());
setIsEnabled(false);
}, []);

const toggle = useCallback(
async (force?: boolean) => {
const shouldStart = force ?? !isEnabled;
shouldStart ? await startStreaming() : stopStreaming();
},
[isEnabled]
);
stream?.getTracks().forEach(t => t.stop());
setStream(null);
}, [stream]);

return { streamRef, start: startStreaming, stop: stopStreaming, toggle, isEnabled };
return { stream, start: startStreaming, stop: stopStreaming, isPending };
};

0 comments on commit 01ea90a

Please sign in to comment.