gpt4 book ai didi

webkit - 减少 navigator.webkitGetUserMedia 的 CPU 使用率(Electron : DesktopCapturer)

转载 作者:行者123 更新时间:2023-12-01 15:03:51 34 4
gpt4 key购买 nike

我正在使用 navigator.webkitGetUserMedia通过分配返回的 stream 每秒捕获一次窗口的屏幕截图到 <video>并将其复制到 <canvas>并将缓冲区保存到文件。

我的应用程序中的 CPU 使用率一直很高,我已将其确定为该区域。

代码

// Initialize the video, canvas, and ctx
var localStream,
_video = document.querySelector('#video'),
_canvas = document.querySelector('#canvas'),
_ctx = _canvas.getContext('2d'),
sourceName = 'my-window-id';

// Load the stream from navigator.webkitGetUserMedia
navigator.webkitGetUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: sourceName,
minWidth: 1920,
maxWidth: 1920,
minHeight: 1080,
maxHeight: 1080
}
}
}, gotStream, getUserMediaError);

function gotStream(stream) {
// Use the stream in our <video>
_video.src = window.URL.createObjectURL(stream);

// Reference the stream locally
localStream = stream;
}

function captureState() {
var buffer,
dataURL;

// Draw <video> to <canvas> and convert to buffer (image data)
_ctx.drawImage(_video, 0, 0);
dataURL = _canvas.toDataURL('image/png');
buffer = new Buffer(dataURL.split(",")[1], 'base64');

// Create an image from the data
fs.writeFileSync('screenshot.png', buffer);
}

// Capture state every second
setInterval(function() {
captureState();
}, 1000);

这段代码我没有运行,它是我的代码中的简化版本,以使其在 StackOverflow 中可读。

我尝试过的事情

  1. _video.pause()_video.play()需要的时候。似乎没有改变 CPU 使用率。
  2. _video.stop() .这意味着我将不得不再次获取流,这会导致 CPU 使用率激增,这比保持打开状态更糟糕。

我现在最好的方法是通过添加以下内容来更改帧速率:

  optional: [
{ minFrameRate: 1 },
{ frameRate: 1 }
]

极低的帧率就可以了。但是,我无法确定 frameRate 是否设置在这种情况下有效。 The docs没有列出,我也没有更新的 mediaDevices.getUserMedia可用。

是否可以为 navigator.webkitGetUserMedia 设置极低的帧率(或任何)? ?

有没有人能够以任何其他方式减少流的 CPU 使用率?

实现相同目标的任何替代方法(间隔状态捕获)也会有所帮助。

谢谢!

旁注

这是在 Windows 上使用 DesktopCapturer 的 Electron 应用程序中得到chromeMediaSourceId .


CPU 使用率更新

  1. 运行成本 stream : 6% 的 CPU 使用率
  2. 调用 captureState每 1000 毫秒:5% 的 CPU 使用率

总电流:11%​​

目前正在根据 Csaba Toth 的建议减少 #2。我应该可以减少 captureState通过更改 Canvas 的捕获方式。完成后会更新。

对于 #1,如果我无法避免捕获视频流,我将不得不尝试通过优化 #2 将总 CPU 使用率限制在略高于 6%。

最佳答案

这里进行了一些不必要的 base64 编码和操作,你获取数据的方式很奇怪:

dataURL = _canvas.toDataURL('image/png');
buffer = new Buffer(dataURL.split(",")[1], 'base64');

看看 QR 解码器如何访问图像:https://github.com/bulldogearthday/booths/blob/master/scripts/qrdecoder.js#L1991

var canvas_qr = document.getElementById("qr-canvas");
var context = canvas_qr.getContext('2d');
qrcode.width = canvas_qr.width;
qrcode.height = canvas_qr.height;
qrcode.imagedata = context.getImageData(0, 0, qrcode.width, qrcode.height);

