Skip to content

Commit

Permalink
feat(core): add useDisplayMedia (vitest-dev#835)
Browse files Browse the repository at this point in the history
  • Loading branch information
soub4i committed Oct 16, 2021
1 parent 4dd83e3 commit 305c283
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 0 deletions.
31 changes: 31 additions & 0 deletions packages/core/useDisplayMedia/demo.vue
@@ -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>
35 changes: 35 additions & 0 deletions packages/core/useDisplayMedia/index.md
@@ -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`
84 changes: 84 additions & 0 deletions packages/core/useDisplayMedia/index.ts
@@ -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>

0 comments on commit 305c283

Please sign in to comment.