问题背景
- 监控出现大量静态资源加载异常报警,ios和安卓各系统版本都有(排查了一段时间,发现是QA同学在全量测试,无语凝噎)
- QA测试反馈,报告页在收音失败的情况稳定复现播放音频失败(确实有问题,监控有效)
排查路径
首先通过error事件的日志数据,发现ErrorEvent中并没有错误message,头一次见。
怀疑音频错误事件有什么特殊处理,在网上搜索到media、video等媒体替换标签的错误属于MediaError,可以通过元素上下文的ele.error.code获取上一次错误的信息。
这个错误码总共包含四种类型:
名字 | 值 | 说明 |
---|---|---|
MEDIA_ERR_ABORTED | 1 | 资源请求被用户中断 |
MEDIA_ERR_NETWORK | 2 | 因为某些网络原因导致资源加载失败 |
MEDIA_ERR_DECODE | 3 | 资源解码出错 |
MEDIA_ERR_SRC_NOT_SUPPORTED | 4 | 资源不支持 |
通过日志确认报错信息为4,即不支持该资源。怀疑格式有问题
将音频文件下载下来后查看,内容也符合wave标准,但大小仅44Bytes,表示文件无内容
于是回过头排查资源请求是否异常,通过PerformanceResourceTiming API能力,看到资源的类型是空的,资源类型未能正确识别。
怀疑是MIME格式非标准,遂查阅音频相关MIME MDN,发现audio/wave是标准的,但如果编码格式非1,支持度有限。
又去看了文件内容。可以看到编码格式为1,是PCM(Pulse Code Modulation / 脉冲编码调制),无信号压缩。
又陷入僵局,一个好奇心驱使我去查了下为什么会有audio/wav和audio/wave两个MIME,结果这两是一个东西。不过我也还是用charles代理修改响应头,将 content-type: audio/wave 变为 audio/wav,但别没有效果。
此时,注意到高版本设备中,会触发资源加载异常,但不会触发audio的error事件。通过对比资源数据,发现高版本系统可识别资源类型。
最后将该文件转为mp3格式,同样有问题。(与格式类型无关?)
综上排查链路告一段落。
具体原因
- 当音频资源数据为空时,部分设备无法解码出资源类型,直接触发MEDIA_ERR_SRC_NOT_SUPPORTED错误。
- 该错误冒泡至window下,被外层捕获并统一上报
解决办法
duration为0的音频认为是不合法。
- 页面不展示
- 错误提示区分
- 兜底默认音频
相关文档
在线 十六进制 编辑器
wav文件格式解析
MediaError.code - Web APIs | MDN
【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )_韩曙亮的博客-CSDN博客
HTMLMediaElement.error - Web APIs | MDN
MIME types (IANA media types) - HTTP | MDN
Common MIME types - HTTP | MDN