Skip to content

feat(VVideo): add src-object prop for MediaStream/WebRTC#22670

Merged
J-Sek merged 9 commits intovuetifyjs:masterfrom
mixelburg:feat/vvideo-src-object
Mar 18, 2026
Merged

feat(VVideo): add src-object prop for MediaStream/WebRTC#22670
J-Sek merged 9 commits intovuetifyjs:masterfrom
mixelburg:feat/vvideo-src-object

Conversation

@mixelburg
Copy link
Copy Markdown
Contributor

@mixelburg mixelburg commented Mar 2, 2026

Description

Adds a srcObject prop to v-video, allowing users to attach a MediaStream, MediaSource, or Blob as the video source without using the src attribute.

This is particularly useful for WebRTC streaming where a MediaStream is obtained from navigator.mediaDevices.getUserMedia() or an RTCPeerConnection.

Changes

  • Added srcObject prop (MediaStream | MediaSource | Blob) to makeVVideoProps()
  • Added a watcher that sets videoRef.value.srcObject when the prop changes, and triggers the video element to render if needed
  • Added a watcher on videoRef to apply a pending srcObject when the element lazily mounts
  • Updated API locale (VVideo.json) with a description for the new prop

Usage

<script setup>
  import { onMounted, ref } from 'vue'

  const stream = ref(null)
  const streamAccessError = ref('')

  async function loadCameraStream () {
    await new Promise(r => setTimeout(r, 1000))
    return navigator.mediaDevices.getUserMedia({ video: true })
      .then(v => stream.value = v)
      .catch(err => streamAccessError.value = err)
  }

  async function retry () {
    streamAccessError.value = false
    await loadCameraStream()
  }

  onMounted(async () => {
    await loadCameraStream()
  })
</script>

<template>
  <v-app theme="dark">
    <v-container max-width="600">
      <v-card>
        <v-video
          :error="!!streamAccessError"
          :src-object="stream"
          height="400"
          autoplay
          muted
          @retry="retry"
        >
          <template #header>
            <v-slide-y-transition>
              <v-alert
                v-if="streamAccessError"
                :text="streamAccessError.message"
                title="No access to the video stream"
                type="error"
              />
            </v-slide-y-transition>
          </template>
        </v-video>
      </v-card>
    </v-container>
  </v-app>
</template>

Closes

Closes #22568

Closes vuetifyjs#22568

Adds a `srcObject` prop to allow attaching a `MediaStream`,
`MediaSource`, or `Blob` as the video source. This is especially
useful for WebRTC streaming where a `MediaStream` is obtained from
`getUserMedia` or a peer connection.

Unlike `src`, the `srcObject` property must be set programmatically
on the `<video>` element rather than as an HTML attribute.

Example:
```vue
<v-video :src-object="stream" />
```
Copy link
Copy Markdown
Contributor

@J-Sek J-Sek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have upgraded the demo in the description. Would it make sense for the VVideo to show an error state instead of spinning infinitely?

…ilure

- Add onError handler to video element that sets state to 'error'
- Emit new 'error' event when video fails to load
- Hide loading spinner and poster in error state
- Show error icon overlay (using $error icon alias)
- Clicking in error state retries via videoRef.load()
@mixelburg
Copy link
Copy Markdown
Contributor Author

Great point, @J-Sek! I've just pushed a fix for this — the video element now has an onError handler that transitions state to 'error' and emits a new error event. In error state:

  • The loading spinner is hidden
  • The poster overlay is hidden
  • An error icon ($error) is shown in the center overlay
  • Clicking the video retries the load via videoRef.load()

The v-video--error CSS class is also applied to the root element so consumers can style the error state as needed.

@J-Sek
Copy link
Copy Markdown
Contributor

J-Sek commented Mar 8, 2026

If the device does not have a camera, this getUserMedia fails and the src-object is not set. Error state is helpful, but the initial failure is a case where we would need a binding error«-»retry.

I have updated the demo in the PR description again. Let me know if you can test it against disconnecting device or interrupting the stream somehow (after it started successfully). I want to make sure the onVideoError is triggered in scenarios involving src-object.

mixelburg and others added 2 commits March 12, 2026 09:30
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The error prop now syncs both ways — internal video errors set the
model, and parent can set error externally. Retry clears the model.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mixelburg
Copy link
Copy Markdown
Contributor Author

Updated the error prop to support v-model:error for bi-directional binding. Now when getUserMedia fails on the consumer side, setting :error="true" transitions VVideo to error state, and clicking to retry emits update:error with false. Internal video errors also sync back via update:error.

@J-Sek J-Sek added T: feature A new feature labs Must be completed for this component to leave labs C: VVideo labels Mar 13, 2026
@J-Sek J-Sek changed the title feat(VVideo): add srcObject prop for MediaStream/WebRTC support feat(VVideo): add src-object prop for MediaStream/WebRTC Mar 18, 2026
@J-Sek J-Sek merged commit 575e7c5 into vuetifyjs:master Mar 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C: VVideo labs Must be completed for this component to leave labs T: feature A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] V-Video set srcObject

2 participants