电子屏幕录制卡在 <10fps

Posted

技术标签:

【中文标题】电子屏幕录制卡在 <10fps【英文标题】:Electron screen recording stuck at <10fps 【发布时间】:2022-01-07 13:13:07 【问题描述】:

目标:

我想运行一个记录特定窗口约 2 分钟视频的电子应用程序。窗口是图像,而不是文本,所以我想要高清和 >=60 帧每秒。我只需要它在窗口平台上工作。捕获音频会很好,但不是我的首要任务。

我的尝试:

我查看了一些在线示例并想出了如何:

我使用electron的desktopCapturer.getSources()来查找我感兴趣的具体窗口源 然后我使用navigator.mediaDevices.getUserMedia() 将该窗口源转换为MediaStream。 然后我使用MediaRecorderMediaStream 收集记录块 我将块聚合到 Blob,转换为 ArrayBuffer,然后是 Buffer。 由于MediaRecorder 不支持.mp4,我使用基于ffmpeg 构建的npm 包将webm 缓冲区转换为mp4 缓冲区。 我使用 node 的 fs 将 webm 和 mp4 缓冲区写入 2 个文件。

这工作正常。 mp4 文件存在一些元数据问题,导致某些视频播放器无法播放,而其他视频播放器可以播放;我不太关心这个。 webm 视频播放良好。

问题:

录制的帧速率非常低。文件属性没有提到每秒帧数或比特率,这些字段只是空白。但它似乎每秒 5 帧。如果可能的话,我想要至少 30 个或更多。

console.log mediaStream 的视频轨道的帧速率为 30。我将写入文件短路,只是将 mediaStream 流式传输到 &lt;video&gt; 元素,但我仍然得到低帧,所以 MediaRecorder ,并且写入文件不负责。

简单示例:

const desktopCapturer = require('electron');

let source, stream, track;

desktopCapturer.getSources(types: ['window']).then(async sources => 
    // Get the stream
    source = sources.find(source => source.name === 'My Window');
    stream = await navigator.mediaDevices.getUserMedia(
        audio: false,
        video: 
            mandatory: 
                chromeMediaSource: "desktop",
                chromeMediaSourceId: source.id,
            ,
        ,
    );

    // Print some info about the stream
    track = stream.getVideoTracks()[0];
    let obj = 
        settings: track.getSettings(),
        constraints: track.getConstraints(),
        capabilities: track.getCapabilities(),
    ;
    console.log(JSON.stringify(obj, null, 2));

    // Project to a <video> element
    let video = document.querySelector('video');
    if (!video) 
        video = document.createElement('video');
        document.body.appendChild(video);
    
    video.srcObject = stream;
    video.onloadedmetadata = () => video.play();
);

Track 控制台日志:


  "settings": 
    "aspectRatio": 1.7777777777777777,
    "deviceId": "window:4982682:0",
    "frameRate": 30,
    "height": 1440,
    "resizeMode": "crop-and-scale",
    "width": 2560
  ,
  "constraints": 
    "deviceId": 
      "exact": "window:4982682:0"
    
  ,
  "capabilities": 
    "aspectRatio": 
      "max": 2560,
      "min": 0.0006944444444444445
    ,
    "deviceId": "window:4982682:0",
    "facingMode": [],
    "frameRate": 
      "max": 30,
      "min": 0
    ,
    "height": 
      "max": 1440,
      "min": 1
    ,
    "resizeMode": [
      "none",
      "crop-and-scale"
    ],
    "width": 
      "max": 2560,
      "min": 1
    
  

Chrome 浏览器示例:

我尝试在 chrome 浏览器中做同样的事情并遇到同样的问题。所以它似乎不是电子特定的。如果我选择与使用电子记录相同的窗口,则 chrome 具有相同的

    // Run this in the dev console

    stream = await navigator.mediaDevices.getDisplayMedia();
    
    let video = document.querySelector('video');
    if (!video) 
        video = document.createElement('video');
        document.body.appendChild(video);
    
    video.srcObject = stream;
    video.onloadedmetadata = () => video.play();

[编辑] 部分修复:

禁用窗口的“后台录制”设置后,我看到流的 fps 有了很大的提高。不过,它仍然不如内置窗口的 xbox-game-bar 录制(我正在尝试替换)那么流畅。

【问题讨论】:

【参考方案1】:

您对 .getUserMedia() 的调用提到了有关源设备的一些视频限制。要控制帧率,向约束对象添加

frameRate: min: 10, ideal: 60, max: 60 

也可以使用其他限制条件,例如大小。 See this.

最好使用 min / Ideal / max 而不是仅仅说

 frameRate: 60

如果你给出一个最小/理想/最大范围,即使捕捉无法保持更高的帧速率,你也会得到一些东西

您在 MediaRecorder 构造函数中设置压缩视频数据流的带宽。你没有问这个。

【讨论】:

也许我误解了在线文档/解释,但我的理解是frameRate 约束对网络摄像头有效,但对屏幕截图无效。当我尝试使用它时,我得到"Unknown name of constraint detected" / "frameRate" 错误 你是对的。这是一个相关的问题。 ***.com/questions/70142727/… maxFrameRate,就像您链接的问题一样,确实会影响流 fps。但是当我将minFrameRate 设置为 60 或 120 时,它并没有什么不同。而且它明显比 widow 的 xbox-game-bar 录音更不稳定。

以上是关于电子屏幕录制卡在 <10fps的主要内容,如果未能解决你的问题,请参考以下文章

oppor9手机怎么录制屏幕视频

Active Presenter(7.1.0)屏幕录制教学幻灯录制创作工具

win10怎么录制电脑屏幕 电脑录制视频

win10怎么录制电脑屏幕 电脑播放视频录制

视频录制软件进行电脑屏幕录像的使用方法

佳能R3和索尼A1哪个好