H5 Video 截取第一帧 Canvas 动态视频渲染、截取控制

         由于现在的新媒体技术、资源、客户体验、需求等也越来越广、多、高,作为HTML5中较为重要的 新媒体video视频API,也是用得非常之多。

           比如之前有个项目要在微信中做直播(半屏)播放(rtmp, m3u8等视频流),在IOS手机还好(听说ios手机微信没那么大的操控权限),而在Android手机下(Android系统毕竟是开源产品), 只要在微信X5内核浏览器中播放视频 就会自动全屏,而且z-index层级也是最高的(当然以qq.什么的域名的视频就不全屏,这是腾讯自已的东西,爱怎么搞就怎么搞咯!

我们第三方开发者也没办法,后来他们又搞了一个同层策略 在video标签中加上 x5-video-player-type="h5" 属性,然而还是有一堆这那样的问题),然后不能发东西,打字聊天等【如有朋友已经解决的情况下,还请多多指教,在此先谢过了!!!】, 还有前两天有个项目就用到了, 其中有个需求就是要获取html5的video视频第一帧作为播放前的图片,还有自定义控制相关播放按扭等等。

           所以就和大家一起分享。如有更好解决办法的朋友,欢迎指导!

代码如下:

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>video获取第一帧</title>
		<style type="text/css">
			html, body{ width: 100%; height: 100%; text-align: center;}
			li{ position: relative; display: inline-block; list-style: none;}
			canvas, img{ width: 600px; height: 350px; border: 1px solid darkgray;}
			button{ padding: 6px 20px; margin: 6px 3px;}
			h3{color: red;}
		</style>
	</head>

	<body>
		<header>
			<video id="video" src="./video.mp4" controls width="600" height="400" loop ></video>
			<p>视频播放器-VIDEO</p>
		</header>
		
		<section>
			<ul>
				<li>
					<img id="rendering-img" class="img" crossOrigin="anonymous" />
					<p>获取当前帧到-IMG</p>
				</li>
				<li>
					<canvas id="canvas" class="canvas" ></canvas>
					<p>视频同步渲染到-CANVAS</p>
				</li>
			</ul>
		</section>
	
		<footer>
			<button id="video-play-btn">视频播放</button>
			<button id="video-pause-btn">视频暂停</button>
			<button id="video-volumed-btn">音量增大</button>
			<button id="video-volumex-btn">音量减小</button>
			<button id="fullscreen-btn">视频全屏</button>
			<button id="get-current-btn">获取当前视频帧</button>
			<button id="rendering-btn">视频同步渲染</button>
			<button id="body-bg-btn">渲染到body背景</button>
		</footer>

		<h3>注:请服务器中运行才有效果哦,如用:WampServer64环境将代码放在 www 目录下,如用phpStudy工具将站点目录指到这个文件!</h3>
	</body>

	<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js" type="text/javascript" charset="utf-8"></script>
	
	<script type="text/javascript">
		(function() {

			var video = document.getElementById("video");
			var canvas = document.getElementById("canvas");
			var interval1 = interval2 = null;
			
			//截取视频画面
			var CaptureFirstFrame = function() {
				
				this.saveImageInfo = function() {
					console.log('base64图片:', canvas.toDataURL("image/png"))
				}  

			};
			
			//打开全屏方法
		    CaptureFirstFrame.prototype = {
				CaptureVideo: function (img, rsy, bbg) {
				//canvas 缩放比率
				this.scale = 1;

				//创建canvas元素
				this.cvs = document.createElement("canvas");

				//设置canvas画布大小
				this.cvs.width = canvas.width = video.videoWidth * this.scale;
				this.cvs.height = canvas.height = video.videoHeight * this.scale;

				//设置canvas画布内容、位置
				this.cvs.getContext('2d').drawImage(video, 0, 0, this.cvs.width, this.cvs.height);
					//注:
					/*
					 * canvas.toDataURL("image/png", 1) 方法可能会出错!!!
					 * 因为 【 如果视频文件所在的 域 和 当前index.html页面所在域不同,就会出现跨域传输的问题】,【及便是给img标签加上crossOrigin': 'anonymous' 也没用!】
					 * 所以 请将 视频文件 和 当前index.html页面放在同一个域中,并在服务器中打开(用phpStudy工具等),才能正常运行。
					 */
					
					if (img) {
						$('#rendering-img').attr({ 'crossOrigin': 'anonymous', 'src': this.cvs.toDataURL("image/png", 1) });
					};

					if (rsy) {
						canvas.getContext('2d').drawImage(video, 0, 0, this.cvs.width, this.cvs.height);
					};

					if (bbg) {
						$(document.body).css('background-image', 'url(' + this.cvs.toDataURL("image/png", 1) + ')');
					};
				},

				//全屏
			 	openFullscreen: function (element) {
					if (element.requestFullscreen) {
						element.requestFullscreen();
					} else if (element.mozRequestFullScreen) {
						element.mozRequestFullScreen();
					} else if (element.msRequestFullscreen) {
						element.msRequestFullscreen();
					} else if (element.webkitRequestFullscreen) {
						element.webkitRequestFullScreen();
					}
				}
		    };
		    
		    var V = new CaptureFirstFrame();
			
			//监听视频加载完成时 获取第一帧
			video.addEventListener('loadeddata', function() {
				V.CaptureVideo(true);
			}, false);

			//监听视频播放时
			video.addEventListener('play', function() {
				//播放时
			}, false);
			
			//监听视频暂停时
			video.addEventListener('pause', function() {
				clearInterval(interval1);
				clearInterval(interval2);
			}, false);
			
			//视频播放
			document.getElementById("video-play-btn").addEventListener('click', function() {
				video.play();
			}, false);
			
			//视频暂停
			document.getElementById("video-pause-btn").addEventListener('click', function() {
				video.pause();
			}, false);
			
			//音量增大
			document.getElementById("video-volumed-btn").addEventListener('click', function() {
				(video.volume > 1 || video.volume == 1) ? video.volume = 1 : video.volume = video.volume + 0.1;
			}, false);
			
			//音量增大
			document.getElementById("video-volumex-btn").addEventListener('click', function() {
				(video.volume < 0.2 || video.volume == 0) ? video.volume = 0 : video.volume = video.volume - 0.1;
			}, false);
			
			//视频全屏
			document.getElementById("fullscreen-btn").addEventListener('click', function() {
				V.openFullscreen(video);
			}, false);
			
			//获取当前帧
			document.getElementById("get-current-btn").addEventListener('click', function() {
				V.saveImageInfo();
				V.CaptureVideo(true);
			}, false);
			
			//渲染到cnavas
			document.getElementById("rendering-btn").addEventListener('click', function() {

				clearInterval(interval1);
				interval1 = window.setInterval(function() {
					V.CaptureVideo(false, true);
				}, 1000/60);
				//window.requestAnimationFrame();
			}, false);
			
			//渲染到body背景
			document.getElementById("body-bg-btn").addEventListener('click', function() {
				clearInterval(interval2);
				interval2 = window.setInterval(function() {
					V.CaptureVideo(false, false, true);
				}, 1000/60);
			}, false);
			
		})();
		
	</script>
</html>

 

问题提示:

Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

经过查阅和分析,发现这个其实是由于视频文件所在的域和图片和页面所在域不同,出现跨域传输的问题。



解决方案:

因为: 【 如果视频文件所在的 域 和 当前index.html页面所在域不同,就会出现跨域传输的问题】,【及便是给img标签加上crossOrigin': 'anonymous' 貌似也没用!】。


所以: 请将 视频文件 和 当前index.html页面放在同一个域中,并在服务器中打开(用phpStudy工具等),才能正常运行。

 

 

 

 

 

 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值