背景
在做需求的时候,都开发完成了,自测兼容性的时候,发现safari的video却不能正常运行,在控制台中输入video.error,发现报错了,我得blob地址放入<video />
src 其他浏览器都正常,为什么就safari不支持呢?于是想办法处理
排查
使用的safari是最新版的Mac系统13.3.1
做了以下排查测试:
- 将
<video />
src更换为http协议的mp4地址,可以正常播放 - 能第1点的静态资源mp4转为blob之后,放入
<video />
src,不能正常播放 - 本地静态资源放入
<video />
src,能正常播放
说明:safari的<video />
不能支持blob类型的src
再查查一下webkit的bugIssue
在海外论坛逛了几圈,发现确实是兼容性问题
解决方法
传入<video />
src只要是mp4类型的blob就行了
代码部分:
如果还没转为blob,那么就成blob
/**
* 将链接地址字符内容转变成 Blob 地址
* @param {string} url - 资源下载地址
* @returns {Promise<string>} 包含 Blob 地址的 Promise 对象
*/
export const urlDownload2Blob = async (url) => {
try {
const res = await fetch(url);
if (res.status !== 200) {
throw new Error('Request failed');
}
const arrayBuffer = await res.arrayBuffer();
// 兼容 Safari,Safari 无法将非 'video/mp4' 的 Blob 传入 video src
const blob = new Blob([arrayBuffer], { type: 'video/mp4' });
// 兼容 Safari
window.URL = window.URL || window.webkitURL;
// 将链接地址字符内容转变成 Blob 地址
const blobUrl = window.URL.createObjectURL(blob);
return blobUrl;
} catch (error) {
throw new Error('Failed to convert URL to Blob');
}
};
如果已经是blob了,那么就对blob进行类型转换
/**
* 将 Blob 地址转换为 MP4 类型的 Blob 对象
* @param {string} blobUrl - Blob 地址
* @returns {Promise<Blob>} 转换后的 MP4 类型的 Blob 对象
*/
const blobUrlToMP4Blob = async (blobUrl) => {
try {
const response = await fetch(blobUrl);
const arrayBuffer = await response.arrayBuffer();
const mp4Blob = new Blob([arrayBuffer], { type: 'video/mp4' });
return mp4Blob;
} catch (error) {
throw new Error('Failed');
}
};