Chrome插件 - 基于chrome API + RecorderRTC.js实现chrome浏览器右键菜单屏幕录制并保存下载功能

主要技术点

  • chrome 插件(扩展)开发。关于chrome插件开发可参考另一篇文章:chrome扩展-打造个性化的web页面
  • chrome API相关功能,主要用到添加右键菜单功能
  • RecordRTC.js

插件缺点

  • 无法录制声音
  • 由于编码格式,一些播放器无法播放,可以在网页中或者腾讯视频中播放

chrome插件

  • 在任意位置新建一个文件夹,文件夹名称可以任意命名,如:screencapture
  • 进入到该文件夹中并新增3/4个文件,一个html文件,一个json配置文件,一或两个js文件
  • 一个html文件(screencapture.html):用于作为插件的背景页,会在chrome后台一直运行
  • 一个json配置文件(manifest.json):名称必须是manifest.json,用于记录插件的配置信息
  • 一个或两个js文件:之所以说一个或两个是因为RecorderRTC.js文件可以通过cdn的形式引入,也可以下载到本地后在引入,本文中将采用第二种形式实现(即用两个js文件)。

各文件具体代码实现

  • screencapture.html

该文件用于作为chrome插件的背景页,会随着浏览器的打开在chrome后台一直运行,直到浏览器关闭。该页面不会被用户看到,在本文功能录屏功能中仅作为一个承接作用,所以可以不用有具体内容,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Screen Capture</title>
</head>
<body>    
    <script src="RecordRTC.js"></script>
    <script src="capture.js"></script>
</body>
</html>
  • manifest.json

插件的配置文件,这个是必须的也是最重要的,并且名称也必须是manifest.json。本功能涉及到的代码如下:

{
    
    
"name":"capture",//插件名称,可随便定义
"manifest_version":2,//manifest版本值,这个值好像必须是2而且这行代码是必须要有的,否则就会报错。
"version":"1.0.0",//插件版本,可随意定义
"description":"浏览器屏幕录制",//插件描述
"browser_action":{
    
    
    "default_icon":"blackad.png"//插件图标,图片需放在上面新建的文件夹screencapture中
},
"background":{
    
    
	"page":"screencapture.html"//配置插件的背景页
},
"permissions":["contextMenus"],//需要的权限,这里要设置右键菜单
"icons":{
    
    
	"16":"xxx.png"//设置右键菜单中的图标
}
}
  • RecordRTC.js

本文采用下载到本地的方式引用,具体代码可参考CDN:https://cdn.WebRTC-Experiment.com/RecordRTC.js

  • capture.js

主要用于调用RecordRTC.js中的方法。另外就是通过chrome api添加右键菜单。
该功能借鉴了另一位老哥的代码:https://blog.csdn.net/qq_41957257/article/details/100583403
具体实现如下:

let videoStart = false;
let recorder, startMenuId, stopMenuId;

function invokeGetDisplayMedia(success, error){
    
    
	let displayMediaStreamConstraints = {
    
    
		video:{
    
    
			displaySurface: 'monitor',
			logicalSurface: true,
			cursor: 'always'
		}
	}
	displayMediaStreamConstraints = {
    
    
		video: true
	}
	
	if(navigator.mediaDevices.getDisplayMedia){
    
    
		navigator.mediaDevices.getDisplayMedia(displayMediaStreamConstraints).then(success).catch(error);
	}else{
    
    
		navigator.getDisplayMedia(displayMediaStreamConstraints).then(success).catch(error);
	}
}

function capture(callback){
    
    
	invokeGetDisplayMedia(screen => {
    
    
		addStreamStopListener(screen, () => {
    
    });
		callback(screen);
	}, function(error){
    
    
		startContextMenu();
	});	
}

function addStreamStopListener(stream, callback){
    
    
	stream.addEventListener('ended', function(){
    
    
		callback();
		callback = function(){
    
    }
	}, false);
	stream.addEventListener('inactive', function(){
    
    
		callback();
		callback = function(){
    
    }
	}, false);
	stream.getTracks().forEach(function(track){
    
    
		track.addEventListener('ended', function(){
    
    
			callback();
			callback = function(){
    
    }
		}, false);
		track.addEventListener('inactive', function(){
    
    
			callback();
			callback = function(){
    
    }
		}, false);
	});
}

function stopRecordingCallback(){
    
    
	let downloadLink = document.createElement('a');
	downloadLink.href = URL.createObjectURL(recorder.getBlob());
	downloadLink.download = "screencapture.mp4";
	downloadLink.click();
	recorder.screen.stop();
	recorder.destroy();
	recorder = null;
	videoStart = false;
}

function startRecording(){
    
    
	capture(screen => {
    
    
		recorder = RecordRTC(screen, {
    
    type:'video', mimeType:'video/webm; codecs=h264'})
		recorder.startRecording();
		recorder.screen = screen;
		videoStart = true;
	});
	stopContextMenu();
}

function stopRecording(){
    
    
	recorder.stopRecording(stopRecordingCallback);
	startContextMenu();
}

//为了保证一次只能实现一个录制功能,所以这里对右键菜单进行了限制,即开始录屏和结束录屏只能出现其中之一
function startContextMenu(){
    
    
	if(stopMenuId){
    
    
		chrome.contextMenus.remove(stopMenuId);
		stopMenuId = null;
	}
	if(!startMenuId){
    
    
		startMenuId = chrome.contextMenus.create({
    
    
			title:'开始录屏',
			onclick: startRecording
		})
	}	
}

function stopContextMenu(){
    
    
	if(startMenuId){
    
    
		chrome.contextMenus.remove(startMenuId);
		startMenuId = null;
	}
	if(!stopMenuId){
    
    
		stopMenuId = chrome.contextMenus.create({
    
    
			title:'结束录屏',
			onclick: stopRecording
		})
	}
}

startContextMenu();

插件安装

插件的打包和安装非常简单, 有两种方式可实现安装:

  • 在浏览器地址栏里输入chrome://extensions回车或者是点浏览器右上角的三个点->更多工具->扩展程序就会打开chrome扩展页面,这里会列出所有已安装过的插件。
  • 在打开的插件页面中有个开发者模式复选框,将其勾选上,这时会多出三个按钮:
    • 加载已解压的扩展程序:这个按钮可以直接选到存放manifest.json,js,css,html,png这些文件的文件夹,然后将插件直接安装
    • 打包扩展程序:这按钮用来将已开发好的插件进行打包组后生成一个.crx的文件这个就是打包好的插件。注意在打包时会需要一个.pem私有秘钥文件,如果没有可以为空打包时会自动生成,但是一旦这个文件存在了就必须选上,否则无法打包
    • 立即更新扩展程序:这个按钮用于更新升级已安装过的插件
  • 将上面打包好的crx文件直接拖入到chrom扩展页面中进行安装
  • 或者:通过"加载已解压的扩展程序"按钮选择打包之前的文件夹进行安装。有时候自己开发打包的插件直接拖拽到浏览器时会提示不在插件列表中,也就是说有些版本的浏览器不支持通过拖拽的方式安装自己开发的插件。这时就可以用加载已解压的扩展程序的方式进行安装。如果只有.crx文件时,可以将后缀改为.rar解压后会得到源码文件,然后再通过这种方式安装。

结尾

如此就可以在浏览器中通过右键菜单实现录屏功能了

猜你喜欢

转载自blog.csdn.net/lixiaosenlin/article/details/119110919
今日推荐