使用AudioContext进行safari音频回放仅在系统设置中的设备更改后才能运行

时间:2019-07-09 12:21:44

标签: javascript reactjs safari html5-audio

我正在尝试创建一个React TestSound组件,以指定的增益播放声音。 但是,我无法在MacOS的Safari(版本12.1.1)中使用它。 我没有收到错误消息。

在Chrome和Firefox中,代码按预期工作。

在Safari中,只有在初始化后更改系统设置中的扬声器时,声音才会播放。 例如,如果在设置中将Mac扬声器设置为默认设备而初始化该页面,则我首先必须将默认设备更改为耳机。然后声音将通过耳机播放。

这是组件;我试图剥离所有不必要的代码:

import React, { Component, Fragment } from 'react';

export default class TestSound extends Component {

    //initalize
    constructor(props) {
        super(props);

        this.state = {
            gain: 1,
        }

        //init audio context
        this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
        this.gainNode = this.audioContext.createGain();
        this.destination = this.audioContext.createMediaStreamDestination();
        this.gainNode.connect(this.destination);
        this.audio = null;

        //fetch sound buffer
        const request = new XMLHttpRequest();
        request.open('GET', '/audio/sound.mp3', true);
        request.responseType = 'arraybuffer';

        request.onload = () => {
            this.audioContext.decodeAudioData(request.response, buffer => {
                this.buffer = buffer;
                this.audio.srcObject = this.destination.stream;
            });
        }
        request.send();
    }

    //play the sound
    onAudioClick = e => {
        this.source = this.audioContext.createBufferSource();
        this.source.buffer = this.buffer;
        this.source.connect(this.gainNode);
        this.gainNode.gain.value = this.state.gain;
        this.source.start(0);
    }

    //set the ref and destination stream for the audio element
    audioMounted = ref => {
        if (!this.audio) {
            this.audio = ref;
            this.audio.srcObject = this.destination.stream;
        }
    }


    //render slider, play button and audio tag
    render() {
        return (
            <Fragment>
                <input type="range" max="1" min="0" step="0.05" onChange={(e) => {this.setState({gain: e.target.value})}}/>
                <button type="button" onClick={this.onAudioClick} >
                    <audio ref={ref => this.audioMounted(ref)} autoPlay/>
                    Play!
                </button>
            </Fragment>
        );
    }
}

这是版本问题还是代码错误?还有其他人遇到过这个问题吗?

0 个答案:

没有答案