我开始播客时学到的 A11y 经验教训
最初发布于a11ywithlindsey.com。
如果你没注意到,我好像很久没来了!我已经一个月没发帖了,这其中有原因的。我和 Kelly Vaughn、Ali Spittel、Emma Wedekind 一起创办了LadyBug 播客。这个播客的制作费了不少功夫。因此,我一直在琢磨如何平衡这个博客和那个副业!不过别担心,这不会消失。我的博客是我的热情之作!
现在你知道了我的近况,我学到了很多关于播客以及它与无障碍互联互通的知识。我对其中一些内容了解得比较多,但在这篇文章中,我们将进行更深入的探讨。
成绩单是必须的
当我们开始策划这期播客时,我们当然希望有文字记录。文字记录既费时又费钱,很多人觉得它只是“锦上添花”。然而,我要告诉你们,文字记录是必不可少的。
成绩单有很多好处:
- 聋人和听力障碍人士也可以访问您的精彩内容。
- 有些人更喜欢阅读而不是聆听。我数不清有多少健全人士告诉我,他们很感激有文字记录。
- 它可以帮助那些母语不是英语的人。
- 如果人们阅读了你的文字记录,这意味着他们在你的网站上花费了大量时间。会话时长可以提升 SEO。
作为一名内容创作者,你得努力让尽可能多的人看到你的内容。你肯定不想因为忽视了潜在受众的需求而疏远他们。
我们尝试过很多方法获取成绩单。我想分享一下我们尝试过的方法以及每种方法的优缺点。
让别人为你做这件事
我们首先尝试的是雇人,因为这是我们唯一知道的选择。我们没有时间把整个音频都过一遍并写出来。所以我们决定雇人帮我们做这件事。我们使用了 Fiverr,我以前从未尝试过。然而,雇人做这件事有利有弊。
优点:
- 付钱给真人,支持别人。
- 实时捕获错误
缺点:
- 昂贵的
- 因为他们是人类,所以需要几天的时间才能让他们回来,这对于快速转身来说并不理想。
- 语言差异。
使用人工智能
另一种选择是使用人工智能软件解析你的音频并提供文字记录。我们尝试了Trint和Otter AI,它们都是很棒的工具。人工智能也有一些优点和缺点。
优点:
- 几分钟或几小时内即可获得您的成绩单。Otter AI 大约需要 10 分钟。
- 更便宜
- 随着他们学习你的演讲者,情况会变得更好
缺点:
- 尤其是刚开始的时候,你必须编辑它。我们不想在里面出现乱七八糟的单词,所以我们花了一些时间听这个工具读出文字记录。
- 当我使用机器学习来取代人类可以做的工作时,我感到有点内疚。
我们最终做了什么
由于我们需要快速交付,最终选择了AI。我们和OtterAI达成了协议,最终选择了他们。最终选择最适合自己的方案,所有选择都是好的!
自定义播客播放器的 A11y 注意事项
你可能知道,也可能不知道,我们使用GatsbyJS构建了 LadyBug Podcast 网站。我负责制作一个易于访问的播客播放器。我学到了很多关于如何使用 React 创建所有 audioElement 事件的知识。非常感谢Syntax.fm提供了一个可供我探索的播放器。我做的第一件事就是ref
给一个<audio>
元素添加一个。
class Player extends React.Component {
render() {
const { show } = this.props;
return (
<audio
ref={audio => (this.audio = audio)}
src={show.audio}
/>
)
}
}
如果我进入代码并添加console.log
class Player extends React.Component {
render() {
const { show } = this.props;
console.log(this.audio)
return (
<audio
ref={audio => (this.audio = audio)}
src={show.audio}
/>
)
}
}
这使我能够访问音频的所有方法。我可以在我的自定义播放器上以按钮、单选按钮和滑块的形式使用它们。
在播客播放器中,我使用了以下方法:
- HTMLMediaElement.currentTime - 这会告诉您音频的当前时间(以秒为单位)。
- HTMLMediaElement.playbackRate - 这会告诉你播放的速度。我们可以在按下按钮时设置此属性来提高速度!
- HTMLMediaElement.volume——这会告诉您当前的音量级别。
- HTMLMediaElement.play() - 播放音频。
- HTMLMediaElement.pause() - 暂停音频。
- HTMLMediaElement.duration - 这会告诉您音频的总长度(以秒为单位)。
将 添加ref
到音频后,您就可以用它this.audio
来控制任何与音频相关的内容。您可以将方法或属性名称附加到。真是太棒了!您也可以用它来控制 React 状态🤯!我不会在这篇博文中过多地介绍所有状态。如果您想了解更多信息,this.audio
我建议您查看我们的源代码以及Syntax.fm 源代码。
按钮标签
按钮标签是播放器无障碍访问的最关键部分。记住,我们正在“破解”音频播放器。我们必须确保屏幕阅读器、键盘和鼠标用户能够访问播放器。后者是残障人士关注的重点,所以如果你正在这样做,我希望确保你考虑到所有体验。
我使用该react-icons/fa
包获取了播放器的图标。我们使用FaPlay
、FaPause
、FaUndo
和FaRedo
作为播放、暂停、后退 15 秒和快进 15 秒按钮。这些图标是 SVG 图标,但我希望确保标记中包含文本。为此,我们确保了以下几点:
- 我们使用语义化
<button>
而不是 a 来<div>
支持键盘事件。阅读我的“提升键盘可访问性的三个简单技巧”文章了解更多信息。 - 我们确保不使用图标字体,这已经通过库为我们解决了
react-icons
。 - 我们确保按钮内有实际的文本,而 SVG 无法做到这一点。我们可以使用 CSS 在视觉上隐藏这些文本,但它仍然必须存在。
<button class="player__icon">
<svg>
<!--paths and things-->
</svg>
<span class="sr-only">play</span>
</button>
创建滑块
我四处寻找一个可以显示滑块的无障碍播放器。我找到了Able Player,并开始观察他们的运作方式。让它变得无障碍是我做过的最难的事情之一,而且它仍然有很多 bug。代码最终变成了许多带有 aria 标签的 div 和大量的事件处理。这个项目的难题是,完成比完美更重要。回想起来,我真希望当初用range input把它做成一个滑块。吸取了教训——敬请期待我更新滑块后发布的后续博客文章!
现在,我将介绍一下我想用滑块做什么的思考过程。以下是源代码……
<div
className="player__progress"
onClick={this.scrub}
ref={x => (this.progress = x)}
>
<div className="player__progress-loaded" />
<div
className="player__progress-played"
style={{ width: `${(currentTime / duration + 0.015) * 100}%` }}
/>
<div
orientation="horizontal"
onKeyDown={this.moveSlider}
tabIndex="0"
className="player__slider"
role="slider"
aria-label="audio timeline"
aria-valuemin="0"
aria-valuemax={duration}
aria-valuetext={renderValueText(currentTime)}
aria-valuenow={renderValueNow(currentTime)}
style={{ left: `${(currentTime / duration - 0.01) * 100}%` }}
/>
</div>
我有 3 个播放器的子 div:.player__progress-loaded
、.player__progress-played
和.player__slider
。让我们看看它们分别对应什么:
.player__progress-loaded
对应于整个滑块的宽度。此 div 对屏幕阅读器用户没有任何语义价值。.player__progress-played
是所玩总金额的直观表示。.player__slider
是实现可访问性最重要的元素。它告诉屏幕阅读器用户当前时间,并允许我们使用键盘移动时间。
现在让我们来看看这里的一些事件和风格。
对于onClick
事件,我们希望确保currentTime
音频中的 被修改到我们点击的位置。如果可以的话,请自己查看代码,fork 一下,然后在控制台中记录所有内容,看看发生了什么。点击.player__progress
div 上的任意位置, 都会被修改currentTime
。
对于.player__progress-played
div,我们进行了样式设置。组件的宽度是剧集播放长度的百分比。
现在介绍滑块本身以及几个辅助函数,其中一个是我从 Syntax 的站点改编而来的。
我的天,ARIA 属性好多啊!我们来分析一下:
role="slider"
- 这告诉屏幕阅读器用户非语义的 div 具有一定的意义!aria-valuetext
- 这是滑块值的可读版本。例如,在上面的屏幕截图中,它是“5 分 51 秒”。aria-valuenow
- 定义范围小部件(滑块)的当前值aria-valuemin
- 定义范围小部件的最小值的必需属性aria-valuemax
- 定义范围小部件的最大值的必需属性
以下是 macOS 上的 VoiceOver 如何读取滑块:
“5 分 51 秒,音频时间轴,滑块”。所以aria-valuetext
,aria-label
然后是role
。
使用 时this.moveSlider
,按下向左或向右箭头,分别后退或快进 5 秒。查看源代码,了解我们是如何实现的。
我想如何重做滑块
如前所述,这确实有点 bug。以下是一些 bug:
- 浏览器支持(我收到了一位听众的评论,但还没有检查)
- 我不知道如何用鼠标拖动滑块。
因此,无论出于什么原因,我假设(大家不要假设,这很危险)您无法自定义范围输入的样式。
我错了。你完全可以。
结论
开办播客总体来说是一个非常积极的体验。我相信我们会在“Ladybug”播客上分享一些开办播客过程中学到的更普遍的经验!
这篇文章有两个关键要点:
- 一定要有成绩单。花时间和金钱去记录其他人的经历是值得的。这不是个例。
- 谨慎破解音频播放器并确保进行过度测试。
如果您对 LadyBug Podcast 感兴趣,请务必订阅以便下载!
保持联系!如果你喜欢这篇文章:
- 在Twitter上告诉我,并和你的朋友们分享这篇文章!另外,如果你有任何后续问题或想法,也欢迎随时在 Twitter 上给我留言。
- 在Patreon上支持我!如果您喜欢我的作品,可以考虑每月捐赠 1 美元。如果您捐赠 5 美元或更高,您将可以对以后的博客文章进行投票!我每月还会为所有赞助人举办“问我任何问题”活动!
- 抢先了解我的帖子,了解更多无障碍趣味!
干杯!祝你度过愉快的一周!
鏂囩珷鏉ユ簮锛�https://dev.to/lkopacz/a11y-lessons-i-learned-when-starting-a-podcast-3l82