简体   繁体   English

Javascript音频无法在iOS上与React和Socket.io一起正常使用

[英]Javascript audio not working properly with React and Socket.io on iOS

I'm working on creating a simple web app that uses React and Socket.io. 我正在创建一个使用React和Socket.io的简单Web应用程序。 The principle is that there are two devices connected, which send each other nothing but 'go to this view' -type messages, which then react renders just fine. 原理是有两个连接的设备,除了“转到此视图”类型的消息外,彼此之间不发送其他任何消息,然后对这些消息做出反应就可以了。

The issue I have is with playing audio clips with javascript when the views change. 我的问题是在视图更改时使用javascript播放音频剪辑。 When I click on the button on the iPad that changes the view, the audio starts to play just fine, but when the view change is initiated by another device over websocket connection, the audio won't play. 当我单击更改视图的iPad上的按钮时,音频开始正常播放,但是当通过Websocket连接的另一设备启动视图更改时,音频将无法播放。

All this works just fine on desktop both Chrome and Safari. 所有这些在Chrome和Safari桌面上都可以正常工作。 This doesn't work on iPad running iOS 9.3.5 nor iPhone running iOs 11.0.1 (tested both safari and chrome) 这不适用于运行iOS 9.3.5的iPad或运行iOs 11.0.1的iPhone(已测试野生动物园和Chrome)

Here's the code for playing audio file: 这是播放音频文件的代码:

// Importing audio files
import responsePromptSound from 'A/responsePrompt.aac';
import endsound from 'A/endsound.aac';

function playSound(view) {
  // Stop playing a repeating sound if there is one
  if (window.soundPlaying) {
    clearInterval(window.soundPlaying);
  }

  // The audio clips to be used in each view
  const views = {
    start: null,
    waitingForResponse: null,
    responsePrompt: responsePromptSound,
    end: endsound,
  };

  // Current audio clip
  const soundClip = views[view];

  if (!soundClip) {
    return;
  }

  const audio = new Audio(soundClip);

  function playMe() {
    audio.play();
  }

  // Repeating notification sound
  if (view === 'responsePrompt') {
    window.soundPlaying = setInterval(() => {
      playMe();
    }, 7 * 1000);
  }

  // Play always at least once
  playMe();
}

export default playSound;

Here's the code that renders a button that also calls the playSound : 这是渲染按钮的代码,该按钮也调用playSound

import React from 'react';
import PropTypes from 'prop-types';

import playSound from 'C/Audio.js';

function Button(props) {
  // text content for each view
  const views = {
    start: ['start1', 'start2'],
    waitingForResponse: null,
    responsePrompt: ['prompt1', 'prompt2'],
    end: ['end1', 'end2'],
  };

  // Current button text
  const btnText = views[props.view];

  let btn;

  // Different views for button
  if (!btnText) {
    btn = null;
  } else if (props.view === 'end') {
    btn = (
      <div className="end-box">
        <div className="end-box-inner">

          <div className="button-txt-one">{btnText[0]}</div>
          <div className="line" />
          <div className="button-txt-two">{btnText[1]}</div>

        </div>
      </div>
    );
  } else {
    btn = (
      <button onClick={props.changeView}>
        <div className="button-inner">
          <span>

            <div className="button-txt-one">{btnText[0]}</div>
            <div className="line" />
            <div className="button-txt-two">{btnText[1]}</div>

          </span>
        </div>
      </button>
    );
  }

  playSound(props.view);

  return (
    btn
  );
}

Button.propTypes = {
  view: PropTypes.string.isRequired,
  changeView: PropTypes.func.isRequired,
};

export default Button;

The socket connection only triggers setState() on the parent element with the correct view . 套接字连接仅使用正确的view触发父元素上的setState()

EDIT: Forgot to add that I also tried using MutationObserver on the main element with everything turned on but still got nothing. 编辑:忘了补充说,我也尝试在主元素上使用MutationObserver并打开所有内容,但仍然一无所获。

Ps. 附言 I know there's like a billion things not done all that well here, bear with me. 我知道大约有十亿件事在这里做得不好,请忍受我。

I found this article which describes the limitations of HTML5 audio on iOS. 我发现这篇文章描述了iOS上HTML5音频的局限性。 Related to this issue, on iOS the playing of the audio must always be initiated by user action, and the only solution is to design the app in such a way that the user always initiates the playback. 与此问题相关,在iOS上,必须始终通过用户操作来启动音频的播放,唯一的解决方案是以用户始终启动播放的方式设计应用。

I'm gonna look into some possible workarounds and will edit my answer asap to include my findings, even though at least according to the article there's no workaround. 我将研究一些可能的解决方法,并尽快编辑我的答案以包括我的发现,即使至少根据本文而言,没有解决方法。 It's from 2012 though, so there might be some changes. 虽然是2012年,所以可能会有一些变化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM