(React js) 音频 src 在 setState 上更新,但音频播放没有改变

IT技术 javascript reactjs audio
2021-05-22 09:44:02

我正在尝试使用 React 构建一个迷你 2 轨音频播放器。音频由 html 音频元素集中控制,该元素在子组件内具有轨道列表。可以在此处查看(尚未设计样式)播放器

我可以在 React 开发工具中看到,单击单个轨道选择按钮确实会更新音频元素的 src(感谢这里的成员的帮助),但是,播放的音频不会改变。我已经在下面发布了应用程序代码。

甚至可以通过以这种方式更新状态来更改播放音频吗?帮助将不胜感激。

var TRACKLIST = [
    {
        id: 1,
        name: "song a",
        source: "./audio/test.m4a"
    },
    {
        id: 2,
        name: "song b",
        source: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/557257/wwy.mp3"
    }
]

function Track(props) {
    return (
        <div className="track">
            <div className="meta">
                <div className="name">
                    <h2>{props.name}</h2>
                </div>
                <audio>
                    <source src={props.source} />
                </audio>
            </div>
            <button className="select" onClick={function() {props.onChange(props.source);}} >
            </button>
        </div>
    )
}

var Application = React.createClass({

    getInitialState: function() {
        return {
            isPlaying: "./audio/test.m4a"
        };
    },

    onTrackChange: function(source) {
        this.setState({ isPlaying: source })
    },

    render: function() {
        return (
            <div className="player">
                <div className="tracklist">
                    {this.props.tracklist.map(function(track){
                        return <Track
                                    key={track.id}
                                    name={track.name}
                                    source={track.source}
                                    onChange={this.onTrackChange} />
                    }.bind(this))}
                </div>
                <div className="controls">
                    <audio controls>
                        <source src={this.state.isPlaying} />
                    </audio>
                </div>
            </div>
        )
    }
});

// Render the UI
ReactDOM.render(
    <Application tracklist={TRACKLIST} />,
    document.getElementById('Player')
);
4个回答

src由于存在缓存,因此无法仅通过更改图像等方式来更改音频文件你将需要load它和play它一次。

onTrackChange: function(source) {
       this.setState({ isPlaying: source },function(){
            this.refs.audio.pause();
            this.refs.audio.load();
            this.refs.audio.play();
       })
}

回调处理状态改变后的暂停、加载和播放。请记住ref在音频标签中添加一个

<audio controls ref="audio">
   <source src={this.state.isPlaying} />
</audio>

使用钩子

导入useRef并创建它的一个实例。

import React, { useRef } from 'react';
const audioRef = useRef()

更新歌曲的功能。

const updateSong = (source) => {
    setSource(source);
    if(audioRef.current){
        audioRef.current.pause();
        audioRef.current.load();
        audioRef.current.play();
    }
}

不要忘记将ref添加到音频标签。

<audio controls ref={audioRef}>
    <source src={source} type='audio/mpeg' />
</audio>

使用钥匙

其实我认为解决这个问题的最好方法就是添加一个' key '属性:

<audio key={props.id}>
    <source src={props.source}/>
</audio>

有效  很好的解决办法 谢谢!

2023-01-10 14:59:55

如果您可以放弃播放状态和时间,则可以根据源在音频标签上设置不同的键属性。