uni-app从后端返回的mp4链接视频截取一帧为封面

2 篇文章 0 订阅
一、需求:

后端返回包含视频链接的数组对象,格式如下:

[
   {
      url: 'xxxxx.mp4',
   },
   {
      url: 'xxxxx.mp4',
   },
   {
      url: 'xxxxx.mp4',
   },
]

从上面的mp4视频中截取一帧设置为封面,如下图,下面的封面图从视频中截取而来。
在这里插入图片描述

二、代码实现:
<script>
	export default {
		onLoad() 
			this.getViedoList();
		},
		data() {
			return{
	            videoLists:[], // 获取到的视频列表数组
				posterList: [] ,// 视频封面图数组
			}
		},
		methods: {
			getViedoList(){
				this.$uniReq({
					url:"doc/api/doc's/@freevideo",
					method:"GET",
				}).then((re)=>
					this.videoLists = re
			        this.createPoster();
				}).catch((err)=>{
					console.log(err);
				})
			}
			createPoster() { // 截取封面 封装函数
				var videoCanList = []
				this.videoLists.forEach((item,index) => {
					var promise = new Promise((reslove, reject) => {
						// 在缓存中创建video标签
						var video = document.createElement("VIDEO")
						// 通过setAttribute给video dom元素添加自动播放的属性,因为视频播放才能获取封面图
						video.currentTime = 1; // 截取视频的第1秒
						video.setAttribute('crossOrigin', 'anonymous');
						video.setAttribute('autoplay', 'autoplay')
						// 再添加一个静音的属性,否则自动播放会有声音
						video.setAttribute('muted', 'muted')
						// 上面我们只是创建了video标签,视频播放需要内部的source的标签,scr为播放源
						video.innerHTML = '<source src=' + item.url + ' type="audio/mp4">'
						// 再创建canvas画布标签
						var canvas = document.createElement('canvas');
						var ctx = canvas.getContext('2d');
						// video注册canplay自动播放事件
						video.addEventListener('canplay', function() {
							// 创建画布的宽高属性节点,就是图片的大小,单位PX
							var anw = document.createAttribute("width");
							anw.nodeValue = 500;
							var anh = document.createAttribute("height");
							anh.nodeValue = 300;
							canvas.setAttributeNode(anw);
							canvas.setAttributeNode(anh);
							// 画布渲染
							ctx.drawImage(video, 0, 0, 500, 300);
							// 生成图片
							var base64 = canvas.toDataURL('image/png') // 这就是封面图片的base64编码
							// 视频结束播放的事件
							video.pause()
							reslove(base64)  // promise函数成功的回调
						}, false)
					})
					videoCanList.push(promise)
				})
				Promise.all(videoCanList).then(res => {
					this.posterList = res
				})
			}
		}
	}
</script>

按照上面的代码,其中posterList就是对应的每一个视频的封面base64数组,一切看起来都挺好,在H5正常运行,但是在APP端使用,明显是不可以的,因为在app端,document为undefined,那么怎么弄呢,查阅了资料,发现使用renderjs即可以识别。

<view class='healthPromotion' :videoLists="videoLists" :change:videoLists="renderScript.createPoster"></view>

<script>
	export default {
		onLoad() 
			this.getViedoList();
		},
		data() {
			return{
	            videoLists:[], // 获取到的视频列表数组
				posterList: [] ,// 视频封面图数组
			}
		},
		methods: {
			getViedoList(){
				this.$uniReq({
					url:"doc/api/doc's/@freevideo",
					method:"GET",
				}).then((re)=>
					this.videoLists = re
				}).catch((err)=>{
					console.log(err);
				})
			},
            reciveMessage(val) {
				this.posterList = val
			}
		}
	}
</script>

<script module="renderScript" lang="renderjs">
	export default {
		methods: {
			createPoster(val) {
				var videoCanList = [],curDateList = []
				val.forEach((item,index) => {
					var promise = new Promise((reslove, reject) => {
						// 在缓存中创建video标签
						var video = document.createElement("VIDEO")
						// 通过setAttribute给video dom元素添加自动播放的属性,因为视频播放才能获取封面图
						video.currentTime = 5
						video.setAttribute('crossOrigin', 'anonymous');
						video.setAttribute('autoplay', 'autoplay')
						// 再添加一个静音的属性,否则自动播放会有声音
						video.setAttribute('muted', 'muted')
						// 上面我们只是创建了video标签,视频播放需要内部的source的标签,scr为播放源
						video.innerHTML = '<source src=' + item.url + ' type="audio/mp4">'
						// 再创建canvas画布标签
						var canvas = document.createElement('canvas');
						var ctx = canvas.getContext('2d');
						// video注册canplay自动播放事件
						video.addEventListener('canplay', function() {
							// 创建画布的宽高属性节点,就是图片的大小,单位PX
							var anw = document.createAttribute("width");
							anw.nodeValue = 500;
							var anh = document.createAttribute("height");
							anh.nodeValue = 300;
							canvas.setAttributeNode(anw);
							canvas.setAttributeNode(anh);
							// 画布渲染
							ctx.drawImage(video, 0, 0, 500, 300);
							// 生成图片
							var base64 = canvas.toDataURL('image/png') // 这就是封面图片的base64编码
							// 视频结束播放的事件
							video.pause()
							curDateList.unshift({ // 这里是我自己的数据处理模块
								type: 'video',
								videoUrl: item.url,
								img: base64
							})
							reslove(base64)  // promise函数成功的回调
						}, false)
					})
					videoCanList.push(promise)
				})
				Promise.all(videoCanList).then(res => {
					this.$ownerInstance.callMethod('reciveMessage', res)
				})
			},
		}
	}
</script>


1)当 videoLists变化时,通过 :change:videoLists="renderScript.createPoster"这一段代码, renderjs 中的createPoster被调用
2)renderjs给script传递数据 this.$ownerInstance.callMethod(‘reciveMessage’, res),调用reciveMessage代码,给posterList 赋值

通过上面的方法完成renderjs与常规script的通信,这样就达到了开篇的需求图的封面列表,H5,APP端都可以生成封面图,亲测有效

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值