在React中管理多个音频源 [英] Manage Multiple Audio Sources in React

查看:62
本文介绍了在React中管理多个音频源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个React组件,当您单击按钮时,该组件会播放/暂停音频.效果很好,我一次在页面上渲染了其中的5个.但是,如果您单击一个播放,然后单击另一个播放,则两个音频都在播放,这不是很好.这是该组件的代码:

I have a React component that plays/pauses audio when you click on a button. It works great and I render about 5 of these on a page at once. However, if you click play on one, and then click play on another, both audio's are playing, which isn't great. Here's my code for the component:

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或其他状态管理库.我想避免这种情况,因为在此网站上我不需要这样做.我研究了事件侦听器(即此解决方案更接近,但我不能缩小jQuery中的实现与我正在React中使用的实现之间的差距.

I've done some looking around and a potential solution is to use redux or some other state management library. I'd like to avoid this as I otherwise have no need for that in this site. I've looked into event listeners (namely the solution proposed here) but when I do a document.getElementsByTagName('audio') I get back an empty HTMLCollection. This solution is closer, but I can't bridge the gap between it's implementation in jQuery to the one I'm using in React.

有没有办法在播放新音频之前识别正在播放的音频并从React组件中暂停它?任何和所有建议表示赞赏.

Is there a way to identify the playing audio and pause it from a React Component before playing new audio? Any and all suggestions are appreciated.

推荐答案

从马学正和TheIncorrigible1获得了一些重要提示.基本上将音频移动到它自己的模块中.从中导出 play pause 方法,并在该模块中跟踪 currentlyPlaying .

Got some big hints from Xuezheng Ma and TheIncorrigible1. Basically moved audio into it's own module. play and pause methods are exported from that, and currentlyPlaying is tracked in that module.

我调整了 Music 组件,使其看起来像这样

I adjusted my Music component to look like this

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 :

import audio1 from './audio1.mp3';
import audio2 from './audio2.mp3';
import audio3 from './audio3.mp3';
import audio4 from './audio4.mp3';
import audio5 from './audio5.mp3';

const audios = {
    'audio1': new Audio(audio1),
    'audio2': new Audio(audio2),
    'audio3': new Audio(audio3),
    'audio4': new Audio(audio4),
    'audio5': new Audio(audio5)
};

let currentlyPlaying = null;

const play = (name) => {
    if (currentlyPlaying) {
        audios[currentlyPlaying].pause();
    }
    audios[name].play();
    currentlyPlaying = name;
};

const pause = (name) => {
    currentlyPlaying = null;
    audios[name].pause();
};

export default {
    pause,
    play
};

感谢所有建议,它们都很有帮助.

Thanks for all of the suggestions, they were all very helpful.

这篇关于在React中管理多个音频源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