这里我们用的是webrtc中的MediaDevices.getUserMedia()的欣赏器api进行的结果实现,MediaDevices.getUserMedia() 会提示用户给予使用媒体输入的允许,媒体输入会产生一个MediaStream,里面包罗了哀求的媒体范例的轨道。此流可以包罗一个视频轨道(来自硬件大概虚拟视频源,比如相机、视频采集装备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D 转换器等等),也可能是其他轨道范例。
它返回一个Promise对象,成功后会resolve回调一个MediaStream对象。若用户拒绝了使用权限,大概需要的媒体源不可用,promise会reject回调一个 PermissionDeniedError 大概 NotFoundError 。
代码:
HTML:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>webrtc实现拍照和滤镜</title>
- <link rel="stylesheet" href="./index.css">
- </head>
- <body>
- <div id="container" style="width: fit-content;height: fit-content;position: relative;">
- <video id="video" src=""></video>
- <div id="filter" class="filter"></div>
- </div>
- <select id="select">
- <option value="">无滤镜</option>
- <option value="style1">滤镜1</option>
- <option value="style2">滤镜2</option>
- <option value="style3">滤镜3</option>
- </select>
- <h3>截图展示</h3>
- <button id="snap">截图</button>
- </body>
- <script src="./index.js"></script>
- </html>
复制代码 js:
- //获取视频流
- const constraints = {
- video: {
- width: { min: 300, ideal: 600, max: 900 },
- height: { min: 300, ideal: 600, max: 900 },
- frameRate: { ideal: 60, max: 120 }, //帧率
- }
- }
- navigator
- .mediaDevices
- .getUserMedia(constraints)
- .then(function (stream) {
- const video = document.querySelector('video')
- video.srcObject = stream;
- video.onloadedmetadata = function (e) {
- video.play();
- }
- })
- .catch(function (err) {
- console.log("启动失败", err)
- })
- //设置视频流滤镜
- const video = document.querySelector('.filter')
- const selectVal = document.querySelector('#select')
- selectVal.addEventListener('change', () => {
- video.className = 'filter' // 清空之前的类名
- if (selectVal.value) {
- video.classList.add(selectVal.value) // 添加新的类名
- }
- })
- const snapButton = document.querySelector('#snap');
- snapButton.addEventListener('click', () => {
- const canvas = document.createElement('canvas')
- const video = document.getElementById('video');
- const filterDiv = document.getElementById('filter');
- console.log(video,filterDiv)
- const ctx = canvas.getContext('2d');
- // 设置 Canvas 的宽高与容器相同
- const container = document.getElementById('container');
- canvas.width = container.offsetWidth;
- canvas.height = container.offsetHeight;
- // 绘制视频的当前帧
- ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
- // 绘制滤镜层
- ctx.fillStyle = window.getComputedStyle(filterDiv).backgroundColor;
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- // 导出图像并显示
- const imgData = canvas.toDataURL('image/png');
- const img = document.createElement('img');
- img.src = imgData;
- document.body.appendChild(img);
- })
复制代码 这里留意: 报错为OverconstrainedError时,看一下自己分辨率是否过大
css:
- :root {
- --back-style: unset;
- }
- .filter {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: var(--back-style);
- z-index: 2;
- pointer-events: none;
- }
- .style1 {
- --back-style: rgba(0, 0, 0, 0.2);
- }
- .style2 {
- --back-style: rgba(255, 255, 255, 0.2);
- }
- .style3 {
- --back-style: rgba(0, 0, 255, 0.2);
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |