【音视频工具】前端屏幕录制工具 + 录制<video>标签内容

news2024/11/16 13:57:33

一、录制的实现思路

1.开始录制、停止录制、下载视频

2.Blob介绍

3.概念

var mediaRecord //用于录制视频
var mediaStream //视频流
var videoBuffer = [] //保存的视频数据

二、屏幕录制工具

下载地址:
https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en

https://www.tampermonkey.net/ https://greasyfork.org/en

三、录制标签内容

1.诉求

网页版本的推、拉流页面,含有标签,屏幕录制需要处理很多边角,选择直接录制流内容本身

2.可行性

写一个脚本,作为第三方去监控录制视频流。🉑️
Tampermonkey

3.难点

首先获取到标签

解决:

在这里插入图片描述
在这里插入图片描述

如何触发录制标签?

解决:

  • 网页控制台添加按钮入口,给予点击事件
    在这里插入图片描述
  • Tampermonkey插件控制录制脚本
    在这里插入图片描述

如何存储视频流 ?如何download本地?

解决:

  • 代码逻辑
  1. 要创建一个Canvas,视频标签本身不具备记录图像的功能,所以我们需要通过Canvas来实现这个功能
  2. 创建一个绑定到CanvasStream的记录器,以便记录器可以触发画布绘制的任何东西的回调
  3. 创建一个计时器,通过CanvasContext连续捕捉视频选项卡,然后将其绘制到画布上
  4. 创建一个字节数组,只要画布捕捉到新的屏幕,它就会触发MediaRecorder数据回调,将帧数据获取到数组中
  5. 每个帧数据本身就是一个Blob[]数据结构。所有的Blob数组组合在一起产生一个最终的Blob,这是录制的视频数据
  • 脚本编写
// ==UserScript==
// @name         录制YouTube
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://www.youtube.com/watch?v=vyfJgJBB3Vk
// @icon         https://www.google.com/s2/favicons?sz=64&domain=undefined.localhost
// @grant        none
// ==/UserScript==


(function() {
    'use strict';
    //alert("HHH")
    //document.body.appendChild(document.createElement("canvas"));
    var mc = document.createElement("canvas");
    mc.id="canvas";
    mc.style.cssText="position:absolute;top:0;left:0;z-index:1000000";
    mc.width='720';
    mc.height='540';
    document.body.appendChild(mc);

    var startbtn = document.createElement("button");
    startbtn.id="button-start";
    startbtn.innerHTML="开始录制";
    startbtn.style.cssText="position:absolute;top:120px;left:0;z-index:1000000";
    document.body.appendChild(startbtn);

    var stopbtn = document.createElement("button");
    stopbtn.id="button-stop";
    stopbtn.innerHTML="结束录制"
    stopbtn.style.cssText="position:absolute;top:150px;left:0;z-index:1000000";
    document.body.appendChild(stopbtn);


    let canvasElement = document.querySelector("#canvas");
    let startButton = document.querySelector("#button-start");
    let stopButton = document.querySelector("#button-stop");

    const videoWidth = 720;
    const videoHeight = 540;
    const frameRate = 60;
    const encodeType = "video/webm;codecs=vp8";

    let chunks = [];

    let frameId = null;

    //设置画布背景
    const canvasContext = canvasElement.getContext("2d");
    canvasContext.fillStyle = "deepskyblue";
    canvasContext.fillRect(0, 0, canvasElement.width, canvasElement.height);

    //创建MediaRecorder,设置媒体参数
    const stream = canvasElement.captureStream(frameRate);
    const recorder = new MediaRecorder(stream, {
        mimeType: encodeType
    });

    //收集录制数据
    recorder.ondataavailable = e => {
        chunks.push(e.data);
    };

    //按钮事件
    startButton.disabled = false;
    stopButton.disabled = true;
    startButton.onclick = e => {
        startButton.disabled = true;
        stopButton.disabled = false;
        recorder.start(10);
        drawFrame();
    };
    stopButton.onclick = e => {
        startButton.disabled = false;
        stopButton.disabled = true;
        recorder.stop();
        cancelAnimationFrame(frameId);
        download();
    };

    //播放视频
    function drawFrame() {
        let videoElement = document.getElementsByTagName("video")[0];
        console.log("videoElement",videoElement);
        canvasContext.drawImage(videoElement, 0, 0, videoWidth, videoHeight);
        frameId = requestAnimationFrame(drawFrame);
    }
     //下载录制内容
     function download() {
    let blob = new Blob(chunks);
    let url = window.URL.createObjectURL(blob);
    let link = document.createElement("a");
    link.href = url;
    link.download = new Date().getTime() + ".mp4";
    link.style.display = "none";
    document.body.appendChild(link);
    link.click();
    link.remove();

}
})();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/184722.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

