使用AttachMediaStream和React Render方法?

时间:2017-11-15 21:29:00

标签: reactjs webrtc skylink temasys

我正致力于将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方法时运行。

这是我遇到的一种方法:

  • 向组件添加两个变量:
    • this.mediaStreamNeedsToBeAttached
    • this.props.mediaStream
  • 请注意,var vid = document.getElementById("myVideo"); attachMediaStream(vid, stream); 不属于this.mediaStreamNeedsToBeAttachedthis.state。如果是的话,在Render方法中切换它是不合法的。
  • 获取媒体流时,组件:
    • this.props设为true;
    • 运行this.mediaStreamNeedsToBeAttached,导致Render方法运行。
  • 渲染方法:
    • 检查this.setProps({ mediaStream: newlyObtainedMediaStream });是否为真
    • 如果是,请运行this.mediaStreamNeedsToBeAttached并切换attachMediaStream(vid, this.props.mediaStream)

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

任何想法或意见都将不胜感激!

2 个答案:

答案 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()

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

    this.refToMyVideo = React.createRef();

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

  3. <video ref={this.refToMyVideo}>
    </video>
    
    1. 视频流可用时使用参考:
    2. 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,但不会修改状态。