使用canves画布录制视频,并且将blob文件流转换成base64

<!DOCTYPE html>
<html lang="en">

<head>
	<title>相机测试</title>
	<style>
		* {
			padding: 0;
			margin: 0;
			box-sizing: border-box;
		}

		#camera-video {
			width: 100%;
			height: 100%;
			border: 1px solid #ff5415;
			border-radius: 4px;
		}

		canvas {
			width: 600px;
			height: 300px;
			border: 1px solid #ff5415;
			border-radius: 4px;
			margin-left: 5px;
		}

		.camera-warpper {
			width: 100%;
			height: 100%;
			position: fixed;
		}

		.video-container {
			width: 100%;
			height: 100%;
			background: #000;
			display: flex;
			align-items: center;
			justify-content: center;
			background-image: url("");
			background-repeat: no-repeat;
			background-size: 100% 100%;
			-moz-background-size: 100% 100%;
		}

		.btns {
			padding: 20px 0;
			display: flex;
			align-items: center;
			justify-content: center;
			position: absolute;
			bottom: 75px;
			right: 0;
			z-index: 99;
		}

		.btns>img {
			margin: 0 15px;
		}

		button+button {
			margin-left: 10px;
		}

		/* 视频留言 */
		#videoCard {
			width: 600px;
			height: 300px;
			border: 1px solid #000;
			margin: 0 auto;
			padding: 5px;
		}

		.cardVideoPart {
			border: blue 1px solid;
		}

		/* 选择模板 */
		.templateList {
			width: 100%;
			margin-bottom: 20px;
			display: flex;
			align-items: center;
			justify-content: center;
		}

		.templateCard {
			width: 100px;
			height: auto;
			margin: 10px;
			text-align: center;
		}

		.templateCard>img {
			width: 100%;
			height: 100%;
		}

		#camera-canvas {
			display: none;
		}

		.mask {
			width: 100%;
			height: 100%;
			position: absolute;
			top: 0;
			left: 0;
		}

		.videoTime {
			color: #fff;
			font-size: 36px;
			margin-right: 60px;
		}

		.type2 {
			display: none;
		}

		/* 保存后的弹窗 */
		#endMask {
			width: 100%;
			height: 100%;
			position: absolute;
			top: 0;
			left: 0;
			background: rgba(0, 0, 0, 0.5);
			z-index: 102;
			display: none;
		}

		#endMask>.img {
			width: 1420px;
			height: 714px;
			background: #fff;
			position: absolute;
			top: 50%;
			left: 50%;
			transform: translate(-50%, -50%);
			border: 10px solid #fff;
		}

		#endMask>.img>.imgMask {
			width: 100%;
			height: 100%;
			position: absolute;
			top: 0;
			left: 0;
		}



		#endMask>.img>video {
			width: 100%;
			height: 100%;
		}

		#endMask>.btn {
			position: absolute;
			left: 50%;
			bottom: 40px;
			transform: translate(-50%);
		}
	</style>
</head>

<body>
	<div class="camera-warpper">
		<div class="video-container" id="video-container">
			<video id="camera-video"></video>
			<canvas id="camera-canvas"></canvas>
		</div>
		<!-- 视频模式 -->
		<div class="btns">
			<span class="videoTime type2">录制中:00:20:00</span>
			<!-- 开启摄像 -->
			<img onclick="openCamera()" src="./img/open.png" class="type1" alt="">
			<!-- 录制 -->
			<img onclick="startRecording()" src="./img/videoStart.png" alt="">
			<!-- 停止 -->
			<img onclick="stopAndblobDownload()" class="type2" src="./img/endVideo.png" alt="">
			<!-- 保存 -->
			<img src="./img/savePicture.png" onclick="downloadVideo()" alt="">
			<!-- 退出 -->
			<img src="./img/quit.png" onclick="goHome()" alt="">
		</div>
		<div class="mask">
			<img src="./img/videoBanner.png" alt="">
		</div>
		<!-- 保存后的弹窗 -->
		<div id="endMask">
			<!-- 保存后的宣誓视频 -->
			<div class="img">
				<video src="./img/ceshi.mp4" autoplay muted></video>
				<img class="imgMask" onclick="startVideo()" src="./img/showVideoBanner.png" alt="">
			</div>
			<div class="btn">
				<img src="img/quit.png" onclick="hideEndMask()" alt="">
			</div>
		</div>
	</div>