k8s之POD资源限制和健康监测

写在前面 本文一起看下POD的资源限制配置和健康监测的相关内容。 1:资源限制 如果是不对POD设置资源限制的话,若任由其占用系统资源,可能会造成非常严重的后果,所以我们需要根据具体情况来设置资源限制,如使用多少内…

怎样把截图转换成文字?三分钟教会你如何截图转文字

在日常的学习中,当你在网上看到一篇文章,而当中的某一段话很适合拿来用在自己的写作上,但是你却无法直接将其复制粘贴下来,只能先截图下来再手动输入,这种方法虽然可行,但比较消耗时间和精力,那…

详细图解LeetCode经典链表算法题

文章目录链表类型算法题一、链表介绍本文使用的Java中链表类:二、链表基础题1、数组转链表代码:测试:2、单链表翻转题目:代码:解析:测试:补充:3、合并两个有序链表题目:解…

顺应信创发展,君子签电子签章方案全面适配信创环境

信创产业作为战略性新兴产业,近年来,国家不断出台相关政策对行业的发展进行支持。 2018年我国首次将信创纳入国家战略,并提出了 “28N”应用体系,信创发展步入“快车道”;2020年起,信创产业由党政逐渐向其…

垃圾收集器必问系列—ZGC

本文已收录至Github,推荐阅读 👉 Java随想录 人的一切痛苦,本质上都是对自己的无能的愤怒。——王小波 文章目录Region布局读屏障染色指针染色指针的优势运作过程ZGC的优缺点ZGC有人称它为Zero GC,其实“Z”并非什么专业名词的缩写…

vue前端框架课程笔记(二)

目录计算属性问题引入插值语法实现methods配置属性实现computed配置属性一些问题getter与setter注意监视属性问题引入computed和methods实现watch属性watch属性简介computed与watch的比较注意本博客参考尚硅谷官方课程,详细请参考 【尚硅谷bilibili官方】 本博客以…

千峰网络安全笔记(前三讲)

典中典 《c语言从研发到脱发》 《C从入门到放弃》 《Java从跨平台到跨行业》 《Ios开发从入门到下架》 《Android开发大全——从开始到转行》 《PHP由初学至搬砖》 《黑客攻防:从入门到入狱》 《Mysql从删库到跑路》 《服务器运维管理从网络异常到硬盘全红》 《服务器运维管理…

CentOS 8 中dnf管理器如何仅下载不安装软件

在某些情况下,我们希望从命令行下载特定或一组 RPM 包而不安装它。虽然我们可以使用 wget 命令下载,但 wget 不会下载安装包的依赖项。在 CentOS 8 中DNF(或 yum)是一个命令行包管理工具。使用 DNF我们可以安装、更新和删除 rpm 包…

HTTP协议学习

一、http请求协议1、常见请求头accept:浏览器通过这个头告诉服务器,它所支持的数据类型Accept-Charset: 浏览器通过这个头告诉服务器,它支持哪种字符集Accept-Encoding:浏览器通过这个头告诉服务器,支持的压缩格式Accept-Language…

114.简单的动态切换app的图标

1.第一步 通过activity-alias别名实现&#xff0c;manifest 这里写的是一个默认的图标Default和一个需要切换的图标Test&#xff0c;以及一个默认的首页面HomeActivity&#xff1a; <!-- 默认的图标--> <activity-aliasandroid:name".activity.Default"and…

C语言入门教程||C语言 运算符||C语言 判断

