如何在React中设置音频元素的srcObject

20

我一直试图在React中设置音频标签的src属性,但音轨从未播放。

playTrack(track) {
    const stream = new MediaStream()
    stream.addTrack(track)
    this.setState(() => ({ stream }))
}

render() {
    return (
        <audio src={this.state.stream || null} controls volume="true" autoPlay />
    )
}

当我在Chrome调试器中检查时,显示音频标签的源已设置为[MediaStream],但没有任何声音播放,所有控件都保持灰色不可用状态。

与设置状态相比,这样做可以解决问题,但我认为在React中这是不被推荐的做法。

const audio = document.querySelector('audio')
audio.srcObject = stream
2个回答

28

如果将流存储在状态中不是必需的,则可以使用 ref 更新 srcObject 属性:

playTrack(track) {
    const stream = new MediaStream()
    stream.addTrack(track)
    this.audio.srcObject = stream;
}

render() {
    return (
        <audio ref={audio => {this.audio = audio}} controls volume="true" autoPlay />
    )
}

如果您确实需要从状态访问流,则可以尝试以下方法

<audio ref={audio => { audio.srcObject = this.state.stream }} />

src={this.state.stream}不能正常工作的原因是,src需要一个表示音频资源URL的字符串,而this.state.stream是一个MediaStream对象。

audio.srcaudio.srcObject是不同的属性,它们期望不同类型的值。


2
当我使用你的例子时,我得到了“audio is null”的错误提示,我需要在引用之前定义音频吗? - AJ_
2
@AJ_ 可能在构造函数中需要 this.audio = React.createRef(); 吗? - David Magalhães
1
没错,就是这样。 - AJ_
1
如果我有一个流数组,并且要使用该数组创建音频标签,该怎么办? - Ankita

7
对于那些使用道具并且不喜欢在每次渲染时创建函数的人:
constructor(props) {
  super(props)
  this.videoRef = React.createRef()
}

render() {
  return <video ref={this.videoRef}/>
}

componentDidMount() {
  this.updateVideoStream()    
}

componentDidUpdate() {
  this.updateVideoStream()
}

updateVideoStream() {
  if (this.videoRef.current.srcObject !== this.props.stream) {
    this.videoRef.current.srcObject = this.props.stream
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接