今天有点时间,总结下前段时间在vue项目中做的移动端视频/图片上传查看组件遇到的一些问(大)题(坑),组件全部实现过程就不讲了,主要说其中遇到的问题以及解决方法,有不足之处请大神们拍砖指教
由于无法确定图片的尺寸大小,就决定使用js来控制样式(不拉伸图片,截取方格展示)
解决思路:将图片相对于父盒子上下左右居中显示,方法很多,选一个自己中意的就好了。js获取图片视频尺寸,若宽比高长,就以设置高为100%,反之就设置宽为100%,父盒子设置溢出隐藏。简单粗暴,就这样。
css实现 :
理想没毛病,现实总是会挖很多坑等你。美美的想着,dom在mounted生命周期内已经挂在完了,这时候我去获取图片尺寸应该没毛病可以吧,得,是获取到,宽高全都是0!原因就是Dom已经加载了没错,可因为网络请求原因,图片/视频资源还没加载回来,以致数据都是0。图样图森破,尝试了很多方法,$nextTick也不管用。setTimeout设置一段时间后请求可以解决这个问题,但是对于请求时间的不确定性,以及强迫症晚期不允许我这么粗暴处理,继续想想方法,那就等图片/视频资源加载后再去获取宽高啊,聪明如我,哈哈哈
calcImgStyle(){ //设置图片在方格内展示let imgArr = document.querySelectorAll(".img")for(let i=0;i<imgArr.length;i++){imgArr[i].onload = ()=>{ if(imgArr[i].width>imgArr[i].height){imgArr[i].style.height = '100%' }else {imgArr[i].style.width = '100%'}} }
}
拿到的数据就是视频的url地址,并没有缩略图,怎么破,自己创造呗,网上找了很多资源,大家都差不多,将video隐藏,使用canvas来绘制一张video一帧,使用toDataURL将地址给创建的img图片的src就好。
几个注意点:
代码:
captureVideoImage() {let videoArr = document.querySelectorAll(".video") for(let i=0;i<videoArr.length;i++){//loadeddata当当前帧的数据已加载,但没有足够的数据来播放指定音频/视频的下一帧时,会发生 loadeddata 事件。//浏览器支持:所有主流浏览器都支持 loadeddata 事件。注释:Internet Explorer 8 或更早的浏览器不支持该事件。let video = videoArr[i]video.addEventListener('loadeddata', function () { let canvas = ateElement('canvas')canvas.width = video.videoWidth //loadeddata事件后,获取视频宽高妥妥的canvas.height = video.videoHeight Context('2d').drawImage(video, 0, 0, canvas.width, canvas.height)let dataUrl = DataURL('image/png')let pareantNode = video.parentNodelet imgNode = ateElement('img')imgNode.src = dataUrl if( video.videoWidth > video.videoHeight ){imgNode.style.height = '100%' }else {imgNode.style.width = '100%'} pareantNode.appendChild(imgNode) video.pause() }, false) }
}
解决:设置video的标签属性crossorigin为anonymous,然后在视频加载后处理canvas。其中还需要后端配合设置CORS为所有*
video.setAttribute('crossorigin', 'anonymous')
由于浏览器的限制,用户未点击之前呈现的是黑屏,即使设置了preload="auto"也无效,体验很糟糕。需要配合设置video的poster属性,手动设置视频封面。
video.setAttribute('poster', dataUrl);
解决思路:canvas获取视频的第一帧,赋值给poster属性
过程中遇到一个很坑很坑的事情:虽然你设置了autoplay在Safari视频也不会自动播放,但是一定要设置autoplay才能触发video的loadeddata事件,就是这里被坑哭的,呜呜呜。。。
到此,似乎已经很满意很开心了,可是在ios设备上查看视频时,鸡肋的将视频自动全屏播放,不是我想要的样子,打死都不开心,找找找,人家是可以设置的,Down there:
<video :src="item" class="swipe-video" v-else controls="controls" webkit-playsinline playsinline x5-playsinline x-webkit-airplay="allow"></video>
终于相对满意了,开心,撒花花
feedbackImages:['../static/images/test/img_1.jpg','../static/images/test/img_2.jpg','../static/images/test/img_3.png','../static/images/test/img_4.png','../static/images/test/video_1.mp4','.mp4']
<span v-for="(item,index) in feedbackImages" :key="item" @click.stop.prevent="view(index)" ><img :src="item" v-if="isImg(item)" class="img"/><div class="video-con" v-else > <video :src="item" class="swipe-video" x-webkit-airplay="allow" autoplay preload="auto" webkit-playsinline playsinline x5-playsinline x-webkit-airplay="allow"></video> </div>
</span>
captureVideoImage() {let videoArr = document.querySelectorAll(".video") for(let i=0;i<videoArr.length;i++){//loadeddata当当前帧的数据已加载,但没有足够的数据来播放指定音频/视频的下一帧时,会发生 loadeddata 事件。//浏览器支持:所有主流浏览器都支持 loadeddata 事件。注释:Internet Explorer 8 或更早的浏览器不支持该事件。let video = videoArr[i]video.addEventListener('loadeddata', function () { let canvas = ateElement('canvas')canvas.width = video.videoWidth canvas.height = video.videoHeight video.setAttribute('crossorigin', 'anonymous')//跨域设置,后端也需要设置CORS为*Context('2d').drawImage(video, 0, 0, canvas.width, canvas.height)let dataUrl = DataURL('image/png')let pareantNode = video.parentNodelet imgNode = ateElement('img')imgNode.src = dataUrl if( video.videoWidth > video.videoHeight ){imgNode.style.height = '100%' }else {imgNode.style.width = '100%'} pareantNode.appendChild(imgNode) video.pause() }, false) }
}
setPoster() {let videoArr = document.querySelectorAll(".swipe-video") for(let i=0;i<videoArr.length;i++){ let video = videoArr[i]video.setAttribute('crossorigin', 'anonymous')let canvas = ateElement('canvas')canvas.width =video.videoWidth canvas.height =video.videoHeight video.addEventListener('loadeddata', function () { Context('2d').drawImage(video, 0, 0, canvas.width, canvas.height)let dataUrl = DataURL('image/png') video.setAttribute('poster', dataUrl);video.pause()}, false) }
}
本文发布于:2024-01-28 12:20:10,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17064156137377.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |