vue2.0移动端图片视频video 混合九宫格预览组件遇到的问题

阅读: 评论:0

vue2.0移动端图片视频video 混合九宫格预览组件遇到的问题

vue2.0移动端图片视频video 混合九宫格预览组件遇到的问题

vue项目获取网络视频/图片九宫格列表展示预览组件

今天有点时间,总结下前段时间在vue项目中做的移动端视频/图片上传查看组件遇到的一些问(大)题(坑),组件全部实现过程就不讲了,主要说其中遇到的问题以及解决方法,有不足之处请大神们拍砖指教

问题1:将获取尺寸不一的图片/视频在方格内展示

由于无法确定图片的尺寸大小,就决定使用js来控制样式(不拉伸图片,截取方格展示)

解决思路:将图片相对于父盒子上下左右居中显示,方法很多,选一个自己中意的就好了。js获取图片视频尺寸,若宽比高长,就以设置高为100%,反之就设置宽为100%,父盒子设置溢出隐藏。简单粗暴,就这样。

css实现

问题2:在mounted生命周期内获取图片/视频尺寸问题

理想没毛病,现实总是会挖很多坑等你。美美的想着,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%'}}        }
}
问题3:如何获取视频图片作为预览封面

拿到的数据就是视频的url地址,并没有缩略图,怎么破,自己创造呗,网上找了很多资源,大家都差不多,将video隐藏,使用canvas来绘制一张video一帧,使用toDataURL将地址给创建的img图片的src就好。

几个注意点:

  1. 获取视频尺寸问题,我是选择在 loadeddata 事件后获取,目前没啥毛病
  2. 虽然你设置了autoplay在Safari视频也不会自动播放(我的是有音频的文件,不能静音),但是一定要设置autoplay才能自动触发video的loadeddata事件,所以需要设置autoplay,曾经被坑哭了
    可以了解更多video加载过程事件:.asp
  3. 在mounted内干这事

代码:

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)  } 
}
问题4:canvas绘制视频封面时,若视频非本地地址而是网络请求回来的地址,使用toDataURL会报安全问题错误

解决:设置video的标签属性crossorigin为anonymous,然后在视频加载后处理canvas。其中还需要后端配合设置CORS为所有*

 video.setAttribute('crossorigin', 'anonymous')
问题5:ios设备上video标签不自动加载

由于浏览器的限制,用户未点击之前呈现的是黑屏,即使设置了preload="auto"也无效,体验很糟糕。需要配合设置video的poster属性,手动设置视频封面。

video.setAttribute('poster', dataUrl);

解决思路:canvas获取视频的第一帧,赋值给poster属性
过程中遇到一个很坑很坑的事情:虽然你设置了autoplay在Safari视频也不会自动播放,但是一定要设置autoplay才能触发video的loadeddata事件,就是这里被坑哭的,呜呜呜。。。

问题6:video标签在ios设备上自动全屏播放问题

到此,似乎已经很满意很开心了,可是在ios设备上查看视频时,鸡肋的将视频自动全屏播放,不是我想要的样子,打死都不开心,找找找,人家是可以设置的,Down there:

<video :src="item" class="swipe-video" v-else controls="controls" webkit-playsinline playsinline x5-playsinline x-webkit-airplay="allow"></video>

终于相对满意了,开心,撒花花

最后附一下关键代码

data:
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']
html:
<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)  } 
}
设置video封面海报poster:
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小时内删除。

标签:组件   九宫格   图片   视频   video
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23