</body>
<script>
	var type1 = document.getElementsByClassName("type1");
	var type2 = document.getElementsByClassName("type2");
	const config = {
		// video属性设置
		video: {
			width: 600,
			height: 300
		},
		// audio属性设置
		audio: true
	}

	const video = document.getElementById('camera-video');
	const canvas = document.getElementById("camera-canvas");
	var videoContainer = document.getElementById("video-container")
	var ctx = canvas.getContext('2d');
	var img = new Image();
	img.src = "img/pictureBanner.png";
	img.onload = function () {
		drawPicture();
	}

	function drawPicture() {
		ctx.drawImage(img, 0, 0, 1920, 1080);
	}


	/**
	 * 开启摄像
	 */
	function openCamera() {
		navigator.mediaDevices.getUserMedia(config).then(mediaStream => {
			//接收一个mediaStream参数与video标签进行对接
			console.log(mediaStream);
			showType(type2);
			hideType(type1);
			video.srcObject = mediaStream;
			video.play();
		}).catch((err) => {
			console.error(err);
		});
	}

	/**
	 * 拍照、canvas绘制
	 */
	function takePicture() {
		ctx.drawImage(video, 10, 10, config.video.width, config.video.height);
	}

	/**
	 * canvas下载图片
	 */
	function downPhoto() {
		const MIME_TYPE = "image/png";
		const dlLink = document.createElement('a');
		dlLink.download = '测试照片';
		// 图片地址
		dlLink.href = canvas.toDataURL(MIME_TYPE);
		dlLink.dataset.downloadurl = [MIME_TYPE, dlLink.download, dlLink.href].join(':');
		document.body.appendChild(dlLink);
		dlLink.click();
		document.body.removeChild(dlLink);
	}

	// 视频部分
	var allChunks = [];
	const stream2 = video.captureStream(60); // 60 FPS recording
	const recorder = new MediaRecorder(stream2, {
		mimeType: 'video/webm;codecs=vp9'
	});
	recorder.ondataavailable = e => {
		console.log("TCL: e", e)
		allChunks.push(
			e.data
		);
	}
	//end & download
	function stopAndblobDownload() {
		recorder.stop();
	}


	function blobToDataURL(blob, callback) {
		let a = new FileReader();
		a.onload = function (e) {
			callback(e.target.result);
		}
		a.readAsDataURL(blob);
	}



	function downloadVideo() {
		const link = document.createElement('a');
		link.style.display = 'none';
		let fullBlob = new Blob(allChunks);

		blobToDataURL(fullBlob, function (e) {
			console.log("e", e);
		})


		console.log("下载地址", window.URL.createObjectURL(fullBlob));
		const downloadUrl = window.URL.createObjectURL(fullBlob);
		link.href = downloadUrl;
		console.log("href", link.href);
		let str = sessionStorage.getItem("userName")
		link.download = `${str}${Math.random()}.mp4`;
		console.log("最新地址", link);
		document.body.appendChild(link);
		link.click();
		link.remove();
		// 展示签名图
		setTimeout(() => {
			endMask.style.display = "block";
		}, 2000);
	}


	//start  开始录制视频
	function startRecording() {
		recorder.start(10);
	}

	// 返回首页
	function goHome() {
		window.location.href = 'home.html';
	}

	// 按钮切换显示
	showType(type1);

	function showType(type) {
		for (let index = 0; index < type.length; index++) {
			type[index].style.display = "block";

		}
	}

	function hideType(type) {
		for (let index = 0; index < type.length; index++) {
			type[index].style.display = "none";
		}
	}
	// 关闭录制好的视频
	function hideEndMask() {
		endMask.style.display = "none";
	}
</script>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值