(软件的另一端早些时候对 Canvas 做了一个drawImage)。现在的任务是找到一种方法,该方法不会不必要地将 PNG 数据转换为 base64,然后对其进行解码。我看到到处都建议使用这种 URI 编码,因为它的行数较少。但是在性能方面,不必要的编码/解码阶段是不可取的。 1920x1080 的 PNG 很大,不适用于 base64 内联。由于无论如何你都在 nodejs 中,请尝试使用 https://github.com/niegowski/node-pngjs或类似的库来保存图像数据。

空间和时间之间总是存在权衡,因此如果时间对较低压缩率真的很重要,您可以获得更高的性能:https://github.com/wheany/js-png-encoder

这里有一个权衡,因为 base64 URI 编码示例利用了浏览器的 native (C++,快速)png 编码,但随后进行了不必要的 base64 编码+解码。 node-pngjs 将在 JS 领域执行 PNG 编码,这可能不如浏览器的内部编码那么高效。最好的办法是找到一种在没有 base64 的情况下利用浏览器编码的方法。


早期建议

根据您展示的内容,我认为您的主要问题是您在 gotStream 中执行了 _ctx.drawImage(_video, 0, 0); 和其他操作。

这是我的一个渐进式网络应用程序,它也执行二维码扫描:https://github.com/bulldogearthday/booths/blob/master/scripts/app.js请注意,在“gotStream”(在我的例子中是匿名的 https://github.com/bulldogearthday/booths/blob/master/scripts/app.js#L67 )中,我只将流连接到 Canvas 。

我的情况比较简单,因为我不必强制执行尺寸(我希望您不要硬连接那些屏幕尺寸像素数),但我也会定期执行处理(QR 码扫描尝试,每 500 毫秒)。我最初为此使用计时器,但在一些迭代/滴答后停止工作,所以从技术上讲我发出一个超时,每次它命中我重新发出一个新的。查看初始超时 https://github.com/bulldogearthday/booths/blob/master/scripts/app.js#L209和期刊再版:https://github.com/bulldogearthday/booths/blob/master/scripts/app.js#L231

如您所见,我唯一做“繁重工作”的地方是 app.scanQRCode,它每秒只发生两次。我在那里处理 Canvas 的内容: https://github.com/bulldogearthday/booths/blob/master/scripts/app.js#L218

我建议您以这种方式重构您的代码。因此,要么设置一个每秒滴答作响的计时器,要么像我一样重新发出超时。然后在该部分中进行捕获+保存。希望这会减轻 CPU 负载,尽管每秒编码 1920x1080 PNG 可能会给 CPU 带来压力(会有 PNG 编码)。

(如果你想要单独的图像,那将是有益的。如果你最终还是想要一个视频,那么我会尝试按照你的建议继续执行 1s FPS 视频并捕获直接视频流而不是单个图像。但对于 CPU 负载,我的建议应该有助于恕我直言。)


在自述文件 (https://github.com/bulldogearthday/booths) 中,您可以看到我为 getUserMedia 查看的主要来源之一:https://github.com/samdutton/simpl/blob/gh-pages/getusermedia/sources/js/main.js

我不会随意发出 .play().pause() 或任何东西。事实上,我的代码一直等到它收到播放开始的信号(默认情况下,至少对于相机而言,它自己开始播放): document.getElementById('qrVideo').addEventListener('playing', app.saveVideoSize , 假); https://github.com/bulldogearthday/booths/blob/master/scripts/app.js#L67我这样做的目的是尽可能不干扰任何事物的自然过程。在我的例子中,我以这种温和的方式检测视频大小。查看 DesktopCapturer,他们在自述文件 https://github.com/electron/electron/blob/master/docs/api/desktop-capturer.mdgotStream 中也没有执行任何额外操作。 ,如理想情况下所示,您只需将视频流与 Canvas 连接起来。

关于webkit - 减少 navigator.webkitGetUserMedia 的 CPU 使用率(Electron : DesktopCapturer),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38243490/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com