HTMLMediaElement:srcObject 属性

srcObjectHTMLMediaElement 接口的一个属性,用于设置或返回用作与 HTMLMediaElement 关联的媒体源的对象。

该对象可以是 MediaStreamMediaSourceBlobFile(继承自 Blob)。

注意:截至 2020 年 3 月,只有 Safari 完整支持 srcObject,即使用 MediaSourceMediaStreamBlobFile 对象作为值。其他浏览器支持 MediaStream 对象;在它们赶上来之前,请考虑回退到使用 URL.createObjectURL() 创建 URL 并将其分配给 HTMLMediaElement.src(请参见下面的示例)。此外,从 Chromium 108 版本开始,支持通过将专用工作线程 MediaSource 对象的 MediaSourceHandle 实例(从工作线程传输)分配给 srcObject 来附加该对象。

MediaStreamMediaSourceBlobFile 对象(尽管请参阅兼容性表以了解实际支持的内容)。

使用说明

早期版本的媒体源规范要求使用 URL.createObjectURL() 创建对象 URL,然后将 src 设置为该 URL。现在,您可以直接将 srcObject 设置为 MediaStream

示例

基本示例

在此示例中,来自摄像头的 MediaStream 被分配给新创建的 <video> 元素。

js
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true });
const video = document.createElement("video");
video.srcObject = mediaStream;

在此示例中,一个新的 MediaSource 被分配给新创建的 <video> 元素。

js
const mediaSource = new MediaSource();
const video = document.createElement("video");
video.srcObject = mediaSource;

支持回退到 src 属性

以下示例支持需要您创建对象 URL 并将其分配给 src(如果 srcObject 不受支持)的旧版浏览器。

首先,来自摄像头的 MediaStream 被分配给新创建的 <video> 元素,并为旧版浏览器提供回退。

js
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true });
const video = document.createElement("video");
if ("srcObject" in video) {
  video.srcObject = mediaStream;
} else {
  // Avoid using this in new browsers, as it is going away.
  video.src = URL.createObjectURL(mediaStream);
}

其次,一个新的 MediaSource 被分配给新创建的 <video> 元素,并为旧版浏览器和尚未直接支持 MediaSource 分配的浏览器提供回退。

js
const mediaSource = new MediaSource();
const video = document.createElement("video");
// Older browsers may not have srcObject
if ("srcObject" in video) {
  try {
    video.srcObject = mediaSource;
  } catch (err) {
    if (err.name !== "TypeError") {
      throw err;
    }
    // Even if they do, they may only support MediaStream
    video.src = URL.createObjectURL(mediaSource);
  }
} else {
  video.src = URL.createObjectURL(mediaSource);
}

在工作线程中构造 MediaSource 并将其传递到主线程以进行播放

MediaSource.handle 属性可以在专用工作线程内部访问,然后生成的 MediaSourceHandle 对象通过 postMessage() 调用传输到创建工作线程的线程(在本例中为主线程)。

js
// Inside dedicated worker
let mediaSource = new MediaSource();
let handle = mediaSource.handle;
// Transfer the handle to the context that created the worker
postMessage({ arg: handle }, [handle]);

mediaSource.addEventListener("sourceopen", () => {
  // Await sourceopen on MediaSource before creating SourceBuffers
  // and populating them with fetched media — MediaSource won't
  // accept creation of SourceBuffers until it is attached to the
  // HTMLMediaElement and its readyState is "open"
});

在主线程中,我们通过 message 事件处理程序接收句柄,通过其 HTMLMediaElement.srcObject 属性将其附加到 <video>,并 play 视频。

js
worker.addEventListener("message", (msg) => {
  let mediaSourceHandle = msg.data.arg;
  video.srcObject = mediaSourceHandle;
  video.play();
});

注意:MediaSourceHandle 不能成功传输到或通过共享工作线程或服务工作线程。

规范

规范
HTML 标准
# dom-media-srcobject-dev

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。