no message
This commit is contained in:
162
未命名 (4).html
Normal file
162
未命名 (4).html
Normal file
@@ -0,0 +1,162 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Chrome 原生 API 屏幕录制</title>
|
||||
<style>
|
||||
.control-panel { margin: 20px 0; }
|
||||
button { padding: 8px 16px; margin-right: 10px; cursor: pointer; }
|
||||
#preview { border: 1px solid #ccc; width: 800px; height: 450px; margin: 10px 0; }
|
||||
.status { color: #666; margin: 10px 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="control-panel">
|
||||
<button id="startBtn">开始录制</button>
|
||||
<button id="pauseBtn" disabled>暂停录制</button>
|
||||
<button id="resumeBtn" disabled>继续录制</button>
|
||||
<button id="stopBtn" disabled>停止录制</button>
|
||||
</div>
|
||||
<div class="status" id="status">状态:未开始</div>
|
||||
<video id="preview" autoplay muted></video>
|
||||
|
||||
<script>
|
||||
// 核心变量
|
||||
let mediaStream = null; // 屏幕捕获流
|
||||
let mediaRecorder = null; // 录制器实例
|
||||
let recordedChunks = []; // 录制的视频数据块
|
||||
let isPaused = false; // 录制暂停状态
|
||||
|
||||
// DOM 元素
|
||||
const startBtn = document.getElementById('startBtn');
|
||||
const pauseBtn = document.getElementById('pauseBtn');
|
||||
const resumeBtn = document.getElementById('resumeBtn');
|
||||
const stopBtn = document.getElementById('stopBtn');
|
||||
const preview = document.getElementById('preview');
|
||||
const status = document.getElementById('status');
|
||||
|
||||
// 1. 开始录制:捕获屏幕流 + 初始化录制器
|
||||
startBtn.addEventListener('click', async () => {
|
||||
try {
|
||||
// 步骤1:请求屏幕捕获权限(用户选择录制范围:全屏/窗口/标签页)
|
||||
mediaStream = await navigator.mediaDevices.getDisplayMedia({
|
||||
video: {
|
||||
cursor: 'always', // 显示鼠标光标(可选:never/hidden)
|
||||
frameRate: { ideal: 30, max: 60 } // 录制帧率(理想30帧,最大60帧)
|
||||
},
|
||||
audio: true // 同时捕获系统音频(需浏览器支持,Chrome需开启实验性功能)
|
||||
});
|
||||
|
||||
// 步骤2:绑定流到预览窗口
|
||||
preview.srcObject = mediaStream;
|
||||
|
||||
// 步骤3:初始化 MediaRecorder(指定录制格式为webm,Chrome 默认支持)
|
||||
const options = {
|
||||
mimeType: 'video/webm; codecs=vp9', // 推荐vp9编码(体积小、画质好)
|
||||
// 可选:设置码率(根据需求调整,越高画质越好但体积越大)
|
||||
// videoBitsPerSecond: 2500000 // 2.5Mbps
|
||||
};
|
||||
mediaRecorder = new MediaRecorder(mediaStream, options);
|
||||
|
||||
// 步骤4:监听录制数据(每块数据存入数组)
|
||||
mediaRecorder.ondataavailable = (e) => {
|
||||
if (e.data.size > 0) {
|
||||
recordedChunks.push(e.data);
|
||||
}
|
||||
};
|
||||
|
||||
// 步骤5:监听录制结束(自动下载视频)
|
||||
mediaRecorder.onstop = () => {
|
||||
// 合并数据块为 Blob 视频文件
|
||||
const blob = new Blob(recordedChunks, { type: 'video/webm' });
|
||||
// 生成视频下载链接
|
||||
const videoUrl = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = videoUrl;
|
||||
a.download = `录制视频_${new Date().getTime()}.webm`;
|
||||
a.click();
|
||||
// 释放资源
|
||||
URL.revokeObjectURL(videoUrl);
|
||||
recordedChunks = [];
|
||||
|
||||
// 重置状态
|
||||
resetRecordingState();
|
||||
status.textContent = '状态:录制已停止,视频已下载';
|
||||
};
|
||||
|
||||
// 步骤6:启动录制
|
||||
mediaRecorder.start(1000); // 每1秒生成一个数据块(可选)
|
||||
status.textContent = '状态:正在录制...';
|
||||
|
||||
// 更新按钮状态
|
||||
startBtn.disabled = true;
|
||||
pauseBtn.disabled = false;
|
||||
stopBtn.disabled = false;
|
||||
|
||||
// 监听流结束(用户手动关闭捕获窗口)
|
||||
mediaStream.getTracks().forEach(track => {
|
||||
track.addEventListener('ended', () => {
|
||||
if (mediaRecorder.state !== 'inactive') {
|
||||
mediaRecorder.stop();
|
||||
}
|
||||
status.textContent = '状态:用户终止了屏幕捕获';
|
||||
resetRecordingState();
|
||||
});
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('录制启动失败:', error);
|
||||
status.textContent = `状态:启动失败 - ${error.message}`;
|
||||
resetRecordingState();
|
||||
}
|
||||
});
|
||||
|
||||
// 2. 暂停录制
|
||||
pauseBtn.addEventListener('click', () => {
|
||||
if (mediaRecorder.state === 'recording') {
|
||||
mediaRecorder.pause();
|
||||
isPaused = true;
|
||||
status.textContent = '状态:录制已暂停';
|
||||
pauseBtn.disabled = true;
|
||||
resumeBtn.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
// 3. 继续录制
|
||||
resumeBtn.addEventListener('click', () => {
|
||||
if (mediaRecorder.state === 'paused') {
|
||||
mediaRecorder.resume();
|
||||
isPaused = false;
|
||||
status.textContent = '状态:正在录制...';
|
||||
pauseBtn.disabled = false;
|
||||
resumeBtn.disabled = true;
|
||||
}
|
||||
});
|
||||
|
||||
// 4. 停止录制
|
||||
stopBtn.addEventListener('click', () => {
|
||||
if (mediaRecorder.state !== 'inactive') {
|
||||
// 停止录制器
|
||||
mediaRecorder.stop();
|
||||
// 停止所有流轨道(释放屏幕捕获)
|
||||
mediaStream.getTracks().forEach(track => track.stop());
|
||||
status.textContent = '状态:正在处理视频...';
|
||||
}
|
||||
});
|
||||
|
||||
// 辅助函数:重置录制状态
|
||||
function resetRecordingState() {
|
||||
mediaStream = null;
|
||||
mediaRecorder = null;
|
||||
isPaused = false;
|
||||
preview.srcObject = null;
|
||||
|
||||
// 重置按钮
|
||||
startBtn.disabled = false;
|
||||
pauseBtn.disabled = true;
|
||||
resumeBtn.disabled = true;
|
||||
stopBtn.disabled = true;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user