许多拥有大量书面内容的网站都使用专门设计的打印样式表。这样,用户就可以打印出相关内容,而无需在导航、广告或任何其他无关内容上浪费纸张。
Articulate.js,一个 jQuery 插件,我认为是叙事的等价物。只需一行代码,它就能让开发者创建链接,允许用户点击、坐下来,并聆听浏览器朗读网页的重要内容。在某些方面,它可以将一篇有思想的论文或文章变成一个迷你播客。并且因为它使用了内置的 JavaScript 功能,所以不需要浏览器扩展或其他系统软件。
我想分享一下我如何创建 Articulate.js,希望它能为读者提供关于如何以不同方式应用这项技术的思路。
语音合成接口
Articulate.js 使用 Web Speech API 的语音合成接口。它目前在所有主流浏览器中都受支持,包括最新版本的 Edge、Safari、Chrome、Opera、Firefox、iOS Safari 和 Android 版 Chrome。
语音合成接口有两个 window
对象用于启用浏览器语音功能:SpeechSynthesis
和 SpeechSynthesisUtterance
。第一步是创建一个 SpeechSynthesisUtterance
对象的实例,并指定您希望朗读的文本。如果需要,您可以设置其他属性,例如速率、音调、音量和语音。
要开始朗读,此对象将作为参数传递给 SpeechSynthesis.speak()
方法。其他播放功能,例如暂停、恢复和取消,都是 SpeechSynthesis
对象的方法。微软提供了一个 有用的演示,您可以使用它来体验这些功能。
在本文的末尾,列出了许多资源,它们将引导您了解此功能的复杂性并提供其他示例。
入门
轻量级的 Articulate.js 插件允许您利用 jQuery 的强大选择器选项来指定要朗读的网站部分。例如,根据页面的组织方式,一行代码(如下所示)可以指示浏览器朗读整篇文章或博客文章的内容
$('article').articulate('speak');
这是一个仅针对主要标题和段落的示例
$('h1, h2, p').articulate('speak');
在内部,Articulate.js 克隆匹配的元素集及其所有后代元素和文本节点。然后,它使用一组默认规则解析此克隆,确定哪些内容应该朗读和忽略,然后添加适当的停顿,使所有内容听起来更像叙事。
这些是基本方法以及 CodePen 示例
函数 | 描述 |
---|---|
$(selector).articulate('speak'); |
朗读指定的 DOM 元素及其后代 |
$().articulate('pause'); |
暂停朗读 |
$().articulate('resume'); |
在暂停后恢复朗读 |
$().articulate('stop'); |
永久停止朗读 |
查看 CodePen 中 Adam Coti 的作品 Articulate: 基本函数 (@adamcoti) 在 CodePen 上。
您一次只能激活一个 SpeechSynthesisUtterance
实例,这就是为什么暂停、恢复或停止不需要 jQuery 选择器的原因。如前所述,这些方法作用于 SpeechSynthesis
对象。
此外,浏览器只有在没有更多文本要读取或执行“停止”调用时才会停止朗读。如果朗读已暂停,则必须在朗读其他内容之前恢复或停止。
可以调整速率、音调和音量。通过使用输入滑块,调整可以为用户提供一些额外的控制。虽然系统默认速率为 1,但在经过大量测试后,我将其略微提高到 1.1,因为这似乎提供了更自然的朗读速度。当然,这是主观的,可以被覆盖。
函数 | 描述 |
---|---|
$().articulate('rate',num); |
设置朗读语音的速率 默认值 = 1.1 范围 = [0.1 – 10] |
$().articulate('pitch',num); |
设置朗读语音的音调 默认值 = 1.0 范围 = [0 – 2] |
$().articulate('volume',num); |
设置朗读语音的音量 默认值 = 1.0 范围 = [0 – 1] |
查看 CodePen 中 Adam Coti 的作品 Articulate : 语音参数 (@adamcoti) 在 CodePen 上。
开发人员可以使用更多选项,但让我们简单地讨论一下当 Articulate.js 被要求朗读页面上的内容时,幕后发生了什么。
Articulate.js 算法
Articulate.js 利用的语音合成接口将以最字面化的方式朗读提供的任何文本字符串。它会发一些符号的音(例如,遇到“%”时会说“percent”);其他符号则会忽略(例如,引号符号不会被朗读)。它的节奏主要由逗号决定,逗号会产生短暂的停顿,句号的停顿稍长一些。
考虑到这一点,需要进行大量的操作才能准备一个网页进行朗读。不幸的是,人们不能简单地连接 DOM 中所有选定的文本节点,因为这会导致大量断句的文本(例如列表),包含不适合以连贯方式朗读的内容(例如表格),并忽略应该描述的项目(例如图像)。
Articulate.js 通过对 jQuery 选择器中指定的 DOM 元素应用以下规则(其中包括)来处理此问题
- 删除可能包含文本节点但不应朗读的 HTML 标签,例如
<form>
和<s>
。默认情况下,指定了 21 个标签应被忽略。 - 查找
<h1>
到<h6>
、<li>
和<br>
标签的实例,并在每个实例后面追加句号或逗号。这样做是为了确保在朗读时会发生停顿,因为这些元素通常在视觉上表示为不带标点的。 - 插入从图像的
alt
属性、表格的<caption>
标签和图形的<figcaption>
标签收集的描述性文本。
完成后,剩下的内容将转换为一个长文本字符串,该字符串现在需要进一步操作,包括
- 查找
<q>
标签和成对的弯引号,并在开头插入“quote”,在结尾插入“unquote”,以便在朗读时区分它们。 - 添加开始和结束文本以指定列表和块引用。
- 查找 em 破折号,并将其替换为逗号以产生短暂的停顿。
- 删除其余的 HTML 标签和注释。
- 删除其余的换行符和回车符,以及残留的 HTML 特殊字符。
此时,文本字符串已准备好发送到语音合成接口,由浏览器朗读。如果您查看此字符串,您会看到多个句号、逗号和空格的实例——没关系——因为这不会影响它的发音。也就是说,一个或多个逗号或句号组合在一起不会产生更长的停顿。
自定义
通过使用 JavaScript 和 HTML 数据属性,可以自定义 Articulate.js 以优化用户体验。如下面的 CodePen 演示所示,您可以
- 指定要朗读的 HTML 标签,否则这些标签会被忽略,反之亦然。
- 在文本中执行搜索和替换,这对于缩写很有帮助。例如,您可以指定所有“i.e.”的实例都应读作“that is”。
- 指定要忽略的文本块。例如,一句“点击此处了解更多信息”的句子不需要朗读。
- 指定要拼读的单词。
- 在专门制作的注释标签中指定要朗读的副本,这些副本在屏幕上是隐藏的。
查看 CodePen 中 Adam Coti 的作品 Articulate: 文本操作 (@adamcoti) 在 CodePen 上。
查看 CodePen 中 Adam Coti 的作品 Articulate: HTML 数据属性 (@adamcoti) 在 CodePen 上。
浏览器一致性
您会注意到,语音合成接口在不同的浏览器和操作系统之间略有不同。例如,在 iPhone 上,默认的语音速度听起来会比桌面实现快一些。开发人员可以为用户提供输入滑块或单选按钮以微调他们的体验。
此外,根据操作系统和设备的不同,浏览器会向语音合成接口公开不同的语音。如前面提到的微软演示中所示,可以选择这些语音以覆盖默认的“本机”语音。但是,为了简单起见,Articulate.js 仅使用默认语音——更高版本也将允许修改此参数。
一些最后的思考
Articulate.js 的灵感来源于这样一个想法:只需轻轻一点,我就能在不方便或不想盯着屏幕的时候享受文章朗读——尤其是在使用手机时。也许是在公园里闭着眼睛躺着,或者是在忙着准备晚餐的时候。目标是允许开发者进行适当的定制,使其听起来不像是屏幕阅读器,而更像是朋友在为你朗读网页。
Articulate.js 可用于网页上的任何内容的语音选项,从发音单个单词到传达屏幕上未显示的内容。如果您有兴趣,请下载源代码并进行实验。最重要的是,玩得开心!
下载和文档
带注释的源代码和 Articulate.js 的压缩版本可以在其 Github 主页下载。完整的文档也可以在那里找到。
这太棒了;我一直想要这样的东西!
我很好奇如何忽略
<code>
,不过;它会让这篇文章很难理解,不是吗?很高兴你喜欢!
对于
<code>
,这完全取决于上下文。请记住,您可以通过在<code>
标签中放置data-articulate-recognize
来根据具体情况覆盖默认值。我们一直在研究这个 API,以便在我们的博客上使用它。我们发现,尽管语音“还可以”,但由于浏览器/操作系统制造商无法解决的数字声音,持续收听起来有点困难。
我想知道是否还有其他人有这种体验?
我注意到数字声音因浏览器和/或操作系统而异。例如,在配备最新操作系统的 Mac 桌面电脑上,我可以在句子前听到数字语音“吸气”。这确实让它听起来更像人类。
播客可以在我的手机上做一些事情
1) 向前或向后跳转 10 或 15 秒
2) 取下耳机时暂停
3) 点击手机关闭后继续播放
当我播放视频(例如 YouTube)时,当我点击手机关闭时声音会停止。当我听音乐(不是“播客”)时,我无法“跳跃”。这些细微的差别累积起来,使得轻松收听网页变得比应有的更困难。我不确定是否可以通过 JS 解决这些问题,所以我想这可能是移动浏览器的问题?
哇,这是一个非常棒的想法!
我可以想到很多在许多网站上使用它的理由。并且在每个页面上将其作为一种不显眼的选项,可能会成为提高用户参与度甚至转化率的一种机制。
您好,
出色的工作,我肯定可以使用它,非常感谢您分享。
一些问题
1. Speech API 可以自动检测语言吗?
2. 对于给定的语言,我能否从不同的语音中选择?
3. 例如,当出现外国地名(或其他任何地名)时会发生什么?例如,“路德维希·维特根斯坦”将如何用英语发音?
再次感谢您的出色工作!
-弗朗哥
感谢您的友好话语。尽我所能回答您的问题
它不会检测语言,但根据我的测试,默认语音将与操作系统的默认语言匹配。当我将 MacBook 上的语言更改为德语时,SpeechSynthesizer 的默认语音更改为说德语的语音。
这将取决于浏览器和操作系统。我建议查看文章末尾列出的一些资源以获取更多信息。不幸的是,浏览器之间几乎没有一致性,尤其是在 Windows 上。
据我所知,它可能会使用该语言的默认英语语法“规则”来发音。例如,德语单词“die”将用英语语音发音为“dye”;用德语语音发音将是正确的“dee”。
谢谢,我会做一些测试并告知您。
-弗朗哥
看来你是对的,但这太糟糕了。我想尝试第一个演示,我的系统开始用浓重的意大利口音朗读文本。
几个句子之后,你再也无法忍受了。:D
我希望有一种方法可以指定语言,以便如果操作系统的语言与页面语言不匹配,用户可以获得更好的体验。
修改它以在系统朗读每个单词时在屏幕上突出显示它有多难?
考虑将其用于学习困难的读者的在线学习。