我正致力于将AttachMediaStream集成到使用React的程序中。
我可以将媒体流附加到这样的元素:
Ftable_rownames <- rownames(Ftable)
# transpose
Ftable <- t(Ftable)
# assign names from the stored object
colnames(Ftable) <- Ftable_rownames
但是在React Render方法之外,我认为这样的事情应该发生。
如果我把它放在里面 React Render方法中,它会在每次运行Render方法时运行。
这是我遇到的一种方法:
var vid = document.getElementById("myVideo");
attachMediaStream(vid, stream);
不属于this.mediaStreamNeedsToBeAttached
或this.state
。如果是的话,在Render方法中切换它是不合法的。this.props
设为true; this.mediaStreamNeedsToBeAttached
,导致Render方法运行。this.setProps({ mediaStream: newlyObtainedMediaStream });
是否为真this.mediaStreamNeedsToBeAttached
并切换attachMediaStream(vid, this.props.mediaStream)
我猜会起作用,但我想我会在这里查看其他人是否有更优雅的解决方案。
任何想法或意见都将不胜感激!
答案 0 :(得分:1)
2018年10月更新
Per this article,我了解到React目前与领先的WebRTC服务提供商100%不兼容。到目前为止,我已经与两个WebRTC服务提供商合作,并且都需要dom元素的ID,并将视频流附加到它,而不是通过React,而是通过直接dom操作。在React渲染上,这些流在完成的渲染中间歇性地丢失。
它间歇性的原因是因为有竞争条件。 React将运行渲染功能,并且WebRTC代码独立地订阅视频流并尝试将其附加到渲染创建的元素。如果订阅尝试将视频流附加到元素,则在渲染功能创建它之前,完成的渲染中缺少流。
根据同一篇文章,解决方案是通过dom操作插入所有与WebRTC相关的dom元素,完全从WebRTC中解散React,例如:
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渲染函数生成的元素的上方和外部 - 因此在渲染函数运行时它们不会受到影响。
我有一个函数addWebRTCElements
,它将这些元素添加到dom中。它由ComponentDidMount()
调用,每次WebRTC事件发生时也会调用它,例如一个远程流进来了。
结束:2018年9月更新
这是另一种方法,使用React createRef()
:
获取视频元素的React引用。在React组件构造函数中:
this.refToMyVideo = React.createRef();
将html元素附加到此引用。在React渲染函数中:
<video ref={this.refToMyVideo}> </video>
let vidElement = this.refToMyVideo.current; attachMediaStream(vidElement, stream); vidElement.onloadedmetadata = function(e) { vidElement.play(); };
React createRef上的文档为here。
外出:自2017年12月起:
@jordan,我认为你提出了一个很好的观点:'访问虚拟dom的方式不连续以及attachMediaStream如何工作。'
以下是我处理它的方式。它似乎工作到目前为止,虽然可能有一个更优雅的解决方案。
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函数呈现目标元素,然后将流附加到它。
答案 1 :(得分:0)
我也遇到了麻烦,似乎在访问虚拟dom和PublishUrl
工作方式方面存在一些不连续性。
我将attachMediaStream
对象置于状态并尝试在其上调用MediaStream
...但无论出于何种原因,它都没有附加。
(我使用的是redux),但概念是一样的):
attachMediaStream
我使用 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; }} />
)
}
(https://reactjs.org/docs/refs-and-the-dom.html)获取虚拟媒体元素,并在ref
中调用它,因为它可以访问DOM,但不会修改状态。