在React

时间:2018-05-30 01:00:03

标签: javascript reactjs audio

我有一个React组件,可以在单击按钮时播放/暂停音频。它工作得很好,我一次在一个页面上渲染其中的大约5个。但是,如果您单击一个播放,然后单击另一个播放,则两个音频都在播放,这并不是很好。这是我的组件代码:

import React from 'react';
import playIcon from './images/play.png';
import pauseIcon from './images/pause.png';
class Music extends React.Component {
    constructor(props) {
        super(props);
        this.state = { 'play': false };
        this.url = props.src;
        this.audio = new Audio(this.url);
        this.audio.preload = 'none';
        this.togglePlay = this.togglePlay.bind(this);
    }

    togglePlay() {
        this.setState({'play': !this.state.play}, () => {
            this.state.play ? this.audio.play() : this.audio.pause();
        });
    }

    componentWillUnmount () {
        this.audio.pause();
    }

    render() {
        return (
            <div style={this.props.style} className={this.props.className}>
                {this.state.play
                    ? <button className="audio-button" aria-label="Pause" onClick={this.togglePlay}><img src={pauseIcon} width="34" height="34" alt="Pause"></img></button>
                    : <button className="audio-button" aria-label="Play" onClick={this.togglePlay}><img src={playIcon} width="34" height="34" alt="Play"></img></button>}
            </div>
        );
    }
}

export default Music;

我已经做了一些环顾四周,潜在的解决方案是使用redux或其他一些状态管理库。我想避免这种情况,因为我在本网站上没有必要这样做。我已经调查了事件监听器(即solution proposed here)但是当我执行document.getElementsByTagName('audio')时,我得到了一个空的HTMLCollectionThis solution更接近,但我无法弥合它在jQuery中的实现与我在React中使用的那个之间的差距。

在播放新音频之前,有没有办法识别播放音频并从React Component暂停播放?任何和所有建议都表示赞赏。

3 个答案:

答案 0 :(得分:2)

import React from 'react';

import audio1 from './audio1.mp3';
import audio2 from './audio2.mp3';

class AudioList extends React.Component {
    constructor (props) {
        super(props);

        this.audios = props.list.map(audio => new Audio(audio));
    }

    getCurrentAudio () {
        return this.audios.find(audio => false === audio.paused);
    }

    toggle (nextAudio) {
        const currentAudio = this.getCurrentAudio();

        if (currentAudio && currentAudio !== nextAudio) {
            currentAudio.pause();
        }

        nextAudio.paused ? nextAudio.play() : nextAudio.pause();
    }

    render () {
        return (
            <div>
                { this.audios.map((audio, index) =>
                    <button onClick={() => this.toggle(audio) }>
                        PLAY AUDIO { index }
                    </button>
                ) }
            </div>
        )
    }
}


export default () => <AudioList list={[ audio1, audio2 ]} />;

PS:new Audio(url)返回 HTMLAudioElement

答案 1 :(得分:1)

创建一个处理音频的模块。将播放,暂停,恢复等方法公开给Music,并跟踪您拥有的所有五个Music实例中的不同音频。每当播放新音频时,暂停旧音频。

答案 2 :(得分:0)

得到了马学正和TheIncorrigible1的一些重要提示。基本上将音频移动到它自己的模块中。从中导出import pandas as pd import numpy as np, numpy.random numpy.random.seed(1) A_int = pd.DataFrame(np.random.randint(1,16,10).reshape(2,5)) A_int.iloc[1,4]= np.NAN int_vals = list(range(1,16)) chr_vals = [chr(n+96) for n in int_vals] A_chr = A_int.apply(axis=0, func=lambda x: pd.Categorical(x, categories=int_vals, ordered=True).rename_categories(chr_vals)) A_chr.apply(axis=1, func=lambda x: ''.join([str(i) for i in x[pd.notnull(x)]])) play方法,并在该模块中跟踪pause

我将currentlyPlaying组件调整为这样

Music

我的新模块import React from 'react'; import playIcon from './images/play.png'; import pauseIcon from './images/pause.png'; import globalAudio from './globalAudio'; class Music extends React.Component { constructor(props) { super(props); this.state = { 'play': false }; this.name = props.src; this.togglePlay = this.togglePlay.bind(this); } togglePlay() { this.setState({'play': !this.state.play}, () => { this.state.play ? globalAudio.play(this.name) : globalAudio.pause(this.name); }); } componentWillUnmount () { globalAudio.pause(this.name); } render() { return ( <div style={this.props.style} className={this.props.className}> {this.state.play ? <button className="audio-button" aria-label="Pause" onClick={this.togglePlay}><img src={pauseIcon} width="34" height="34" alt="Pause"></img></button> : <button className="audio-button" aria-label="Play" onClick={this.togglePlay}><img src={playIcon} width="34" height="34" alt="Play"></img></button>} </div> ); } } export default Music;

globalAudio

感谢所有的建议,他们都非常有帮助。