Reactjs 如何在React&;中处理音频播放;重演

Reactjs 如何在React&;中处理音频播放;重演,reactjs,audio,redux,Reactjs,Audio,Redux,我正在制作一个音频播放器。它具有暂停、回放和时间搜索功能。如何以及谁应该处理音频元素 我可以把它放在商店旁边。我不能直接把它放到州里,因为它可能会被克隆。然后在减速器中,我可以与它交互。问题是,如果我需要将时间滑块与音频同步,我将需要使用动作不断轮询存储。从语义上讲,它也没有真正意义 我可以创建一个定制的React组件,Audio,它完成了我所说的一切。这个问题没有解决。如何刷新滑块?我可以投票,但我真的不喜欢这个解决方案。此外,除非我创建一个同时包含音频和滑块的组件,否则我仍然需要使用red

我正在制作一个音频播放器。它具有暂停、回放和时间搜索功能。如何以及谁应该处理音频元素

  • 我可以把它放在商店旁边。我不能直接把它放到州里,因为它可能会被克隆。然后在减速器中,我可以与它交互。问题是,如果我需要将时间滑块与音频同步,我将需要使用动作不断轮询存储。从语义上讲,它也没有真正意义
  • 我可以创建一个定制的React组件,Audio,它完成了我所说的一切。这个问题没有解决。如何刷新滑块?我可以投票,但我真的不喜欢这个解决方案。此外,除非我创建一个同时包含音频和滑块的组件,否则我仍然需要使用redux来连接这两个组件

那么,用进度显示来处理音频的最简单的方法是什么呢?

redux-这一切都与状态和一致性有关

你的目标是保持歌曲时间和进度条同步

我看到两种可能的方法:

1.把一切都留在店里。 因此,您必须将歌曲的当前时间(例如,以秒为单位)保留在存储中,因为有一些依赖的组件,如果没有存储,很难同步它们

您几乎没有更改当前时间的事件:

  • 当前时间本身。例如,每1秒
  • 倒带
  • 时间在寻找
在时间更改时,您将发送一个操作,并使用新时间更新存储。因此,保持当前歌曲的时间,所有组件都将同步

使用操作调度、减缩器和存储管理单向数据流中的状态是实现任何组件的Redux方法

下面是#1 aproach的伪代码:

class AudioPlayer extends React.Component {

    onPlay(second) {
        // Store song current time in the Store on each one second
        store.dispatch({ type: 'SET_CURRENT_SECOND', second });
    }

    onRewind(seconds) {
        // Rewind song current time
        store.dispatch({ type: 'REWIND_CURRENT_SECOND', seconds });
    }   

    onSeek(seconds) {
        // Seek song current time
        store.dispatch({ type: 'SEEK_CURRENT_SECOND', seconds });
    }

    render() {
        const { currentTime, songLength } = this.state;

        return <div>
            <audio onPlay={this.onPlay} onRewind={this.onRewind} onSeek={this.onSeek} />

            <AudioProgressBar currentTime songLength />
        </div>
    }
}
class AudioPlayer扩展了React.Component{
在线游戏(第二){
//每秒钟在存储中存储歌曲当前时间
dispatch({type:'SET_CURRENT_SECOND',SECOND});
}
正在倒带(秒){
//倒带歌曲当前时间
dispatch({type:'revind\u CURRENT\u SECOND',seconds});
}   
星期一(秒){
//查找歌曲当前时间
dispatch({type:'SEEK_CURRENT_SECOND',seconds});
}
render(){
const{currentTime,songLength}=this.state;
返回
在componentDidMount生命周期方法中

HTML5音频标签具有DOM事件,您可以在不接触存储的情况下保持两个组件的同步。如果需要在存储中保存某些内容,您可以随时保存

请看一看并检查它是如何处理引用的,以及插件公开了什么API。当然你可以从中获得灵感。你也可以在你的用例中重用它

以下是一些与您的问题相关的API方法:

  • OnSeek-当用户将时间指示器拖到新时间时调用。已传递事件
  • onPlay-当用户点击play时调用。已传递事件
  • onPause-当用户暂停播放时调用。已传递事件
  • onListen-在播放过程中调用every listenInterval毫秒。已传递事件

我应该使用什么方法? 这取决于您的用例具体情况。但是,一般来说,在这两种方法中,使用必要的API方法实现一个应用程序是一个好主意,并且由您决定在存储中管理多少数据

因此,我为您创建了一个开始组件,以说明如何处理音频和滑块的引用。包括开始/停止/搜索功能。当然它有缺点,但正如我已经提到的,这是一个很好的起点

您可以使用良好的API方法将其发展为一个表示组件,以满足您的需要

class音频扩展React.Component{
建造师(道具){
超级(道具);
此.state={
持续时间:空
}
};
handlePlay(){
这个.audio.play();
}
手杖{
this.audio.currentTime=0;
this.slider.value=0;
this.audio.pause();
}
componentDidMount(){
this.slider.value=0;
this.currentTimeInterval=null;
//获取歌曲的持续时间并将其设置为最大滑块值
this.audio.onloadedmetadata=函数(){
this.setState({duration:this.audio.duration});
}.约束(本);
//将滑块位置与歌曲当前时间同步
this.audio.onplay=()=>{
this.currentTimeInterval=setInterval(()=>{
this.slider.value=this.audio.currentTime;
}, 500);
};
this.audio.onpause=()=>{
clearInterval(此.currentTimeInterval);
};
//搜索功能
this.slider.onchange=(e)=>{
clearInterval(此.currentTimeInterval);
this.audio.currentTime=e.target.value;
};
}
render(){
常量src=”https://mp3.gisher.org/download/1000/preview/true";
返回
{this.audio=audio}}src={src}/>
{this.slider=slider}}
type=“范围”
name=“积分”
min=“0”max={this.state.duration}/>

} } ReactDOM.render(,document.getElementById('container'))


如果您需要同时拥有多个玩家,您可以给每个玩家一个唯一的id,在所有动作中传递该id,并将商店中的所有内容都放在玩家id下。没错!这两种方法都适用。非常感谢:)命令式设计似乎更适合这一种,因为这不会对性能造成太大影响。我仍然会保存一些东西,但是我仍然会使用状态来保存一些东西,比如track ended…还有,我如何从声明性代码传递到命令性代码。也就是说,假设我有一个AudioComponent,它接受曲目名称、艺术家名称和音频url。如何确保该组件在状态更改时不会被销毁?如何收听状态更改?例如,我想更改音频源,我的父母