【问题标题】:Render HTMLAudioElement DOM element with React使用 React 渲染 HTMLAudioElement DOM 元素
【发布时间】:2019-09-18 13:37:33
【问题描述】:

我在我的项目中使用 Twillio JS API 来显示来自多个来源的视频输出。此 API 生成可附加到页面的 DOM 视频/音频元素的枚举,如下所示:

let tracks = TwillioVideo.createLocalTracks({
  video: { deviceId: this.state.selectedVideoInput.deviceId },
  audio: { deviceId: this.state.selectedAudioInput.deviceId }
}
//Find dom element to attach tracks to
let previewContainer = document.getElementById('local-media')

//Attach all tracks
this.setState({localTracks: tracks})
tracks.forEach(track => previewContainer.appendChild(track.attach()))

track.attach() 生成一个可以附加的 dom 元素,但它不是我可以放入 React 状态的东西,因此它可以像这样呈现:

<div id="local-media">{this.state.localTracks.map(track => track.attach()}</div>

如果我真的尝试这样做,我会得到:

未处理的拒绝(不变违规):对象作为无效的 反应孩子(找到:[object HTMLAudioElement])。如果你打算渲染 子集合,请改用数组。

编辑 1: 通过这样做,我能够摆脱错误:

{this.state.localTracks.map(track => track.attach().Element)}

但它没有返回可渲染的 html,而是返回 undefined

【问题讨论】:

    标签: javascript reactjs twilio twilio-api


    【解决方案1】:

    这里是 Twilio 开发者宣传员。

    attach method in Twilio Video 可以接受一个参数,即HTMLMediaElement,并将媒体附加到该元素。

    我建议您创建一个组件,用于渲染每个媒体轨道的媒体,然后使用React refs 获取指向 DOM 元素的指针。

    类似这样的:

    import React, { Component, createRef } from 'react';
    
    class Participant extends Component {
      constructor(props) {
        super(props);
        this.video = createRef();
        this.audio = createRef();
        this.trackAdded = this.trackAdded.bind(this);
      }
    
      trackAdded(track) {
        if (track.kind === 'video') {
          track.attach(this.video.current);
        } else if (track.kind === 'audio') {
          track.attach(this.audio.current);
        }
      }
    
      componentDidMount() {
        const videoTrack = Array.from(
          this.props.participant.videoTracks.values()
        )[0];
        if (videoTrack) {
          videoTrack.attach(this.video.current);
        }
        const audioTrack = Array.from(
          this.props.participant.audioTracks.values()
        )[0];
        if (audioTrack) {
          audioTrack.attach(this.audio.current);
        }
    
        this.props.participant.on('trackAdded', this.trackAdded);
      }
    
      render() {
        return (
          <div className="participant">
            <h3>{this.props.participant.identity}</h3>
            <video ref={this.video} autoPlay={true} muted={true} />
            <audio ref={this.audio} autoPlay={true} muted={true} />
          </div>
        );
      }
    }
    
    export default Participant;
    

    然后,对于聊天中的每个参与者,您可以渲染其中一个组件。

    让我知道这是否有帮助。

    【讨论】:

    • 如果我有任意数量的曲目我该怎么办? (多个用户动态加入)我需要一些动态创建 mediaElements 的方法
    • 在这种情况下,我为每个参与者呈现这些组件之一。您可以更进一步,将&lt;video&gt;&lt;audio&gt; 元素移动到它们自己的组件中,并带有单独的引用,因此您可以为用户提供多个。您是否尝试过这种方法?
    • 酷,告诉我进展如何!
    • philnash,好像 attach() 只能接受从版本 2 开始的参数。但是 v.2x 仍处于 beta 测试阶段,在生产环境中使用是否安全?
    • v1 也支持。在此处查看文档:media.twiliocdn.com/sdk/js/video/releases/1.19.2/docs/…
    猜你喜欢
    • 2021-03-26
    • 1970-01-01
    • 2022-12-10
    • 2020-08-20
    • 1970-01-01
    • 2017-05-04
    • 1970-01-01
    • 2020-03-30
    • 2021-03-19
    相关资源
    最近更新 更多