如何使用Puppeteer录制浏览器页面的音频?
实现方案
前置配置(Puppeteer启动参数)
首先启动Puppeteer时需要添加以下参数,避免权限拦截,确保音频可被捕获:
import puppeteer from 'puppeteer'; const browser = await puppeteer.launch({ args: [ '--autoplay-policy=no-user-gesture-required', // 允许页面自动播放音频 '--use-fake-ui-for-media-stream', // 跳过媒体权限请求弹窗 '--enable-audio-capture' // 开启音频捕获能力 ] });
TypeScript 完整实现
你可以直接用以下代码替换原有的AudioRecord函数,实现支持启停控制、本地存储的页面音频录制能力:
import { Page } from 'puppeteer'; import fs from 'fs/promises'; // 函数返回停止录制的方法,调用后会将音频写入指定路径 export const AudioRecord = async (page: Page, outputPath: string): Promise<() => Promise<void>> => { // 1. 授予当前页面音频捕获权限 const context = page.browserContext(); await context.overridePermissions(page.url(), ['audioCapture']); // 2. 注入页面内录制逻辑 await page.exposeFunction('writeAudioChunk', async (chunk: string) => { // 接收页面传递的base64格式音频块,暂存(可优化为流写入,避免内存占用过高) const buffer = Buffer.from(chunk, 'base64'); await fs.appendFile(outputPath, buffer); }); await page.evaluate(() => { // @ts-ignore 挂载录制实例到window对象 window.mediaRecorder = null; // 捕获页面所有音频输出流 const stream = (navigator as any).mediaDevices.getDisplayMedia({ video: false, audio: true }).then((stream: MediaStream) => { // 初始化MediaRecorder,音频格式默认用audio/webm,兼容性最好 const recorder = new MediaRecorder(stream, { mimeType: 'audio/webm' }); // @ts-ignore window.mediaRecorder = recorder; recorder.ondataavailable = (e) => { if (e.data.size > 0) { // 转base64传递给Node.js层写入文件 const reader = new FileReader(); reader.readAsDataURL(e.data); reader.onloadend = () => { const base64 = (reader.result as string).split(',')[1]; // @ts-ignore 调用暴露的Node.js方法 window.writeAudioChunk(base64); }; } }; recorder.start(1000); // 每1秒返回一次音频块,可按需调整间隔 }); }); // 返回停止录制的方法 return async () => { await page.evaluate(() => { // @ts-ignore if (window.mediaRecorder && window.mediaRecorder.state !== 'inactive') { // @ts-ignore window.mediaRecorder.stop(); // @ts-ignore window.mediaRecorder.stream.getTracks().forEach(track => track.stop()); } }); // 等待1秒确保最后一块音频写入完成 await new Promise(resolve => setTimeout(resolve, 1000)); }; };
使用示例
// 初始化page实例逻辑省略 const stopRecord = await AudioRecord(page, './output.webm'); // 执行你的其他业务逻辑,比如等待研讨会结束 await page.waitForSelector('#seminar-end', { timeout: 0 }); // 停止录制 await stopRecord();
注意事项
- 默认输出的是webm格式音频,如果需要转MP3,可以在录制完成后调用ffmpeg工具做格式转换
- 如果录制时长较长,建议改为流写入的方式处理音频块,避免内存占用过高
- 如果目标网站有内容安全策略(CSP)限制内联脚本,可以在启动Puppeteer时添加
--disable-web-security参数临时关闭安全限制
内容的提问来源于stack exchange,提问作者xksa
相关产品推荐
相关产品推荐

