我开始播客时学到的 A11y 经验教训

2025-06-09

我开始播客时学到的 A11y 经验教训

最初发布于a11ywithlindsey.com

如果你没注意到,我好像很久没来了!我已经一个月没发帖了,这其中有原因的。我和 Kelly Vaughn、Ali Spittel、Emma Wedekind 一起创办了LadyBug 播客。这个播客的制作费了不少功夫。因此,我一直在琢磨如何平衡这个博客和那个副业!不过别担心,这不会消失。我的博客是我的热情之作!

现在你知道了我的近况,我学到了很多关于播客以及它与无障碍互联互通的知识。我对其中一些内容了解得比较多,但在这篇文章中,我们将进行更深入的探讨。

成绩单是必须的

当我们开始策划这期播客时,我们当然希望有文字记录。文字记录既费时又费钱,很多人觉得它只是“锦上添花”。然而,我要告诉你们,文字记录是必不可少的。

成绩单有很多好处:

  1. 聋人和听力障碍人士也可以访问您的精彩内容。
  2. 有些人更喜欢阅读而不是聆听。我数不清有多少健全人士告诉我,他们很感激有文字记录。
  3. 它可以帮助那些母语不是英语的人。
  4. 如果人们阅读了你的文字记录,这意味着他们在你的网站上花费了大量时间。会话时长可以提升 SEO。

作为一名内容创作者,你得努力让尽可能多的人看到你的内容。你肯定不想因为忽视了潜在受众的需求而疏远他们。

我们尝试过很多方法获取成绩单。我想分享一下我们尝试过的方法以及每种方法的优缺点。

让别人为你做这件事

我们首先尝试的是雇人,因为这是我们唯一知道的选择。我们没有时间把整个音频都过一遍并写出来。所以我们决定雇人帮我们做这件事。我们使用了 Fiverr,我以前从未尝试过。然而,雇人做这件事有利有弊。

优点:

  • 付钱给真人,支持别人。
  • 实时捕获错误

缺点:

  • 昂贵的
  • 因为他们是人类,所以需要几天的时间才能让他们回来,这对于快速转身来说并不理想。
  • 语言差异。

使用人工智能

另一种选择是使用人工智能软件解析你的音频并提供文字记录。我们尝试了TrintOtter 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}
      />
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

如果我进入代码并添加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}
      />
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

这使我能够访问音频的所有方法。我可以在我的自定义播放器上以按钮、单选按钮和滑块的形式使用它们。

在播客播放器中,我使用了以下方法:

将 添加ref到音频后,您就可以用它this.audio来控制任何与音频相关的内容。您可以将方法或属性名称附加到。真是太棒了!您也可以用它来控制 React 状态🤯!我不会在这篇博文中过多地介绍所有状态。如果您想了解更多信息,this.audio我建议您查看我们的源代码以及Syntax.fm 源代码。

按钮标签

按钮标签是播放器无障碍访问的最关键部分。记住,我们正在“破解”音频播放器。我们必须确保屏幕阅读器、键盘和鼠标用户能够访问播放器。后者是残障人士关注的重点,所以如果你正在这样做,我希望确保你考虑到所有体验。

我使用该react-icons/fa包获取了播放器的图标。我们使用FaPlayFaPauseFaUndoFaRedo作为播放、暂停、后退 15 秒和快进 15 秒按钮。这些图标是 SVG 图标,但我希望确保标记中包含文本。为此,我们确保了以下几点:

  1. 我们使用语义化<button>而不是 a 来<div>支持键盘事件。阅读我的“提升键盘可访问性的三个简单技巧”文章了解更多信息。
  2. 我们确保不使用图标字体,这已经通过库为我们解决了react-icons
  3. 我们确保按钮内有实际的文本,而 SVG 无法做到这一点。我们可以使用 CSS 在视觉上隐藏这些文本,但它仍然必须存在。
<button class="player__icon">
  <svg>
    <!--paths and things-->
  </svg>
  <span class="sr-only">play</span>
</button>
Enter fullscreen mode Exit fullscreen mode

创建滑块

我四处寻找一个可以显示滑块的无障碍播放器。我找到了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>
Enter fullscreen mode Exit fullscreen mode

我有 3 个播放器的子 div:.player__progress-loaded.player__progress-played.player__slider。让我们看看它们分别对应什么:

自定义音频播放器:播放部分为红色,滑块为白色圆圈。

  • .player__progress-loaded对应于整个滑块的宽度。此 div 对屏幕阅读器用户没有任何语义价值。
  • .player__progress-played是所玩总金额的直观表示。
  • .player__slider是实现可访问性最重要的元素。它告诉屏幕阅读器用户当前时间,并允许我们使用键盘移动时间。

现在让我们来看看这里的一些事件和风格。

对于onClick事件,我们希望确保currentTime音频中的 被修改到我们点击的位置。如果可以的话,请自己查看代码,fork 一下,然后在控制台中记录所有内容,看看发生了什么。点击.player__progressdiv 上的任意位置, 都会被修改currentTime

对于.player__progress-playeddiv,我们进行了样式设置。组件的宽度是剧集播放长度的百分比。

现在介绍滑块本身以及几个辅助函数,其中一个是我从 Syntax 的站点改编而来的。

我的天,ARIA 属性好多啊!我们来分析一下:

  1. role="slider"- 这告诉屏幕阅读器用户非语义的 div 具有一定的意义!
  2. aria-valuetext- 这是滑块值的可读版本。例如,在上面的屏幕截图中,它是“5 分 51 秒”。
  3. aria-valuenow- 定义范围小部件(滑块)的当前值
  4. aria-valuemin- 定义范围小部件的最小值的必需属性
  5. aria-valuemax- 定义范围小部件的最大值的必需属性

以下是 macOS 上的 VoiceOver 如何读取滑块:

“5 分 51 秒,音频时间轴,滑块”。所以aria-valuetextaria-label然后是role

使用 时this.moveSlider,按下向左或向右箭头,分别后退或快进 5 秒。查看源代码,了解我们是如何实现的。

我想如何重做滑块

如前所述,这确实有点 bug。以下是一些 bug:

  1. 浏览器支持(我收到了一位听众的评论,但还没有检查)
  2. 我不知道如何用鼠标拖动滑块。

因此,无论出于什么原因,我假设(大家不要假设,这很危险)您无法自定义范围输入的样式。

我错了。你完全可以。

结论

开办播客总体来说是一个非常积极的体验。我相信我们会在“Ladybug”播客上分享一些开办播客过程中学到的更普遍的经验!

这篇文章有两个关键要点:

  1. 一定要有成绩单。花时间和金钱去记录其他人的经历是值得的。这不是个例。
  2. 谨慎破解音频播放器并确保进行过度测试。

如果您对 LadyBug Podcast 感兴趣,请务必订阅以便下载!

保持联系!如果你喜欢这篇文章:

  • 在Twitter上告诉我,并和你的朋友们分享这篇文章!另外,如果你有任何后续问题或想法,也欢迎随时在 Twitter 上给我留言。
  • 在Patreon上支持我!如果您喜欢我的作品,可以考虑每月捐赠 1 美元。如果您捐赠 5 美元或更高,您将可以对以后的博客文章进行投票!我每月还会为所有赞助人举办“问我任何问题”活动!
  • 抢先了解我的帖子,了解更多无障碍趣味!

干杯!祝你度过愉快的一周!

鏂囩珷鏉ユ簮锛�https://dev.to/lkopacz/a11y-lessons-i-learned-when-starting-a-podcast-3l82
PREV
ARIA States 简介
NEXT
我经常手动测试的 4 件事