本文通过使用webrtc、dom监听、使用插件三种方式实现截屏,使用webrtc、dom监听来实现录屏

  1. 使用webrtc实现截屏录屏

①实现录屏

// 音频或视频流
let mediaStreamTrack = null;
// 录制器
let mediaRecorder = null;/*** @description: 开启屏幕录制,异步返回录制数据* @author: flyer* @param {Function} onstart 开启录制回调* @param {Function} onstop 关闭录制回调*/
const startMedia = (onstart, onstop) => {return new Promise((resolve, reject) => {if (!isObjEmpty(typeof navigator.mediaDevices)) {// eslint-disable-next-line no-undefconst controller = new CaptureController();navigator.mediaDevices.getDisplayMedia({ audio: true, preferCurrentTab: true,controller }).then(stream => {mediaStreamTrack = stream;stream.oninactive = () => {stopMedia();};mediaRecorder = new MediaRecorder(stream, {audioBitsPerSecond: 1280000, //音频码率videoBitsPerSecond: 8500000000, //视频码率 (数值越大视频越清晰)mimeType: 'video/webm;codecs=h264' //视频编码格式});mediaRecorder.start();mediaRecorder.ondataavailable = e => {const blob = new Blob([e.data], {type: 'video/mp4'});resolve(blob);};mediaRecorder.onerror = e => {reject(e);};mediaRecorder.onstart = e => {if (typeof onstart !== 'function') {return;}onstart(e);};mediaRecorder.onstop = e => {if (typeof onstop !== 'function') {return;}onstop(e);};}).catch(err => {reject(err);});} else {reject('该浏览器不支持屏幕录制');}});
};/*** @description: 关闭屏幕录制* @author: flyer*/
const stopMedia = () => {if (!mediaStreamTrack || !mediaRecorder) return;mediaStreamTrack.getTracks().forEach(track => {track.stop();});mediaRecorder.stop();
};

②实现截屏

通过webrtc获取屏幕录制的第一帧实现截屏功能,为了能实现涂鸦功能,我们引入js-web-screen-shot开源插件

npm i js-web-screen-shot --save

使用代码

/*** @description: 开始截屏* @author: flyer* @param {object} param 传入配置,配置地址可见 https://www.npmjs.com/package/js-web-screen-shot*/
const shotScreen = (param = {}) => {return new Promise((resolve, reject) => {// 截图确认按钮回调函数const callback = base64 => {resolve(base64);};// 截图取消时的回调函数const closeFn = () => {console.log('截图窗口关闭');};if (!isObjEmpty(typeof navigator.mediaDevices)) {new ScreenShot({...{enableWebRtc: true,completeCallback: callback,closeCallback: closeFn,clickCutFullScreen: true,showScreenData: true,wrcReplyTime: 500,loadCrossImg: true,level: 999999},...param});} else {reject('该浏览器不支持截屏');}});
};
  1. 使用dom监听实现截屏录屏

①实现录屏

除了使用浏览器自带的webrtc以外,我们可以通过监听dom变化实现截屏和录屏,方便起见直接使用开源插件rrweb,由于得到的数据是dom层变化的JSON数据并非文件流,因此我们还需要使用rrweb-player来播放JSON

npm i rrweb-player rrweb --save

使用代码

import rrwebPlayer from 'rrweb-player';
import 'rrweb-player/dist/style.css';
import * as rrweb from 'rrweb';// rrweb数据
let mediaEvents = [];/*** @description: 通过rrweb开启屏幕录制* @author: flyer*/
const startByRrweb = () => {rrweb.record({/** 订阅事件监听,必需字段 */emit(event) {mediaEvents.push(event);}});
};/*** @description: rrweb关闭屏幕录制* @author: flyer*/
const stopByRrweb = () => {return new Promise(resolve => {rrweb.record({emit() {resolve(mediaEvents);mediaEvents = []}});});
};/*** @description: rrweb开始播放* @author: flyer* @param {Array<object>} events 播放数据* @param {HTMLElement} dom 播放器放置的dom层*/
const playByRrweb = (events, dom = document.body) => {new rrwebPlayer({target: dom, // 可以自定义 DOM 元素props: {events}});
};

②实现截屏,正常来说实现dom截屏我们可以使用三方开源插件html2canvas,若是需要加入涂鸦功能,我们可以使用js-web-screen-shot插件

npm i js-web-screen-shot html2canvas --save

代码

import ScreenShot from 'js-web-screen-shot';
import html2canvas from 'html2canvas';
  1. 使用niuniu插件实现截屏

①去牛牛截图官网下载web端插件,安装在电脑上

②加入以下官方提供代码

var emPensize = 1; //设置画笔大小
var emDrawType = 2; //设置是腾讯风格还是360风格 0: 腾讯风格   1: 360风格
var emTrackColor = 3; //自动识别的边框的颜色
var emEditBorderColor = 4; //文本输入的边框颜色
var emTransparent = 5; //工具栏的透明度
var emSetSaveName = 8; //设置保存时的开始文字     免费版本无效
var emSetMagnifierLogoText = 10; //设置放大镜上的LOGO字符,可提示快捷键,如: 牛牛截图(CTRL + SHIFT + A)     免费版本无效
var emSetWatermarkPictureType = 20; //设置水印的类型
var emSetWatermarkPicturePath = 21; //设置水印的路径
var emSetWatermarkTextType = 22; //设置水印文字的类型
var emSetWatermarkTextValue = 23; //设置水印文字的字符串
var emSetMosaicType = 24; //指定马赛克的类型,1为矩形,2为画线
var emSetTooltipText = 25; //用于设置工具栏图标的TOOLTIP文字
var emSetMoreInfo = 26; //设置额外的信息,用于特殊需求
/******************************************************************************/
var emClosed = 1;
var emConnected = 2;
var emConnecting = 3;var emCaptureSuccess = 0;
var emCaptureFailed = 1;
var emCaptureUnknown = 2;
function isMacintosh() {return navigator.platform.indexOf('Mac') > -1;
}
function isLinux() {return navigator.platform.indexOf('Linux') > -1;
}
function rgb2value(r, g, b) {return r | (g << 8) | (b << 16);
}function NiuniuCaptureObject() {var self = this;this.PenSize = 2;this.DrawType = 0;this.TrackColor = rgb2value(255, 0, 0);this.EditBorderColor = rgb2value(255, 0, 0);this.Transparent = 255;this.WindowAware = 1;this.MosaicType = 1;this.SaveName = '测试保存';this.MagnifierLogoText = '测试截图';this.WatermarkPictureType = '2|100|100|400|400|20';this.WatermarkPicturePath = '';this.WatermarkTextType = '2|100|100|100|40|20|0|150|30|80,55,55,55';this.WatermarkTextValue = '';this.NiuniuAuthKey = '';this.ToolTipText = '测试一下'; //tipRectangle|tipCircle|tipArrow|tipBrush|tipGlitter|tipMosaic|tipText|tipUndo|tipSave|tipCancel|tipFinish|txtFinishthis.MoreInfo = '1,100|300|600';this.More_Ext_Params = new Array();this.useCustomizedProtoco = true; //是否使用浏览器自定义协议加websocketthis.IsWaitCustomizedCallBack = false;this.autoConnectAfterPageLoad = true;this.IsFirstConnect = true;this.IsEverConnected = false;this.reconnectTryTime = 0;this.TimeIntervalID = -1;this.ReceivedEchoBack = false;this.Version = '1.0.0.0';this.hostPort = '30101,30102';this.hostPortIndex = 0;this.CaptureName = 'NiuniuCapture';this.NiuniuSocket = null;this.connectState = emClosed;this.SocketTimeStamp = new Date().getTime();this.TimeOutID = -1;this.FinishedCallback = null;this.PluginLoadedCallback = null;this.VersionCallback = null;this.OnConnectFailed = function (isReconnect) {self.WriteLog(isReconnect ? 'reconnect failed, the capture control process is exit.' : 'connect failed at the first time.');};this.LoadPlugin = function () {};this.niuniuCapture = function () {return document.getElementById('niuniuCapture');};this.addEvent = function (obj, name, func) {if (obj.attachEvent) {obj.attachEvent('on' + name, func);} else {obj.addEventListener(name, func, false);}};this.pluginValid = function () {try {if (self.niuniuCapture().valid) {return true;}} catch (e) {}return false;};this.OnCaptureFinished = function (x, y, width, height, content, localpath) {self.OnCaptureFinishedEx(1, x, y, width, height, '', content, localpath);};this.OnCaptureFinishedEx = function (type, x, y, width, height, info, content, localpath) {//交给上层去处理截图完成后的事项if (self.FinishedCallback != null) {self.FinishedCallback(type, x, y, width, height, info, content, localpath);} else {alert('截图完成的事件未绑定,将不能对图片进行处理,请指定FinishedCallback回调函数');}};this.pluginLoaded = function (fromWebsocket) {if (!fromWebsocket && !self.pluginValid()) {if (self.PluginLoadedCallback != null) {self.PluginLoadedCallback(false);}return false;}self.GetVersion();if (self.PluginLoadedCallback != null) {self.PluginLoadedCallback(true);}if (!self.pluginValid()) {return false;}//此函数必需调用,传递正确的参数,且必需先于其他函数调用self.niuniuCapture().InitCapture(self.NiuniuAuthKey);self.niuniuCapture().InitParam(emPensize, self.PenSize);self.niuniuCapture().InitParam(emDrawType, self.DrawType);self.niuniuCapture().InitParam(emTrackColor, self.TrackColor);self.niuniuCapture().InitParam(emEditBorderColor, self.EditBorderColor);self.niuniuCapture().InitParam(emTransparent, self.Transparent);self.niuniuCapture().InitParam(emSetSaveName, self.SaveName);self.niuniuCapture().InitParam(emSetMagnifierLogoText, self.MagnifierLogoText);self.niuniuCapture().InitParam(emSetMosaicType, self.MosaicType);//设置工具栏上的按钮TOOLTIPself.niuniuCapture().InitParam(emSetTooltipText, self.ToolTipText);//self.niuniuCapture().InitParam(emSetMoreInfo, self.MoreInfo);for (i = 0; i < self.More_Ext_Params.length; i++) {self.niuniuCapture().InitParam(emSetMoreInfo, self.More_Ext_Params[i]);}//niuniuCapture().InitParam(23, "测试文字.");//此BASE64字符串表示牛牛默认的水印图片,可以替换niuniuCapture().InitParam(21,'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');//注:以上设置LOGO及保存名的接口,免费版本无效//添加控件的事件监听self.addEvent(self.niuniuCapture(), 'CaptureFinishedEx', self.OnCaptureFinishedEx);//以下这个事件主要是用于兼容旧的浏览器控件的事件通知self.addEvent(self.niuniuCapture(), 'CaptureFinished', self.OnCaptureFinished);};this.SetWatermarkPicture = function (watermarPicData) {self.WatermarkPicturePath = watermarPicData;//设置测试的水印图片的Base64字符串,此操作应该是在页面加载中处理比较合适if (!self.pluginValid()) {return;}self.niuniuCapture().InitParam(emSetWatermarkPicturePath, self.WatermarkPicturePath);self.niuniuCapture().InitParam(emSetWatermarkPictureType, self.WatermarkPictureType);};this.SetWatermarkText = function (watermarkText) {self.WatermarkTextValue = watermarkText;//设置测试的水印文字,此操作应该是在页面加载中处理比较合适if (!self.pluginValid()) {return;}//nShowType|nMinWidth|nMinHeight|nVerticalInterval|nOffset|nFontSize|nIsBold|nTextWidth|nTextHeight|colorTextself.niuniuCapture().InitParam(emSetWatermarkTextValue, self.WatermarkTextValue);self.niuniuCapture().InitParam(emSetWatermarkTextType, self.WatermarkTextType);};this.SavePicture = function (savename) {if (self.pluginValid()) {self.niuniuCapture().SavePicture(savename);}};this.GetCursorPosition = function () {if (self.pluginValid()) {var val = self.niuniuCapture().GetCursorPosition();return val;}return '';};this.NewCaptureParamObject = function (defaultpath, hideCurrWindow, autoCaptureFlag, x, y, width, height) {var obj = new Object();obj.CmdType = 1;obj.IsGBK = 0; //是否是GBK编码,这样会涉及到编码转换obj.AuthKey = self.NiuniuAuthKey; //obj.Pensize = self.PenSize; //设置画笔大小obj.DrawType = self.DrawType; //设置是腾讯风格还是360风格obj.TrackColor = self.TrackColor; //自动识别的边框的颜色obj.EditBorderColor = self.EditBorderColor; //文本输入的边框颜色obj.Transparent = self.Transparent; //工具栏的透明度obj.SetSaveName = self.SaveName; //设置保存时的开始文字obj.SetMagnifierLogoText = self.MagnifierLogoText; //设置放大镜上的LOGO字符obj.SetWatermarkPictureTypeEx = self.WatermarkPictureType; //设置水印的类型obj.SetWatermarkPicturePath = self.WatermarkPicturePath; //设置水印的路径obj.SetWatermarkTextTypeEx = self.WatermarkTextType; //设置水印文字的类型obj.SetWatermarkTextValue = self.WatermarkTextValue; //设置水印文字obj.MosaicType = self.MosaicType; //设置马赛克的类型obj.SetToolbarText = self.ToolTipText;obj.MoreInfo = this.MoreInfo;if (self.More_Ext_Params.length > 0) {obj.more_ext_count = self.More_Ext_Params.length;for (i = 0; i < self.More_Ext_Params.length; i++) {switch (i) {case 0:obj.more_ext0 = self.More_Ext_Params[i];break;case 1:obj.more_ext1 = self.More_Ext_Params[i];break;case 2:obj.more_ext2 = self.More_Ext_Params[i];break;case 3:obj.more_ext3 = self.More_Ext_Params[i];break;case 4:obj.more_ext4 = self.More_Ext_Params[i];break;case 5:obj.more_ext5 = self.More_Ext_Params[i];break;case 6:obj.more_ext6 = self.More_Ext_Params[i];break;case 7:obj.more_ext7 = self.More_Ext_Params[i];break;case 8:obj.more_ext8 = self.More_Ext_Params[i];break;case 9:obj.more_ext9 = self.More_Ext_Params[i];break;}}}//以下是截图时传递的参数obj.DefaultPath = defaultpath;obj.HideCurrentWindow = hideCurrWindow;obj.AutoCaptureFlag = autoCaptureFlag;obj.x = x;obj.y = y;obj.Width = width;obj.Height = height;return obj;};this.DoCapture = function (name, hide, AutoCapture, x, y, width, height) {if (self.IsNeedCustomizedProtocol()) {return self.DoCaptureForCustomize(name, hide, AutoCapture, parseInt(x), parseInt(y), parseInt(width), parseInt(height));}if (!self.pluginValid()) {return emCaptureFailed;}self.niuniuCapture().Capture(name, hide, AutoCapture, x, y, width, height);return emCaptureSuccess;};this.InitNiuniuCapture = function () {self.LoadPlugin();setTimeout(self.InitWebSocketAndBindCallback(), 200);};this.InitWebSocketAndBindCallback = function () {if (!self.autoConnectAfterPageLoad || !self.IsNeedCustomizedProtocol()) {return;}self.connectHost();};this.getNextPort = function () {//init port params flag//进行拆分处理 self.hostPort;var portArray = self.hostPort.split(',');if (portArray.length < 1) {alert('服务端口为空');return 30101;}if (self.hostPortIndex < 0) {self.hostPortIndex = 0;}if (self.hostPortIndex > portArray.length - 1) {self.hostPortIndex = portArray.length - 1;}var nPort = parseInt(portArray[self.hostPortIndex]);self.hostPortIndex++;if (self.hostPortIndex > portArray.length - 1) {self.hostPortIndex = 0;}return nPort;};this.connectHost = function () {if (self.NiuniuSocket != null) {self.WriteLog('connectHost NiuniuSocket is not null, return.');return;}clearTimeout(self.TimeOutID);self.connectState = emConnecting;try {var wshosts = ['127.0.0.1', 'localhost'];for (var i in wshosts) {try {var host = 'ws://127.0.0.1:' + self.getNextPort() + '/' + self.CaptureName;self.NiuniuSocket = new WebSocket(host);break;} catch (ee) {var ggg = 0;}}//OutputLog('Socket Status: '+socket.readyState);self.NiuniuSocket.onopen = function (evt) {self.NiuniuSocket.send('0' + self.SocketTimeStamp);self.WriteLog('NiuniuSocket.onopen.');clearTimeout(self.TimeOutID);};self.NiuniuSocket.onmessage = function (msg) {var str = '';str = msg.data;var id = str.substr(0, 1);var arg1 = str.substr(1);clearTimeout(self.TimeOutID);if (id == '0') {self.hostPortIndex--;//表示连接成功,此时应该提示可以截图了self.connectState = emConnected;self.pluginLoaded(true);self.IsEverConnected = true;self.IsFirstConnect = false;if (self.IsWaitCustomizedCallBack) {setTimeout(self.SendReadyRecvData(), 3);}self.WriteLog('connect sucess.');self.ReceivedEchoBack = true;clearInterval(self.TimeIntervalID);self.TimeIntervalID = setInterval(self.LoopEchoMessage(), 3000);}if (id == '1') {//解析消息var _aoResult = eval('(' + arg1 + ')');self.ReceivedEchoBack = true;if (_aoResult.command == 'echo') {self.WriteLog('received echo');return;}self.WriteLog('received capturedata.');if (_aoResult.command == 'version') {self.WriteLog(_aoResult.Ver);self.VersionCallback(_aoResult.Ver);} else {self.OnCaptureFinishedEx(_aoResult.Type,_aoResult.x,_aoResult.y,_aoResult.Width,_aoResult.Height,_aoResult.Info,_aoResult.Content,_aoResult.LocalPath);}}};self.NiuniuSocket.onclose = function (evt) {self.OnWebSocketError('self.NiuniuSocket.onclose.' + evt.data);};self.NiuniuSocket.onerror = function (evt) {//self.OnWebSocketError("self.NiuniuSocket.onerror." + evt.data);};} catch (e) {self.OnWebSocketError('connect exception.' + e.message);}};this.WriteLog = function (txt) {//写日志try {// console.log(txt);} catch (e) {}};this.OnWebSocketError = function (type) {//如果不处于连接成功状态,说明不是断开连接,而是连接失败var isConnectedFailed = false;if (self.connectState != emConnected) {isConnectedFailed = true;}self.WriteLog(type);self.ReceivedEchoBack = false;self.connectState = emClosed;if (self.NiuniuSocket != null) {self.NiuniuSocket.close();}self.NiuniuSocket = null;clearTimeout(self.TimeOutID);clearInterval(self.TimeIntervalID);if (isConnectedFailed) {if (self.IsFirstConnect) {self.IsFirstConnect = false;if (self.OnConnectFailed != null) {self.OnConnectFailed(false);}return;}if (self.IsEverConnected) {self.reconnectTryTime++;//通知连接连接断开if (self.reconnectTryTime > 3) {self.IsEverConnected = false;self.reconnectTryTime = 0;if (self.OnConnectFailed != null) {self.OnConnectFailed(true);}return;}}}self.TimeOutID = setTimeout(self.connectHost(), 800);};this.LoopEchoMessage = function () {if (!self.ReceivedEchoBack) {self.OnWebSocketError('this.LoopEchoMessage, !self.ReceivedEchoBack');self.ReceivedEchoBack = false;clearInterval(self.TimeIntervalID);self.TimeIntervalID = setInterval(self.LoopEchoMessage(), 3000);return;}self.ReceivedEchoBack = false;clearTimeout(self.TimeOutID);if (self.connectState != emConnected) {clearInterval(self.TimeIntervalID);return;}var obj = new Object();obj.command = 'echo';self.NiuniuSocket.send('1' + encodeURIComponent(JSON.stringify(obj)));};this.SendReadyRecvData = function () {self.WriteLog('SendReadyRecvData.');var obj = self.NewCaptureParamObject('', 0, 0, 0, 0, 0, 0);obj.CmdType = -1;self.NiuniuSocket.send('1' + encodeURIComponent(JSON.stringify(obj)));};this.DoCaptureForCustomize = function (name, hide, AutoCapture, x, y, width, height) {var obj = self.NewCaptureParamObject(name, hide, AutoCapture, x, y, width, height);try {//启动客户端,或者通过websocket去发送数据if (self.connectState == emConnected) {var json = JSON.stringify(obj);self.NiuniuSocket.send('1' + encodeURIComponent(json));} else {//首次启动时,不支持水印,否则会过长obj.SetWatermarkPicturePath = '';//obj.SetWatermarkTextValue = "";var json = JSON.stringify(obj);self.WriteLog(json.length);var newUrl = self.CaptureName + '://' + encodeURIComponent(json);if (isLinux()) {newUrl = self.CaptureName + '://xxxx';}self.WriteLog(newUrl.length);//启动客户端document.location.href = newUrlself.IsWaitCustomizedCallBack = true;self.connectHost();return emCaptureUnknown;}return emCaptureSuccess;} catch (e) {alert(e.message);}return emCaptureUnknown;};this.IsNeedCustomizedProtocol = function () {if (isMacintosh()) {return true;}if (!self.useCustomizedProtoco) {return false;}if (self.pluginValid()) {return false;}try {var agent = window.navigator.userAgent.toLowerCase();var isIE = agent.indexOf('compatible') > -1 && agent.indexOf('msie') > -1;if (isIE) {return false;}var isIE11 = agent.indexOf('trident') > -1 && agent.indexOf('rv:11.0') > -1;if (isIE11) {return false;}var isQQBrowser = agent.indexOf('qqbrowser') != -1;//if(isQQBrowser)//{//    return false;//}var isUBrowser = agent.indexOf('ubrowser') != -1;if (isUBrowser) {return false;}//如果是firefox 且在50版本以上,则需要var isFirefox = agent.indexOf('firefox') != -1;if (isFirefox) {return true;}var isEdge = agent.indexOf('edge') != -1;if (isEdge) {return true;}var isChrome = agent.indexOf('chrome') != -1;if (isChrome) {return true;}return false;} catch (e) {self.WriteLog('IsNeedCustomizedProtocol exception: ' + e.message);}return true;};this.GetVersion = function () {if (self.IsNeedCustomizedProtocol()) {if (self.connectState != emConnected) {return;}var obj = new Object();obj.command = 'version';self.NiuniuSocket.send('1' + encodeURIComponent(JSON.stringify(obj)));return;}if (!self.pluginValid()) {return;}var verSion = self.niuniuCapture().GetVersion();self.VersionCallback(verSion);self.WriteLog(verSion);};
}

③添加startCapture方法,callback回调函数中返回的就是截出来的图片数据

/*** @description: 使用牛牛插件截屏* @author: flyer* @param {Function} callBack 截屏回调函数* @param {object} params 截屏参数*/
const startCapture = (callBack,params = {}) => {let captureObj = new NiuniuCaptureObject();captureObj.NiuniuAuthKey = 'niuniu';//此处可以设置相关参数captureObj.TrackColor = niuniuJs.rgb2value(255, 0, 0);captureObj.EditBorderColor = niuniuJs.rgb2value(0, 0, 255);//设置控件加载完成以及截图完成的回调函数captureObj.FinishedCallback = (type, x, y, width, height, extinfo, content, localpath) => {callBack(type,content, localpath)};captureObj.PluginLoadedCallback = () => {};captureObj.VersionCallback = () => {};captureObj = {...captureObj,...params}//初始化控件captureObj.InitNiuniuCapture();captureObj.DoCapture('1.jpg', false, 0, 0, 0, 0, 0);
}

多种方式实现web端截屏录屏相关推荐

  1. webrtc性能优化:MacOS下的快速截屏录屏方式

    截屏和录屏现在已经变成了各个系统中最最基础的功能了,特别是直播的兴起和疫情促进的会议系统,诸如远程办公,都会使用到系统录屏的功能,录屏的快慢又决定了我们直播和会议的流畅程度. 最近各个大厂商也推出了很 ...

  2. airtest web 录制滑块_Airtest 录屏总结,这不是一个简单的 recording!

    此文章来源于项目官方公众号:"AirtestProject" 版权声明:允许转载,但转载必须保留原链接:请勿用作商业或者非法用途 前言 经常有同学过来问如何在脚本运行的过程中进行录 ...

  3. DXGI快速截屏录屏技术

    DXGI快速截屏录屏技术 概述   很多地方都需要用到截屏/录屏技术,比如桌面直播,桌面录制等等.在微软Windows平台,有很多截屏的接口,不过大多数性能并不理想,Windows8以后微软引入了一套 ...

  4. Win10怎么截屏录屏?Win10截图方法大全 超强大的工具!

    转载自奇它博客,原文链接:[http://qitablog.com/tips/win10怎么截屏录屏?win10截图方法大全-超强大的工具!.html ‎] [infobox title=" ...

  5. 【Ubuntu20.04】好用的快捷键\截屏录屏

    unbuntu20.04好用的快捷键 快捷键很大程度上决定了一个产品的使用体验,作为一个刚刚接触linux的小白根据自身需求学习了一下在编码过程中ubuntu20.04可能会用到的一些,在这里和大家分 ...

  6. DXGI快速截屏录屏技术,高帧率直播桌面

    DXGI快速截屏录屏技术 概述   很多地方都需要用到截屏/录屏技术,比如桌面直播,桌面录制等等.在微软Windows平台,有很多截屏的接口,不过大多数性能并不理想,Windows8以后微软引入了一套 ...

  7. 超便携式截屏录屏软件FastStone Capture

    超便携式截屏录屏软件FastStone Capture 转载于:https://www.cnblogs.com/Renyi-Fan/p/8628196.html

  8. iphone屏幕镜像如何全屏_苹果系统截屏录屏+标记剪辑功能详解( iPhone/iPad/Mac)

    苹果系统中的截屏和录屏.标记和剪辑功能一如它的其他产品设计,做得非常细致.在我们日常的工作中,不免会遇到这些功能,今天小编就给大家详细讲解下苹果系统截屏录屏.标记剪辑功能,希望对大家有所帮助! 001 ...

  9. 截屏录屏软件分享 FSCapture、Snipaste【目前见过的最好用的录屏软件】

    目录 截屏录屏软件--FSCapture 截屏软件--Snipaste-2.4-Beta-x64.zip 截屏录屏软件--FSCapture 使用教程(17:09):https://www.bilib ...

最新文章

  1. Windows Server 2008 多元密码策略之ADSIEDIT
  2. 不懂编程的产品经理如何不被程序员吊打?
  3. 转,数组遍历的三种方式
  4. timertask run函数未执行_图执行模式下的 TensorFlow 2
  5. jquery文档加载完毕后执行的几种写法
  6. java线程并发blockingqueue类使用示例
  7. FastDFS学习总结(1)--FastDFS安装和部署
  8. 程序员以上帝视角解读“旅行青蛙”,你的呱真的在旅行嘛?
  9. python解释器使用函数可以进入帮助系统_使用help()命令可以进入帮助系统。
  10. java 切图_分布式切图服务——切图篇
  11. 软件设计师真题知识点笔记❀
  12. 清华2019最新AI发展报告出炉!400页干货,13大领域一文看懂
  13. 进度猫带你来了解,一个优秀的管理者都有哪些准则
  14. 按头安利 好看又实用的冰淇淋VRay材质球素材看这里
  15. activemq启动错误:ERROR | Temporary Store limit is 51200 mb, whilst the temporary data directory
  16. 彩色图直方图均衡化matlab
  17. [Java]知乎下巴第4集:再把抓到篮子里的知乎塞到硬盘里吧
  18. Myeclipse10完美破解过程
  19. MyBaitsPlus快速入门,java进阶书籍推荐
  20. Spark性能调优案例-优化spark估计表大小失败 和 小表关联 走 broadcast join

热门文章

  1. Apache 日志分类及作用
  2. 整理了一下脑电的资料,(情绪识别,运动想象)
  3. 牛客网基础题-有容乃大
  4. 微信网页版协议的java封装
  5. python代码覆盖率_增量代码覆盖率工具
  6. C#关键字之abstract详解
  7. 新概念2 课文和单词(16)
  8. 新员工试用期月度总结
  9. 关于平均情况困难问题与最坏情况困难问题的理解
  10. vnc连接后没桌子黑屏_vnc win10,vnc远程桌面黑屏只有光标