0

我正在创建一个使用 React 和 Socket.io 的简单 Web 应用程序。原理是连接了两个设备,它们只发送“转到此视图”类型的消息,然后反应渲染就好了。

我遇到的问题是在视图更改时使用 javascript 播放音频剪辑。当我单击 iPad 上更改视图的按钮时,音频开始播放得很好,但是当视图更改由另一台设备通过 websocket 连接启动时,音频将无法播放。

所有这些在桌面 Chrome 和 Safari 上都可以正常工作。这不适用于运行 iOS 9.3.5 的 iPad 或运行 iOS 11.0.1 的 iPhone(已测试 safari 和 chrome)

这是播放音频文件的代码:

// 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;

这是呈现一个按钮的代码,该按钮也调用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;

套接字连接仅setState()在具有正确view.

编辑:忘了补充一点,我也尝试MutationObserver在所有打开的主要元素上使用,但仍然一无所获。

附言。我知道这里有十亿件事情做得不好,请耐心等待。

4

1 回答 1

0

我发现这篇文章描述了 iOS 上 HTML5 音频的限制。与此问题相关的是,在 iOS 上,音频的播放必须始终由用户操作来启动,唯一的解决方案是将应用程序设计为让用户始终启动播放。

我将研究一些可能的解决方法,并将尽快编辑我的答案以包括我的发现,即使至少根据文章没有解决方法。不过是从 2012 年开始的,所以可能会有一些变化。

于 2017-10-31T08:16:22.990 回答