bil*_*oah 12 javascript audio firefox google-chrome
我有一个带有输入字段的页面,用于扫描产品。当扫描条形码或在字段中键入SKU时,会发出ajax请求,并且应用程序会根据响应使用播放成功或错误声音HTMLMediaElement.play()。
sounds.error.play();
Run Code Online (Sandbox Code Playgroud)
前一阵子工作正常,但现在我收到了这个错误:
only仅当获得用户批准,网站被用户激活或媒体被静音时,才允许自动播放。
其次是:
NotAllowedError:在当前上下文中,用户代理或平台不允许使用play方法,这可能是因为用户拒绝了权限。
由于此页面仅出于扫描SKU的目的而存在,因此,在页面加载时,该输入字段将以编程方式集中显示,从而使最终用户的操作更加轻松。我尝试删除此焦点,以便用户必须单击输入字段,但这似乎无法满足允许播放音频的任何要求
经过更多的实验后,我发现在进行一些额外的用户交互后,声音会播放。例如,如果我创建一个复选框以“启用”声音,然后用户单击它,这似乎就足够了。或者,如果用户在输入元素之外单击,然后再次回到输入元素,那也可以。
满足大多数现代浏览器以允许播放音频的要求是什么?
我知道答案对于不同的浏览器和配置可能会有所不同,但是我找不到对Firefox或Chrome当前版本具有权威性的任何信息。我正在寻找一种解决方法,以使应用程序无需通过额外的单击或其他类型的交互而变得复杂,并且由于我现在已经知道了这一新政策,因此我希望这些修订尽可能不引人注目。
更新:
这是我努力演示该问题的基本示例。刚才我尝试了三种不同的浏览器,它们的行为都有所不同。Firefox的行为如上所述特别重要-在我专注于输入字段,模糊然后单击再次聚焦之前,它不会播放声音:
小智 25
在 safari 中,要允许video标签中自动播放,您需要添加它们playsinline属性。像这样:
<video autoplay="" muted="" playsinline=""></video>
Run Code Online (Sandbox Code Playgroud)
小智 15
我也遇到了同样的问题,突然间我很容易解决了这个问题:
只需在播放按钮上更改事件监听器即可
onClick={togglePlay}到
onClickCapture={togglePlay}
React 中使用钩子的示例:
const Player = ({ audio }) => {
const [playing, setPlaying] = useState(false);
const togglePlaying = () => setPlaying((prev) => !prev);
useEffect(() => {
if (audioRef && audioRef.current) {
if (playing) {
audioRef.current.play();
} else {
audioRef.current.pause();
}
}
}, [playing]);
return (
<audio
autoPlay=""
src={audio}
ref={audioRef}
onTimeUpdate={(e) => setCurrentTime(e.target.currentTime)}
onCanPlay={(e) => setDur(e.target.duration)}
onEnded={songEnded}
/>
<PlayerStart onClickCapture={togglePlaying}>
{playing ? <PauseIcon /> : <PlayIcon />}
</PlayerStart>
)
}
Run Code Online (Sandbox Code Playgroud)
Nic*_*lay 10
[编辑] Firefox 70修复了这个问题。此答案的其余部分提供了解释和建议的解决方法。
当你想知道什么特别的“用户与网站进行互动的”标准方式:
根据Firefox 源代码中的评论,
[“激活”由] 事件触发,这些事件可能是用户与文档的交互,而不是与浏览器交互的副产品(即滚动查看端口的按键、键盘快捷键等)。
具体来说,在当前的 Firefox 开发版本中,以下事件不会使页面“用户手势激活”(代码):
contenteditable)的事件,例如键入/点击文本输入;一个想法 - 从一个假的/模糊的文本框开始,在输入第一个字符后显示/聚焦真正的文本框(通过 JS 将第一个字符添加到文本输入中) - 以下代码似乎在 Firefox 中工作:
$(document).one('keypress', function(ev) {
// copy the first character typed over to the text input
let char = String.fromCharCode(ev.which);
$('.play').val(char).focus();
});
$('.play').on('keypress', function() {
if($(this).val().length === 3) { // assuming you want to validate when a certain number of characters is typed
sounds[$(this).data('sound')].play();
}
})
Run Code Online (Sandbox Code Playgroud)
如果用户通过单击文本输入开始,这将无济于事,但可以在这种情况下实施后备非听觉反馈。
当归因于自动播放多媒体时,在所有现代浏览器(尤其是chrome)中都有一些权限阻止。
这是MDN的“自动播放可用性”部分,其中显示了何时允许媒体自动执行:
- 音频被静音或其音量设置为0;
- 用户已经与站点进行了交互(通过单击,点击,按下键等)。
- 如果站点已被列入白名单;如果浏览器确定用户经常与媒体互动,这可能会自动发生,也可能通过首选项或其他用户界面功能手动发生
- 如果自动播放功能策略用于向
<iframe>和及其文档授予自动播放支持。
这是针对使用AJAX的arrayBuffer的解决方案
这是一个演示
| 归档时间: |
|
| 查看次数: |
1101 次 |
| 最近记录: |