Audio duration NaN

257 阅读1分钟

需求

上传音频后,点击确认,将文件信息(文件名,文件类型,播放时长)同步后端。

...
<audio
  ref="audio"
  :src="audioUrl"
></audio>
...
<el-button type="primary" @click="toConfirm">确认</el-button>
...
toConfirm() {
  ...
  const params = {
    ...
    duration: this.$refs.audio.duration.toFixed(2),
  };
  ...
}
...

问题

偶现:点击确认按钮,发现duration的值是NaN,特别是刚上传成功后,马上点击确认按钮则能稳定复现,duration值返回NaN。

console.log('this.$refs.audio.duration', this.$refs.audio.duration)

分析

根据现象分析,上传文件成功后,audio媒体资源还没加载或还没获取媒体元数据等信息,此时获取duration,则会返回NaN

解决方案

监听durationchange事件,在durationchange事件触发后,audio的duration就能获取到。

...
<audio
  ref="audio"
  :src="audioUrl"
  @durationchange="durationchange"
></audio>
...
<el-button type="primary" @click="toConfirm">确认</el-button>
...
durationchange() {
  this.durationChange = true;
},
toConfirm() {
  ...
  if(this.durationChange) {
    const params = {
      ...
      duration: this.$refs.audio.duration.toFixed(2),
    };
  }
  ...
}
...

浏览器媒体HTMLMediaElement加载生命周期

image.png

  • loadstart

    当浏览器开始载入一个资源文件时触发

  • durationchange

    在 duration 属性更新时被触发

  • loadedmetadata

    在元数据(metadata)被加载完成后触发

  • canplay

    在终端可以播放媒体文件时(但估计还没有加载足够的数据来播放媒体直到其结束,即后续可能需要停止以进一步缓冲内容)被触发

  • canplaythrough

    在终端可以播放媒体文件时(估计已经加载了足够的数据来播放媒体直到其结束,而不必停止以进一步缓冲内容)被触发