将 AttachMediaStream 与 React Render 方法一起使用?
Using AttachMediaStream with React Render Method?
我正在努力将 AttachMediaStream 集成到使用 React 的程序中。
我可以像这样将媒体流附加到元素:
var vid = document.getElementById("myVideo");
attachMediaStream(vid, stream);
但这在 React Render 方法之外,我认为应该发生这样的事情。
如果我按原样放置,在 React Render 方法中,它会运行 每次Render 方法运行s。
这是我想到的一种方法:
- 向组件添加两个变量:
- this.mediaStreamNeedsToBeAttached
- this.props.mediaStream
- 请注意
this.mediaStreamNeedsToBeAttached
不是 this.state
或 this.props
的一部分。如果是,则在 Render 方法中切换它是不合法的。
- 获取媒体流时,组件:
- 将
this.mediaStreamNeedsToBeAttached
设置为真;
- 运行s
this.setProps({ mediaStream: newlyObtainedMediaStream });
导致 Render 方法 运行.
- 渲染方法:
- 检查
this.mediaStreamNeedsToBeAttached
是否为真
- 如果是这样,运行s
attachMediaStream(vid, this.props.mediaStream)
并切换 this.mediaStream
我 猜测 会起作用,但我想我会在这里查看是否有其他人有更优雅的解决方案。
如有任何想法或意见,我们将不胜感激!
我也遇到了这个问题,似乎访问虚拟 dom 的方式和 attachMediaStream
的工作方式有些不连续。
我正在将 MediaStream
对象置于状态中并尝试对其调用 attachMediaStream
... 但由于某种原因它没有附加。
(我使用的是 redux)但概念是一样的):
componentDidMount = () => {
setTimeout((function () {
console.log('Attaching media stream')
attachMediaStream(this.props.stream, this.video);
}).bind(this), 0);
}
render() {
return (
<video ref={(video) => { this.video = video; }} />
)
}
我使用 ref
(https://reactjs.org/docs/refs-and-the-dom.html) 获取虚拟媒体元素,并在 componentDidMount
中调用它,因为它可以访问 DOM 但不修改状态。
2018 年 10 月更新
根据 this article,我了解到 React 目前与领先的 WebRTC 服务提供商 100% 不兼容。到目前为止,我已经与两个 WebRTC 服务提供商合作,并且都需要 dom 元素的 ID,并将视频流附加到它,不是通过 React,而是通过直接 dom 操作。在 React 渲染中,完成的渲染中间歇性地缺少这些流。
它断断续续的原因是存在竞争条件。 React 将 运行 呈现函数,并且您的 WebRTC 代码独立地订阅视频流并尝试将其附加到呈现器创建的元素。如果订阅尝试将视频流附加到元素,则在渲染函数创建它之前,完成的渲染中会丢失该流。
根据同一篇文章,解决方案是通过 dom 操作插入所有与 WebRTC 相关的 dom 元素,从而完全将 React 从 WebRTC 中分离出来,例如:
let elDialUIContainer = document.querySelector('#dialComponentUIContainer');
if (!elDialUIContainer) {
elDialUIContainer = document.createElement('div');
elDialUIContainer.setAttribute('id', 'dialComponentUIContainer');
elDialUIContainer.setAttribute('style', this.styleObjectToString(styles.dialComponentUIContainer));
elContentContainer.prepend(elDialUIContainer);
}
[.....]
if (localThis.applicationState.remoteVideoStream) {
console.log('attaching remoteVideoStream to #video' + localThis.applicationState.remoteVideoStream.getId());
let elOtherCallerVideoStream = document.querySelector('#video' + localThis.applicationState.remoteVideoStream.getId());
if (!elOtherCallerVideoStream) {
localThis.applicationState.remoteVideoStream.play('remoteCallerVideo');
}
}
...等这些元素被添加到 dom 元素中,该元素位于 React 渲染函数为该组件生成的元素之上和之外——因此当渲染函数 运行s 时,它们不会受到影响。
我有一个函数 addWebRTCElements
,可以将这些元素添加到 dom。它由 ComponentDidMount()
调用,每次发生 WebRTC 事件时也会调用它,例如远程流进来。
已过时:2018 年 9 月更新
这是另一种方法,使用 React createRef()
:
获取视频元素的 React 引用。在 React 组件构造函数中:
this.refToMyVideo = React.createRef();
将 html 元素附加到此参考。在 React 渲染函数中:
<video ref={this.refToMyVideo}>
</video>
- 当视频流可用时使用 ref:
let vidElement = this.refToMyVideo.current;
attachMediaStream(vidElement, stream);
vidElement.onloadedmetadata = function(e) {
vidElement.play();
};
关于 React createRef 的文档是 here。
过时:自 2017 年 12 月起:
@jordan,我认为你说得很对:'discontinuity in the way accessing the virtual dom and how attachMediaStream works.'
以下是我的处理方式。到目前为止它似乎工作正常,尽管可能有更优雅的解决方案。
function attachMediaStreamToElement(idToWaitFor, stream){
const elementExists = $(idToWaitFor).length > 0;
if (elementExists) {
const idToWaitForMinusPoundSign = idToWaitFor.replace("#", "");
var vid = document.getElementById(idToWaitForMinusPoundSign);
attachMediaStream(vid, stream);
}
else {
setTimeout(function () {
attachMediaStreamToElement(idToWaitFor, idToWaitFor, stream)
}, 50);
}
}
我在流可用后立即调用它。该例程等待 Render 函数呈现目标元素,然后将流附加到它。
我正在努力将 AttachMediaStream 集成到使用 React 的程序中。
我可以像这样将媒体流附加到元素:
var vid = document.getElementById("myVideo");
attachMediaStream(vid, stream);
但这在 React Render 方法之外,我认为应该发生这样的事情。
如果我按原样放置,在 React Render 方法中,它会运行 每次Render 方法运行s。
这是我想到的一种方法:
- 向组件添加两个变量:
- this.mediaStreamNeedsToBeAttached
- this.props.mediaStream
- 请注意
this.mediaStreamNeedsToBeAttached
不是this.state
或this.props
的一部分。如果是,则在 Render 方法中切换它是不合法的。 - 获取媒体流时,组件:
- 将
this.mediaStreamNeedsToBeAttached
设置为真; - 运行s
this.setProps({ mediaStream: newlyObtainedMediaStream });
导致 Render 方法 运行.
- 将
- 渲染方法:
- 检查
this.mediaStreamNeedsToBeAttached
是否为真 - 如果是这样,运行s
attachMediaStream(vid, this.props.mediaStream)
并切换this.mediaStream
- 检查
我 猜测 会起作用,但我想我会在这里查看是否有其他人有更优雅的解决方案。
如有任何想法或意见,我们将不胜感激!
我也遇到了这个问题,似乎访问虚拟 dom 的方式和 attachMediaStream
的工作方式有些不连续。
我正在将 MediaStream
对象置于状态中并尝试对其调用 attachMediaStream
... 但由于某种原因它没有附加。
(我使用的是 redux)但概念是一样的):
componentDidMount = () => {
setTimeout((function () {
console.log('Attaching media stream')
attachMediaStream(this.props.stream, this.video);
}).bind(this), 0);
}
render() {
return (
<video ref={(video) => { this.video = video; }} />
)
}
我使用 ref
(https://reactjs.org/docs/refs-and-the-dom.html) 获取虚拟媒体元素,并在 componentDidMount
中调用它,因为它可以访问 DOM 但不修改状态。
2018 年 10 月更新
根据 this article,我了解到 React 目前与领先的 WebRTC 服务提供商 100% 不兼容。到目前为止,我已经与两个 WebRTC 服务提供商合作,并且都需要 dom 元素的 ID,并将视频流附加到它,不是通过 React,而是通过直接 dom 操作。在 React 渲染中,完成的渲染中间歇性地缺少这些流。
它断断续续的原因是存在竞争条件。 React 将 运行 呈现函数,并且您的 WebRTC 代码独立地订阅视频流并尝试将其附加到呈现器创建的元素。如果订阅尝试将视频流附加到元素,则在渲染函数创建它之前,完成的渲染中会丢失该流。
根据同一篇文章,解决方案是通过 dom 操作插入所有与 WebRTC 相关的 dom 元素,从而完全将 React 从 WebRTC 中分离出来,例如:
let elDialUIContainer = document.querySelector('#dialComponentUIContainer');
if (!elDialUIContainer) {
elDialUIContainer = document.createElement('div');
elDialUIContainer.setAttribute('id', 'dialComponentUIContainer');
elDialUIContainer.setAttribute('style', this.styleObjectToString(styles.dialComponentUIContainer));
elContentContainer.prepend(elDialUIContainer);
}
[.....]
if (localThis.applicationState.remoteVideoStream) {
console.log('attaching remoteVideoStream to #video' + localThis.applicationState.remoteVideoStream.getId());
let elOtherCallerVideoStream = document.querySelector('#video' + localThis.applicationState.remoteVideoStream.getId());
if (!elOtherCallerVideoStream) {
localThis.applicationState.remoteVideoStream.play('remoteCallerVideo');
}
}
...等这些元素被添加到 dom 元素中,该元素位于 React 渲染函数为该组件生成的元素之上和之外——因此当渲染函数 运行s 时,它们不会受到影响。
我有一个函数 addWebRTCElements
,可以将这些元素添加到 dom。它由 ComponentDidMount()
调用,每次发生 WebRTC 事件时也会调用它,例如远程流进来。
已过时:2018 年 9 月更新
这是另一种方法,使用 React createRef()
:
获取视频元素的 React 引用。在 React 组件构造函数中:
this.refToMyVideo = React.createRef();
将 html 元素附加到此参考。在 React 渲染函数中:
<video ref={this.refToMyVideo}> </video>
- 当视频流可用时使用 ref:
let vidElement = this.refToMyVideo.current; attachMediaStream(vidElement, stream); vidElement.onloadedmetadata = function(e) { vidElement.play(); };
关于 React createRef 的文档是 here。
过时:自 2017 年 12 月起:
@jordan,我认为你说得很对:'discontinuity in the way accessing the virtual dom and how attachMediaStream works.'
以下是我的处理方式。到目前为止它似乎工作正常,尽管可能有更优雅的解决方案。
function attachMediaStreamToElement(idToWaitFor, stream){
const elementExists = $(idToWaitFor).length > 0;
if (elementExists) {
const idToWaitForMinusPoundSign = idToWaitFor.replace("#", "");
var vid = document.getElementById(idToWaitForMinusPoundSign);
attachMediaStream(vid, stream);
}
else {
setTimeout(function () {
attachMediaStreamToElement(idToWaitFor, idToWaitFor, stream)
}, 50);
}
}
我在流可用后立即调用它。该例程等待 Render 函数呈现目标元素,然后将流附加到它。