将 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。

这是我想到的一种方法:

猜测 会起作用,但我想我会在这里查看是否有其他人有更优雅的解决方案。

如有任何想法或意见,我们将不胜感激!

我也遇到了这个问题,似乎访问虚拟 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():

  1. 获取视频元素的 React 引用。在 React 组件构造函数中:

    this.refToMyVideo = React.createRef();

  2. 将 html 元素附加到此参考。在 React 渲染函数中:

<video ref={this.refToMyVideo}>
</video>
  1. 当视频流可用时使用 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 函数呈现目标元素,然后将流附加到它。