历史课堂转视频接入方式
伯索历史课堂格式是私有格式, 不是标准的MP4格式, 针对客户需要转为普通的MP4格式视频做数据留存,我们建议使用如下技术方案来实现。
Puppeteer是一个Node库,它提供了各种高级的API,通过DevTools协议来控制浏览器(chrome, chromium)。可以理解成为一个headless chrome浏览器。当前,我们也可以通过option,设置为有UI的浏览器。
Puppeteer api
**API ** | ** 描述 ** |
---|---|
Browser | 浏览器实例,可以包含多个BrowserContext |
BrowserContext | 对应浏览器的一个上下文回话。例如普通的浏览器中打开隐身模式的浏览器,具有独立的cookie和cache, 拥有多个page |
Page | 表示一个Tab页面: browser.newPage() |
Frame | 每个页面有一个主框架(page.MainFrame(),可以拥有多个子框架,由iframe标签创建 |
ExecutionContext | JavaScript执行环境。每一个frame有一个默认的JavaScript执行环境 |
ElementHandle | 对应Dom的一个元素节点,通过该实例可以实现对元素的点击,操作 |
JsHandle | 对应Dom中的JavaScript对象,ElementHandle继承于JSHandle.由于我们无法直接操作 DOM 中对象,所以封装成 JsHandle 来实现相关功能 |
CDPSession | 可以直接与原生的 CDP 进行通信,通过 session.send 函数直接发消息,通过 session.on 接收消息,可以实现 Puppeteer API 中没有涉及的功能 |
Coverage | 获取JavaScript和css代码覆盖率 |
Tracing | 抓取性能数据进行分析 |
Response | 页面收到的响应 |
Request | 页面发出的请求 |
tips: chrome.tabCapture.capture: 捕获当前活动标签页的可视区域。该方法只能在扩展程序被调用之后在当前活动网页上使用,与 activeTab 的工作方式类似。
打开浏览器
访问需要录制的页面
获取录制页面的stream对象,存放如webm格式视频文件
这里需要注意defaultViewport 和 --window-size需要结合配置,让窗体才能100%打开。不然打开后是一个很小的窗体。
import { launch } from "puppeteer-stream";
let width = 1920,
height = 1080;
this.browser = await launch({
headless: true,
args: [
"--no-sandbox",
"--disable-setuid-sandbox",
`--window-size=${width},${height}`,
"--autoplay-policy=no-user-gesture-required",
// '--remote-debugging-port=3333',
// "--auto-open-devtools-for-tabs",
],
defaultViewport: {
width: 0,
height: 0,
},
ignoreDefaultArgs: ["--disable-extensions", "--mute-audio"],
});
创建一个page, 在page中输入需要访问的地址, 并处理界面上各种点击事件操作。
const result = await page.evaluate(
async (option: { [key in string]: any }) => {
let { _client } = window as any;
console.log(options.id);
return JSON.stringify(joinResult)
},
{
id: this.id,
}
);
getStream会返回整个页面的stream,将该流生成一个webm格式的视频。
import fs from "fs";
import { Page } from "puppeteer";
import { getStream } from "puppeteer-stream";
this.stream = await getStream(this.page as Page, {
audio: true,
video: true,
frameSize: 20,
});
this.file = fs.createWriteStream(`${this.filePath}.webm`);
this.stream.pipe(this.file);

修改于 2025-03-20 06:33:51