HTML音频可访问性与输入范围

9
最简单的问题示例:https://codepen.io/sidouglas/pen/LYPZaOG 当输入范围得到关注时,使用Chrome Vox或Mac的Voice over,会连续读出每个valuetext的值。
<input
 ...
  v-bind:aria-valuemax="valueMax"
  v-bind:aria-valuenow="valueNow"
  v-bind:aria-valuetext="currentTime + ' of ' + totalDuration"
  ...
/>

与非常易于访问的https://plyr.io/#audio组件相比,它在聚焦时会持续更新其aria值,但只会向屏幕阅读器通报两次。有人知道plyr是如何做到的吗?

new Vue({
  el: '#range',
  data: {
    valueMax:100,
    duration:100,
    current:0,
    totalDuration:'1:40'
  },
  computed:{
    currentTime: function() {
      return this.convertTime(this.current);
    },
     valueNow() {
      return Math.round(this.current);
    },
  },
  methods: {
    convertTime(time) {
      const minutes = Math.floor(time / 60);
      const seconds = time - (minutes * 60);
      return `${minutes}:${seconds.toFixed(0).toString().padStart(2, '0')}`;
    },
  },
  mounted: function(){
   var self = this;
   setInterval(function(){
     self.current = Number(self.current) + 1;
     if(self.current >= self.valueMax){
        self.current = 0;
     }
    },2000);
  },
});
.audio-file-player__slider-range{
  border:1px solid red;
  width:100%;
}

.audio-file-player__slider-range:focus {
  box-shadow: 0 0 10px blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="range">
  <input
         aria-label="Seek"
         aria-valuemin="0"
         autocomplete="off"
         class="audio-file-player__slider-range u-color-gray-111111 u-width-100"
         min="0"
         role="slider"
         step="1"
         type="range"
         v-bind:aria-valuemax="valueMax"
         v-bind:aria-valuenow="valueNow"
         v-bind:aria-valuetext="currentTime + ' of ' + totalDuration"
         v-bind:max="duration"
         v-model="current"
         />
  <p>current: {{ current }}</p>
  <p>aria-valuenow: {{ valueNow }}</p>
  <p>aria-valuetext: {{ currentTime + ' of ' + totalDuration }}</p>
</div>


1
我不知道plyr在做什么,但是它也会重复。并非总是如此。不知道为什么有时会重复较少。 - gman
嗯,我不太明白,但你是对的,这不是一个很好的体验。看起来我得开始使用Vue了。 - Simon
2个回答

1
对于任何遇到此问题的人,简单的解决方案是使用aria-valuetext覆盖该值。
当项目正在播放时,我会在第一次获得焦点时将aria-valuetext设置为“当前:currentTime,剩余时间:remainingTime”。
然后在项目正在播放时不要更新时间(保持aria-valuetext不变)。
最后,当播放暂停/停止时,再次更改aria-valuetext以反映当前时间。
最后,我会在200毫秒的节流下更新当前时间,以便某人使用箭头键进行搜索。
您可以决定在播放时是否执行此操作,或仅在不播放时执行此操作,因为我不确定哪种方法在信息与干扰方面更好。
我倾向于在播放时不进行更新,因为用户始终可以通过制作聚焦点来切换到当前时间。
通过这样做,您可以确保它不会干扰播放音乐或宣布200个不同的时间。

plyr.io理论 - 对我来说,它一开始也是重复的,然后我改变了我的公告速度设置。我相信有些人会得到通知,有些人则不会,原因在于他们更新当前时间的速度(看起来每秒3-4次),我认为这样重复得如此之快,屏幕阅读器决定不要让用户感到困惑。只是一个理论,但是我最好的猜测是他们没有做任何聪明的事情。


0
将您的歌曲路径转换为计算属性,然后获取其currentTime。如下所示:
<template>
  <div>
    <h3>Audio Player Test</h3>

    <audio
      ref="myMusic"
      src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3"
      @timeupdate="onTimeUpdateListener"
    ></audio>
    {{currentTime}}
    <button @click="play">Play</button>
    <button @click="pause">Pause</button>
  </div>
</template>

data() {
    return {
      songCurrent: 0,
      currentTime: "00:00" // The initial current time
    };
},
computed: {
    song() {
      return this.$refs.myMusic;
    }
}
methods: {
    play() {
      this.song.play();
    },
    pause() {
      this.song.pause();
    },
    onTimeUpdateListener: function() {
      // Update current time
      this.currentTime = this.$refs.myMusic.currentTime;
    }
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接