问题:同样的组件在移动端怎样都无法播放视频,音频、图片、pdf等都可以正常加载,加载的页面状态一直是禁止播放:
贴一波源码
如果要加载的资源是video,首先会触发handleIChangeVideo这个方法,用于调整样式,用于放在通用组件的合适范围里面
function handleIChangeVideo(url: string) {
linkState.status = StatueEnum.LOADING;
const video = document.createElement('video');
video.src = url;
video.oncanplay = (e: Event) => {
contentRatio.value = video.videoWidth / video.videoHeight;
if (linkState.currentUrl !== url) {
const ele: any[] = e.composedPath();
linkState.linkScale = Number(props.linkScale) || 0.8;
ele && emit('img-load', {
index: linkState.currentIndex,
dom: ele[0],
url
});
}
linkState.currentUrl = url;
linkState.status = StatueEnum.DONE;
};
}
然后会触发渲染函数,返回对应的dom,将dom插入到它父组件中,整个弹窗是动态创建的组件
case ResourceType.Video:
return (
<div
style={unref(getImageStyle)}
class={[
`${prefixCls}-image`,
linkState.status === StatueEnum.DONE ? '' : 'hidden'
]}
ref={imgElRef}
onMousedown={handleAddMoveListener}
>
<video autoplay controls src={linkState.currentUrl} />
</div>
);
排查流程:
1. google一圈以为是移动端禁止自动播放导致,然后我将autoplay去掉了也无法解决
2. 将源码发给chatgpt帮我分析错误,强调了不同浏览器的安全策略、资源不支持加载等,可是我的资源是常规mp4,并且测试了多个平台没有一个能用
3. 尝试在handleIChangeVideo方法中,注释掉oncanplay方法,直接将linkState.currentUrl赋值,再看的时候视频内容就显示出来了,并且可以点击进行播放。找到出问题的代码了就好解决了,于是我去搜oncanplay方法的触发时机,看看能不能替换为其它的方法来达到我的样式。
将oncanplay替换为onloadedmetadata,再次尝试就好了。
onloadedmetadata:获取视频meta信息完毕,这个时候播放器已经获取到了视频时长和视频资源的文件大小。
oncanplay:在用户可以开始播放视频/音频(audio/video)时触发
原因:
在IOS中不会自动加载音视频,所以oncanplay事件不会自动执行;而在 pc 端和 android 端,系统会自动加载音视频,所以oncanplay会自动被执行