C语言 运算符 运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 语言内置了丰富的运算符&#xff0c;并提供了以下类型的运算符&#xff1a; 算术运算符关系运算符逻辑运算符位运算符赋值运算符杂项运算符 本章将逐一介绍算术运算符、关系运算符、逻辑运算符、位运算…

基于android的大学生图书管理系统app

需求信息&#xff1a; 1.学生用户端 查询图书。学生用户可以对馆内图书资料进行简单和高级的查询。 预约图书。当查询时发现要借阅的图书已被借阅&#xff0c;可以提前预约。 挂失图书。图书不慎丢失&#xff0c;可以在学生端实现挂失。 2.管理员端 学生用户管理。管理员可以对…

LeetCode——2309. 兼具大小写的最好英文字母

一、题目 给你一个由英文字母组成的字符串 s &#xff0c;请你找出并返回 s 中的最好英文字母。返回的字母必须为大写形式。如果不存在满足条件的字母&#xff0c;则返回一个空字符串。 最好 英文字母的大写和小写形式必须 都 在 s 中出现。 英文字母 b 比另一个英文字母 a …

Python 操作pdf(pdfplumber读取PDF写入Exce)

1. Python 操作pdf(pdfplumber读取PDF写入Exce) 1.1 安装pdfplumber模块库: 安装pdfplumber: pip install pdfplumber 复制代码 pdfplumber.PDF类 pdfplumber.PDF类表示单个PDF ,并具有两个主要属性: 属性说明pdf.metadata从PDF的Info中获取元数据键/值对字典。通常包括&q…

【HBase——陌陌海量存储案例】4. Apache Phoenix 介绍与安装

5. 性能问题 Hbase默认只支持对行键的索引&#xff0c;那么如果要针对其它的列来进行查询&#xff0c;就只能全表扫描之前介绍的查询是使用scan filter组合来进行查询的&#xff0c;但查询地效率不高&#xff0c;因为要进行顺序全表扫描而没有其他索引。如果数据量较大&#…

51单片机学习笔记-8 DS1302实时时钟

8 DS1302实时时钟 [toc] 注&#xff1a;笔记主要参考B站江科大自化协教学视频“51单片机入门教程-2020版 程序全程纯手打 从零开始入门”。 8.1 芯片介绍&#xff1a;DS1302 RTC(Real Time Clock)实时时钟&#xff0c;是一种集成电路&#xff0c;通常称为时钟芯片。常见的时…

AIGC在营销图片生成技术综述

基于文本生成素材imagen分析用户输入的文本并使用T5-XXL进行编码。嵌入在 AI 中的文本首先被转换为分辨率为64x64像素的小图像。Imagen进一步利用文本条件超分辨率扩散模型对图像进行6464的上采样&#xff0c;然后这个图像继续增长并最终形成。Imagen 的开发者谷歌研究的大脑团…

剑指 Offer 第11天 第12天

目录 剑指 Offer 18. 删除链表的节点 剑指 Offer 22. 链表中倒数第k个节点 剑指 Offer 25. 合并两个排序的链表 剑指 Offer 52. 两个链表的第一个公共节点 剑指 Offer 18. 删除链表的节点 给定单向链表的头指针和一个要删除的节点的值&#xff0c;定义一个函数删除该节点。…

台式电脑怎么连wifi,1分钟轻松弄懂

电脑已经成为了各位小伙伴日常生活中经常会使用的工具。笔记本电脑连接wifi很简单&#xff0c;相信很多小伙伴都会&#xff0c;可是面对台式电脑&#xff0c;很多小伙伴就不知道怎么连wifi了。台式电脑怎么连wifi&#xff1f;别担心&#xff0c;1分钟教你轻松弄懂。 台式电脑怎…

MQ消息队列

mq1、什么是消息队列1.1 MQ基本框架1.2 消息队列的优点1.3 消息队列的缺点1.4 消息队列比对2、RabbitMQ2.1、RabbitMQ如何保证消息不被重复消费2.2、RabbitMQ如何保证消息不丢失2.2.1 生产者丢数据2.2.2 消息队列丢数据2.2.3 消费者丢数据2.3、RabbitMQ如何保证消息有序2.4、Ra…