Xvfb录制黑屏

问题描述 投票:0回答:1

我正在尝试通过在 docker 映像中运行 xvfb 来录制视频。无论我做什么,它都会让我黑屏。

xvfb、ffmpeg 和 puppeteer 中的屏幕尺寸相同。

如果有人能提供帮助,那就太好了。


start-xvfb.sh
---------------------------------------------------------------------
# Start Xvfb
Xvfb :99 -screen 0 1280x720x24 &

# Set the display environment variable
export DISPLAY=:99

# Run the application (assuming it starts with npm start)
npm run dev

Dockerfile

FROM node:lts-alpine3.19

# Install dependencies using apk
RUN apk update && \
    apk add --no-cache \
    gnupg \
    ffmpeg \
    libx11 \
    libxcomposite \
    libxdamage \
    libxi \
    libxtst \
    nss \
    cups-libs \
    libxrandr \
    alsa-lib \
    pango \
    gtk+3.0 \
    xvfb \
    bash \
    curl \
    udev \
    ttf-freefont \
    chromium \
    chromium-chromedriver

# Set working directory
WORKDIR /app

# Copy package.json and install dependencies
COPY package.json .
RUN npm install --force

# Copy remaining source code
COPY . .

# Add a script to start Xvfb
COPY start-xvfb.sh /app/start-xvfb.sh
RUN chmod +x /app/start-xvfb.sh

# Expose the port
EXPOSE 4200
EXPOSE 3000

# Command to start Xvfb and run the application
CMD ["./start-xvfb.sh"]

这是从 Nodejs 应用程序启动 puppeteer 并创建 ffmpeg 进程的代码

export class UnixBrowserRecorder implements Recorder {

  url = 'https://stackoverflow.com/questions/3143698/uncaught-syntaxerror-unexpected-token'; // Replace with your URL
  outputFilePath = `/app/output_video.mp4`; // Output file path within the container
  durationInSeconds = 6; // Duration of the video in seconds
  resolution = '1280x720';

  public async capture(): Promise<string> {
    const browser = await puppeteer.launch({
      args: [
        '--no-sandbox', // Required in Docker
        '--disable-setuid-sandbox', // Required in Docker
        '--disable-dev-shm-usage', // Required in Docker
        '--headless', // Run browser in headless mode
        '--disable-gpu', // Disable GPU acceleration
        `--window-size=${this.resolution}` // Set window size
      ],
      executablePath: '/usr/bin/chromium' // Specify the path to Chromium executable
    });

    const page = await browser.newPage();
    await page.goto(this.url);

    await page.screenshot({
      "type": "png", // can also be "jpeg" or "webp" (recommended)
      "path": `/app/screenshot.png`,  // where to save it
      "fullPage": true,  // will scroll down to capture everything if true
    });

    //ffmpeg -video_size `DISPLAY=:5 xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -framerate 30 -f x11grab -i :5.0+0,0 output.mpg

    const ffmpegProcess = spawn('ffmpeg', [
      '-video_size', this.resolution,
      '-framerate', '30',
      '-f', 'x11grab',
      '-i', ':99', // Use display :99 (assuming Xvfb is running on this display)
      '-t', this.durationInSeconds.toString(),
      '-c:v', 'libx264',
      '-loglevel', 'debug',
      '-pix_fmt', 'yuv420p',
      this.outputFilePath
    ]);

    // Log ffmpeg output
    ffmpegProcess.stdout.on('data', data => {
      console.log(`ffmpegProcess stdout: ${data}`);
    });

    ffmpegProcess.stderr.on('data', data => {
      console.error(`ffmpegProcess stderr: ${data}`);
    });

    // Handle ffmpegProcess process exit
    ffmpegProcess.on('close', code => {
      console.log(`ffmpeg process exited with code ${code}`);
    });

    // Wait for the duration to complete
    await new Promise(resolve => setTimeout(resolve, this.durationInSeconds * 1000));

    // Close the FFmpeg stream and process
    ffmpegProcess.stdin.end();
    // Close Puppeteer
    await page.close();
    await browser.close();

    return "Video generated successfully";
  }
}

enter image description here

node.js ffmpeg puppeteer
1个回答
0
投票

我终于能够通过在启动 puppeteer 时删除以下参数来捕获视频

'--headless', // 以无头模式运行浏览器

© www.soinside.com 2019 - 2024. All rights reserved.