You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在不支持MediaRecorder的Safari 11中实现HTML5视频录制?

解决Safari 11视频录制问题:替代MediaRecorder的方案

Got it, I’ve run into this exact headache with Safari 11 before—native MediaRecorder support was missing entirely back then, but we can work around it using Canvas-based frame capture and a lightweight video synthesis library. Let’s walk through how to make this work:

核心思路

Since Safari 11 doesn’t support the MediaRecorder API, we’ll:

  1. Feed the getUserMedia() stream into a video element (which you already have working)
  2. Mirror that video stream to a Canvas element
  3. Capture individual frames from the Canvas at regular intervals
  4. Synthesize those frames into a playable video file using a JS library

Step 1: Set Up Video & Canvas Elements

First, make sure you have the necessary HTML elements, and bind your media stream to both the video and canvas:

<video id="liveVideo" autoplay playsinline></video>
<canvas id="captureCanvas" style="display: none;"></canvas>
<button id="startBtn">Start Recording</button>
<button id="stopBtn">Stop Recording</button>
let mediaStream;
let videoElement = document.getElementById('liveVideo');
let canvas = document.getElementById('captureCanvas');
let ctx = canvas.getContext('2d');

// Get media stream (you already have this part)
navigator.mediaDevices.getUserMedia({ video: true, audio: false })
  .then(stream => {
    mediaStream = stream;
    videoElement.srcObject = stream;
    videoElement.onloadedmetadata = () => {
      // Match canvas size to video resolution
      canvas.width = videoElement.videoWidth;
      canvas.height = videoElement.videoHeight;
    };
  })
  .catch(err => console.error('Failed to get stream:', err));

Step 2: Capture Frames During Recording

We’ll use setInterval to grab frames from the Canvas at a consistent frame rate (e.g., 30fps or 60fps) and store them as Blobs:

let captureInterval;
let capturedFrames = [];

// Start recording logic
document.getElementById('startBtn').addEventListener('click', () => {
  capturedFrames = []; // Reset frame array
  // Capture a frame every ~33ms for 30fps (adjust for 60fps by using 16ms)
  captureInterval = setInterval(() => {
    // Draw current video frame to canvas
    ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
    // Convert canvas to PNG Blob and store
    canvas.toBlob(blob => {
      capturedFrames.push(blob);
    }, 'image/png');
  }, 33);
});

Step 3: Synthesize Frames into Video

Once recording stops, we need to turn those frame Blobs into a video file. For this, use a lightweight library like Whammy.js (which creates WebM videos) or FFmpeg.js (for more flexibility, like MP4 output):

Example with Whammy.js

document.getElementById('stopBtn').addEventListener('click', () => {
  clearInterval(captureInterval);

  // Create a Whammy Video instance with your target frame rate
  const videoCreator = new Whammy.Video(30);
  // Add all captured frames to the video
  capturedFrames.forEach(frameBlob => {
    videoCreator.add(frameBlob);
  });

  // Compile the frames into a single video Blob
  const finalVideoBlob = videoCreator.compile();

  // Create a download link for the video
  const downloadLink = document.createElement('a');
  downloadLink.href = URL.createObjectURL(finalVideoBlob);
  downloadLink.download = 'safari-recorded-video.webm';
  downloadLink.click();

  // Clean up
  URL.revokeObjectURL(downloadLink.href);
});

Step 4: Handling Audio (If Needed)

The above setup only captures video. If you need audio too:

  • Use AudioContext and MediaStreamAudioSourceNode to capture raw audio data while recording frames
  • Sync the audio samples with your video frames
  • Use FFmpeg.js to merge the audio and video into a single file (Whammy.js doesn’t support audio)

This is more complex, but FFmpeg.js handles the syncing and format conversion seamlessly.

Key Notes for Safari 11

  • Canvas capture performance: Safari 11 isn’t the fastest with Canvas operations, so you might need to lower the video resolution or frame rate if you see lag.
  • Video format: Whammy.js outputs WebM, which Safari 11 can’t play natively, but users can download and play it in other players or you can convert it to MP4 with FFmpeg.js.
  • Memory: Storing hundreds of frame Blobs can use a lot of memory—consider processing frames in batches instead of storing all at once if you’re recording long videos.

内容的提问来源于stack exchange,提问作者Archna Rangrej

火山引擎 最新活动