【问题标题】:MediaRecorder class Not Available in Electron APPMediaRecorder 类在 Electron APP 中不可用
【发布时间】:2021-06-01 13:28:12
【问题描述】:

我正在按照 Fireships 的 Electron 教程构建桌面捕获器。 我知道的一件事是,到目前为止,我使用的版本和他的版本之间存在巨大差异。 我遇到的唯一问题是在 MediaRecorder 类的实例化期间。 该类根本没有被识别。

有什么办法可以解决吗?

Render.js - 源代码

// Buttons
const videoElement = document.querySelector('video');
const startBtn = document.getElementById('startBtn');
startBtn.onclick = e => {
  mediaRecorder.start();
  startBtn.classList.add('is-danger');
  startBtn.innerText = 'Recording';
};
const stopBtn = document.getElementById('stopBtn');
stopBtn.onclick = e => {
  mediaRecorder.stop();
  startBtn.classList.remove('is-danger');
  startBtn.innerText = 'Start';
};
const videoSelectBtn = document.getElementById('videoSelectBtn');
videoSelectBtn.onclick = getVideoSources; 

const { desktopCapturer, remote } = require('electron');
const { dialog, Menu } = remote;

// Get the available video sources
async function getVideoSources() {
  const inputSources = await desktopCapturer.getSources({
    types: ['window', 'screen']
  });

  const videoOptionsMenu = Menu.buildFromTemplate(
    inputSources.map(source => {
      return {
        label: source.name,
        click: () => selectSource(source)
      };
    })
  );


  videoOptionsMenu.popup();
}

let mediaRecorder; //MediaRecorder instance to capture footage
const recordedChunks = [];

// Change the videoSources window to record
async function selectSource(source) {

  videoSelectBtn.innerText = source.name;

  const constraints = {
    audio: false,
    video: {
      mandatory: {
        chromeMediaSource: 'desktop',
        chromeMediaSourceId: source.id
      }
    }
  };

  // Create a Stream
  const stream = await navigator.mediaDevices.getUserMedia(constraints);

  //Preview the source in a video element
  videoElement.srcObject = stream;
  videoElement.play();

  // Create the Media Recorder
  const options = { mimeType: 'video/webm; codecs=vp9' };
  mediaRecorder = new MediaRecorder(stream, options);

  // Register Event Handlers
  mediaRecorder.ondataavailable = handleDataAvailable;
  mediaRecorder.onStop = handleStop;
}

// Captures allrecorded chunks
function handleDataAvailable(e) {
  console.log('video data available')
  recordedChunks.push(e.data);
}

const { writeFile } = require('fs');

//Saves the video file on stop
async function handleStop(e) {
  const blob = new Blob(recordedChunks,{
    type: 'video/webm; codecs=vp9'
  });

  const buffer = Buffer.from(await blob.arrayBuffer());

  const { filePath } = await dialog.showSaveDialog({

    buttonLabel: 'Save Video',
    defaultPath: `vid -${Date.now()}.webm`
  });

  console.log(filePath);

  writeFile(filePath, buffer, () => console.log('Video Saved Successfully!'));
}

Web 偏好设置 - Index.js

const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
      enableRemoteModule: true,
    }

【问题讨论】:

    标签: javascript electron web-mediarecorder


    【解决方案1】:

    在 render.js 文件中试试这个,使用electron": "10.2.0

    const { desktopCapturer, remote, dialog } = require('electron');
    const { writeFile } = require('fs');
    const { Menu } = remote;
    
    //Buttons
    const videoElement = document.querySelector('video');
    const startBtn = document.getElementById('startBtn');
    const stopBtn = document.getElementById('stopBtn');
    const videoSelectBtn = document.getElementById('videoSelectBtn');
    videoSelectBtn.onclick = getVideoSources();
    
    //Get all available video sources
    async function getVideoSources() {
      const inputSources = await desktopCapturer.getSources({
        types: ['window', 'screen'],
      });
    
      const videoOptionsMenu = Menu.buildFromTemplate(
        inputSources.map((source) => {
          return {
            label: source.name,
            click: () => selectSource(source),
          };
        })
      );
    
      videoOptionsMenu.popup();
    }
    
    let mediaRecorder; //Mediarecorder instance to capture footage
    const recordedChunks = [];
    
    async function selectSource(source) {
      videoSelectBtn.innerText = source.name;
    
      const constraints = {
        audio: false,
        video: {
          mandatory: {
            chromeMediaSource: 'desktop',
            chromeMediaSourceId: source.id,
          },
        },
      };
    
      //Create a stream
      const stream = await navigator.mediaDevices.getUserMedia(constraints);
    
      //Preview the source in a video element
      videoElement.srcObject = stream;
      videoElement.play();
    
      //Create the Media Recorder
      const options = { mimeType: 'video/webm; codecs=vp9' };
      mediaRecorder = new mediaRecorder(stream, options);
    
      //Register Event Handlers
      mediaRecorder.ondataavailable = handleAvailableData;
      mediaRecorder.onstop = handleStop;
    }
    
    async function handleAvailableData(e) {
      console.log('Video data available');
      recordedChunks.push(e.data);
    }
    
    //Save video on stop
    async function handleStop(e) {
      const blob = new Blob(recordedChunks, {
        type: 'video/webm; codecs=vp9',
      });
    
      const buffer = Buffer.from(await blob.arrayBuffer());
    
      const { filePath } = await dialog.showSaveDialog({
          buttonLabel: 'Save Video',
          defaultPath: `vid-${Date.now()}.webm`
      })
    
      console.log(filePath);
    
      writeFile(filePath, buffer, () => console.log('Saved Successfully'))
    }
    

    【讨论】:

    • 导入电子模块时的含义?
    • 我的意思是你将从 package.json 中删除它,然后使用 npm i electron@10.2.0 安装它。
    • 我试过了,它奏效了。但无论如何,我从Github 获取了 package.json 和锁定文件。 VS 代码仍然没有检测到,但代码工作得很好。无论如何谢谢。
    • 太好了,我能帮上忙
    猜你喜欢
    • 1970-01-01
    • 2021-02-09
    • 2022-12-19
    • 2016-08-09
    • 2018-01-14
    • 1970-01-01
    • 2017-08-29
    • 2018-09-21
    • 2020-02-03
    相关资源
    最近更新 更多