原文地址:www.joshwcomeau.com/react/annou…
作者:Josh Comeau、 译者:林鸿鹄
未经授权禁止转载。
读前须知
本篇译文涉及到的部分 音频demo 需要前往到 原文 进行尝试。
强力推荐去试试看哦~ (需翻墙)
介绍
可能因为我是一个音频工程师,本人很期待能在浏览器里听到更多的音效。
我知道这时候会有一大堆的人反驳我,很大部分原因是曾经音频在浏览器里被乱用,从而导致一部分人觉得在浏览器听到声音是一件很讨厌的事情。
早期遇到音频往往是在以下情况:
- 老的浏览器里使用 MIDI 文件作为背景音乐 🎺
- 黑客病毒类曾用音效来达到一些邪恶的目的,来获取用户的注意力,让诈骗更可信 😈
- 还有自动播放视频等等 😬
但是我认为这个想法还是可以拯救一下的。我相信音效可以强调用户的行为,增强给用户的反馈、给枯燥的用户行为增添一些快乐。当声音被高雅地使用后,产品会更加地真实、更加地栩栩如生。
给项目添加音效并不是一个新主意:例如网页游戏,或手机app上一直有在使用音效来提升用户交互的体验。实际上,web 才是个奇葩,我能想到的所有数字媒体都有用到音效吧?你们说是不是?
当我搭建这个博客的时候,我就想要开始这个试验。在我这个博客里,当你和很多 UI 组件互动的时候都会发出声音哦~
去试试看吧!
你可以尝试点击博客的右上角 (需翻墙)
或尝试一下原文的在线代码编辑区,真的非常有意思!
因为音效在浏览器上真的是太少太少了,所以体验的时候你会感觉特别的吸引人的"耳球"。所以只要把声音用在正确的项目里,这会是一个绝对的秘密武器,给 everybody 带来大大滴惊喜!
为了让你们比较方便的开始,我把这个博客的 hook,use-sound
, 发布到 NPM 上了。本篇博客会尽快得让你们知道它可以做什么,我还会分享一些如何在 web 中正确使用音效的技巧。
直接看文档?
如果你想直接用这个 hook,你可以 直接跳到这个 GITHUB 链接 哦~
概述
use-sound
是一个 react hook 让你可以播放音效。这里是一个比较简单的例子:
import useSound from 'use-sound';
import boopSfx from '../../sounds/boop.mp3'; // 导入你自己的音频
const BoopButton = () => {
const [play] = useSound(boopSfx);
return <button onClick={play}>Boop!</button>;
};
useSound
会异步加载10kb的第三方依赖包 Howler,但对你的包只加大约1kb。
它提供了一大堆很赞的东西,包括:
- 提早停止声音,或者暂停/重播声音。
- 加载一个雪碧音频,然后分裂成很多独立的声音。
- 让声音加速或减速。
- 拥有一大堆事件!
- 还有好多好多 Howler 所实现的高级东西。
假如你想看更多复杂的使用方式或 API详情,你可以 点击此处查看文档。
让我们开始吧!
安装
第一步我们要做的是通过 NPM 或者 Yarn 来进行安装包:
# 用 YARN
yarn add use-sound
# 或,用 NPM
npm install use-sound
导入
这个包只导出一个默认的 hook,useSound
:
import useSound from 'use-sound';
在使用这个 hook 之前,你还需要导入你的音频文件。
如果你是使用 create-react-app
/Gatsby 这样的脚手架,你应该可以像导入图片或其他media一样的方式来导入 MP3 文件:
import boopSfx from '../../sounds/boop.mp3';
如果你在捣鼓自己的 Webpack 配置,你可以用到 file-loader 使 .mp3
格式的文件成为随意的文件类型。
前端好声音!
知道如何安装依赖和写代码只是成功的一半;我们还需要准备好优美动听的音乐才行!
我最喜欢的资源是 freesound.org。几乎博客的所有音频都来自于这个网站。你需要先注册一个账号来下载他们的资源,所有东西都是免费的喔。
请做好寻找音乐的准备。网站里很多里面的声音都录的不是很清晰,
可能就是大海捞针的感觉 嘻嘻 毕竟是免费的
准备音频
很多来自 freesound.org 的音频我们都需要先处理一下:
- 比如说一些和弦,音频播放时是断断续续的。你需要把他们裁剪一下,达到触发声音后就立马能听到的效果。
- 假如一些音频音量一会儿高一会儿低的,你还得调整音频的音量调成一致哦。
- 下载下来的音频格式可能不同,你还需要转成 MP3 的格式~
完成以上几点,你播放的音频才会完美哟~
你可以使用一个免费,开源,跨平台的音频编辑器来编辑你下载的音频
我推荐你们使用 Audacity(该地址需要翻墙下载)
译者在百度找到了这个下载地址:audacity.onl/
当然学习怎么使用 Audacity 不是这个博客的重点,但是外面还是有很多免费的资源来学习如何使用它。
为什么一定要使用 MP3?
在好久以前,还没有一个哪里都支持的音频格式;大家常用 MP3,AIFF,或是 WAV,在不同的环境下加载不同的文件。
开心的是, MP3 当今被所有主流的 浏览器支持,包括 Internet Explorer 9。和其他格式相比,MP3 可以很好的被压缩成更小的文件大小。
所以我强推 MP3!
音频 🔊 & 辅助功能 ♿️ & 可用性
即使音频被网页所支持,我注意到有一部分用户不会在乎它的存在,他们可能更喜欢静静地呆着。
对于那些视力损伤的人群一般都会使用屏幕朗读软件来访问网页。如果我们给网页放置过多的音效,可能会导致这类用户在聆听朗读的内容时,被这些音效所打扰到。
以上原因所致,在你的页面上放置一个静音按钮 🔕 是非常重要的。而且把静音"状态保持"住也是至关重要的,这样用户就不再需要反复地设置是否需要静音啦!
相反的,对于听力有障碍的用户而言,他们察觉不到声音是否被触发了。因此,我们绝不能仅通过音频来传递重要的信息。如果你在使用音效来作为反馈用户的途径,请也确保拥有视觉上的反馈。这样、网页才能100%在没声音的情况下保持可用性。
状态保持 Sticky 是作者的另外一篇文章,
假如同学们感兴趣可以在评论区点赞留言,小编抽空再翻译一下~
小试牛刀
请不要忘记打开本地设备的声音哦~
1. Checkbox
当我点击这个 checkbox 的时候,我已经颅内升天了(゜-゜)つ!!如果有鼠标的或触控板的话,请尝试一次飞快的点击,然后再尝试一次缓慢的点击,听听他们的音效。
代码:
function Demo() {
const [isChecked, setIsChecked] = React.useState(
false
);
const [playActive] = useSound(
'/sounds/pop-down.mp3',
{ volume: 0.25 }
);
const [playOn] = useSound(
'/sounds/pop-up-on.mp3',
{ volume: 0.25 }
);
const [playOff] = useSound(
'/sounds/pop-up-off.mp3',
{ volume: 0.25 }
);
return (
<Checkbox
name="demo-checkbox"
checked={isChecked}
size={24}
label="I agree to self-isolate"
onChange={() => setIsChecked(!isChecked)}
onMouseDown={playActive}
onMouseUp={() => {
isChecked ? playOff() : playOn();
}}
/>
);
}
2. 互动音频
有时候你只希望声音在互动的时候被播放。 注意到下面这个 demo 声音只在 hover 的时候被播放:
代码:
function Demo() {
const soundUrl = '/sounds/rising-pops.mp3';
// 你可以通过更换资源 'rising-pops' 成下面的音频资源听听看哟~
// - fanfare
// - dun-dun-dun
// - guitar-loop
const [play, { stop }] = useSound(
soundUrl,
{ volume: 0.5 }
);
const [isHovering, setIsHovering] = React.useState(
false
);
return (
<Button
onMouseEnter={() => {
setIsHovering(true);
play();
}}
onMouseLeave={() => {
setIsHovering(false);
stop();
}}
>
<ButtonContents isHovering={isHovering}>
Hover over me!
</ButtonContents>
</Button>
);
}
3. 逐步升高的音阶
我在点赞的按钮上加了一个很有意思的技巧:每次点击的音频音阶,都会比上一次的点击的要更高一点。我是这么实现的:
代码:
function Demo() {
const soundUrl = '/sounds/glug-a.mp3';
const [playbackRate, setPlaybackRate] = React.useState(0.75);
const [play] = useSound(soundUrl, {
playbackRate,
volume: 0.5,
});
const handleClick = () => {
setPlaybackRate(playbackRate + 0.1);
play();
};
return (
<Button onClick={handleClick}>
<span role="img" aria-label="Heart">
💖
</span>
</Button>
);
}
4. 播放/暂停 按钮
你可以用这个播放按钮搞一个新的网易音音乐了哈哈哈。
代码:
function Demo() {
const soundUrl = '/sounds/guitar-loop.mp3';
const [play, { stop, isPlaying }] = useSound(soundUrl);
return (
<PlayButton
active={isPlaying}
size={60}
iconColor="var(--color-background)"
idleBackgroundColor="var(--color-text)"
activeBackgroundColor="var(--color-primary)"
play={play}
stop={stop}
/>
);
}
5. 雪碧音频
如果你的组件打算用很多音效,我建议你使用雪碧音频哦~ 雪碧音频是一个音频文件集合了很多不同的音效。把音频都结合成一个单独文件后,我们可以写出更优美的代码,此外防止很多并行的 HTTP 请求。
这里我们用了一个雪碧音频搭建了一个打碟机!尝试点击这些按钮,或者点击你键盘上的1234听听看吧!
代码:
function Demo() {
const soundUrl = '/sounds/909-drums.mp3';
const [play] = useSound(soundUrl, {
sprite: {
kick: [0, 350],
hihat: [374, 160],
snare: [666, 290],
cowbell: [968, 200],
}
});
// Custom hook that listens for 'keydown',
// and calls the appropriate handler function.
useKeyboardBindings({
1: () => play({ id: 'kick' }),
2: () => play({ id: 'hihat' }),
3: () => play({ id: 'snare' }),
4: () => play({ id: 'cowbell' }),
})
return (
<>
<Button
aria-label="kick"
onMouseDown={() => play({ id: 'kick' })}
>
1
</Button>
<Button
aria-label="hihat"
onMouseDown={() => play({ id: 'hihat' })}
>
2
</Button>
<Button
aria-label="snare"
onMouseDown={() => play({ id: 'snare' })}
>
3
</Button>
<Button
aria-label="cowbell"
onMouseDown={() => play({ id: 'cowbell' })}
>
4
</Button>
</>
);
}
更多关于雪碧音频的详情 查看 API 文档
百万种可行性
在网页中探索声音的过程深深触动着我,因为实在是有太多尚未开发的领域了!!我在网页上尝试音频有一段时间了,但我感觉我仅仅只是触碰到了表面而已。
现在你有了开始试验的工具,我希望能鼓励到你去尝试一下,看看你能走多远 😁
你可以通过 GitHub 了解更多关于 use-sound
这个 hook 噢~ 快去行动起来吧~