forked from vitest-dev/vitest
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): add useDisplayMedia (vitest-dev#835)
- Loading branch information
Showing
3 changed files
with
150 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<script setup lang="ts"> | ||
import { ref, watchEffect } from 'vue-demi' | ||
import { useDisplayMedia } from '.' | ||
const video = ref<HTMLVideoElement>() | ||
const { stream, enabled } = useDisplayMedia() | ||
watchEffect(() => { | ||
if (video.value) video.value.srcObject = stream.value! | ||
}) | ||
</script> | ||
|
||
<template> | ||
<div class="flex flex-col gap-4 text-center"> | ||
<div> | ||
<button @click="enabled = !enabled"> | ||
{{ enabled ? 'Stop' : 'Start' }} sharing my screen | ||
</button> | ||
</div> | ||
|
||
<div> | ||
<video | ||
ref="video" | ||
muted | ||
autoplay | ||
controls | ||
class="h-100 w-auto" | ||
/> | ||
</div> | ||
</div> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
--- | ||
category: Sensors | ||
--- | ||
|
||
# useDisplayMedia | ||
|
||
Reactive [`mediaDevices.getDisplayMedia`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia) streaming. | ||
|
||
## Usage | ||
|
||
```js | ||
import { useDisplayMedia } from '@vueuse/core' | ||
|
||
const { stream, start } = useDisplayMedia() | ||
|
||
// start streaming | ||
|
||
start() | ||
|
||
|
||
``` | ||
|
||
```ts | ||
const video = document.getElementById('video') | ||
|
||
watchEffect(() => { | ||
// preview on a video element | ||
video.srcObject = stream.value | ||
}) | ||
``` | ||
|
||
|
||
## Related | ||
|
||
- `useUserMedia` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
|
||
import { MaybeRef } from '@vueuse/shared' | ||
import { watch, Ref, ref, shallowRef } from 'vue-demi' | ||
import { ConfigurableNavigator, defaultNavigator } from '../_configurable' | ||
|
||
export interface UseDisplayMediaOptions extends ConfigurableNavigator { | ||
/** | ||
* If the stream is enabled | ||
* @default false | ||
*/ | ||
enabled?: MaybeRef<boolean> | ||
|
||
/** | ||
* If the stream video media constraints | ||
*/ | ||
video?: boolean | MediaTrackConstraints | undefined | ||
/** | ||
* If the stream audio media constraints | ||
*/ | ||
audio?: boolean | MediaTrackConstraints | undefined | ||
} | ||
|
||
/** | ||
* Reactive `mediaDevices.getDisplayMedia` streaming | ||
* | ||
* @see https://vueuse.org/useDisplayMedia | ||
* @param options | ||
*/ | ||
export function useDisplayMedia(options: UseDisplayMediaOptions = {}) { | ||
const enabled = ref(options.enabled ?? false) | ||
const video = options.video | ||
const audio = options.audio | ||
const { navigator = defaultNavigator } = options | ||
const isSupported = Boolean(navigator?.mediaDevices?.getDisplayMedia) | ||
|
||
const constraint: DisplayMediaStreamConstraints = { audio, video } | ||
|
||
const stream: Ref<MediaStream | undefined> = shallowRef() | ||
|
||
async function _start() { | ||
if (!isSupported || stream.value) | ||
return | ||
stream.value = await navigator!.mediaDevices.getDisplayMedia(constraint) | ||
return stream.value | ||
} | ||
|
||
async function _stop() { | ||
stream.value?.getTracks().forEach(t => t.stop()) | ||
stream.value = undefined | ||
} | ||
|
||
function stop() { | ||
_stop() | ||
enabled.value = false | ||
} | ||
|
||
async function start() { | ||
await _start() | ||
if (stream.value) | ||
enabled.value = true | ||
return stream.value | ||
} | ||
|
||
watch( | ||
enabled, | ||
(v) => { | ||
if (v) | ||
_start() | ||
else | ||
_stop() | ||
}, | ||
{ immediate: true }, | ||
) | ||
|
||
return { | ||
isSupported, | ||
stream, | ||
start, | ||
stop, | ||
enabled, | ||
} | ||
} | ||
|
||
export type UseDisplayMediaReturn = ReturnType<typeof useDisplayMedia> |