当前位置:首页 > JavaScript

js实现视频压缩

2026-04-04 11:12:28JavaScript

使用 MediaRecorder API 压缩视频

通过 MediaRecorder API 可以录制视频并设置压缩参数。该方法适合在浏览器端直接处理视频文件。

async function compressVideo(file) {
  const videoElement = document.createElement('video');
  videoElement.src = URL.createObjectURL(file);
  await new Promise(resolve => videoElement.onloadedmetadata = resolve);

  const canvas = document.createElement('canvas');
  canvas.width = videoElement.videoWidth * 0.5; // 缩小分辨率
  canvas.height = videoElement.videoHeight * 0.5;
  const ctx = canvas.getContext('2d');

  const stream = canvas.captureStream();
  const recorder = new MediaRecorder(stream, {
    mimeType: 'video/webm;codecs=vp9',
    bitsPerSecond: 250000 // 设置比特率
  });

  videoElement.play();
  const chunks = [];
  recorder.ondataavailable = e => chunks.push(e.data);
  recorder.start();

  const interval = setInterval(() => {
    ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
  }, 1000/30);

  return new Promise(resolve => {
    setTimeout(() => {
      clearInterval(interval);
      recorder.stop();
      resolve(new Blob(chunks, {type: 'video/webm'}));
    }, 3000); // 录制3秒
  });
}

使用 FFmpeg.wasm 进行高级压缩

FFmpeg.wasm 是 WebAssembly 版本的 FFmpeg,提供更专业的视频处理能力。

import { createFFmpeg } from '@ffmpeg/ffmpeg';

async function compressWithFFmpeg(file) {
  const ffmpeg = createFFmpeg({ log: true });
  await ffmpeg.load();

  ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(file));
  await ffmpeg.run(
    '-i', 'input.mp4',
    '-vf', 'scale=640:-1', // 调整分辨率
    '-c:v', 'libx264',     // H.264编码
    '-crf', '28',          // 压缩质量(18-28)
    '-preset', 'fast',
    'output.mp4'
  );

  const data = ffmpeg.FS('readFile', 'output.mp4');
  return new Blob([data.buffer], { type: 'video/mp4' });
}

使用 Canvas 和 Web Worker 处理

对于长时间压缩任务,建议使用 Web Worker 避免阻塞主线程。

// worker.js
self.onmessage = async (e) => {
  const { file, width, height, quality } = e.data;
  const video = document.createElement('video');
  video.src = URL.createObjectURL(file);

  await new Promise(resolve => {
    video.onloadedmetadata = resolve;
    video.play();
  });

  const canvas = new OffscreenCanvas(width, height);
  const ctx = canvas.getContext('2d');

  const frames = [];
  for (let i = 0; i < video.duration * 30; i++) {
    ctx.drawImage(video, 0, 0, width, height);
    frames.push(await canvas.convertToBlob({quality}));
    await new Promise(r => setTimeout(r, 1000/30));
  }

  postMessage(frames);
};

使用第三方库 compressor.js

compressor.js 提供简单的视频压缩接口,适合快速实现基本需求。

import Compressor from 'compressorjs';

new Compressor(file, {
  quality: 0.6,
  maxWidth: 1280,
  maxHeight: 720,
  success(result) {
    console.log('压缩完成', result);
  },
  error(err) {
    console.error('压缩失败', err);
  }
});

注意事项

视频压缩会受浏览器兼容性限制,不同浏览器支持的编码格式不同。建议检测浏览器支持情况:

js实现视频压缩

function checkCodecSupport() {
  return MediaRecorder.isTypeSupported('video/webm;codecs=vp9') 
    || MediaRecorder.isTypeSupported('video/mp4');
}

移动端设备可能对高分辨率视频处理性能有限,建议先降低分辨率再压缩。

标签: 视频压缩js
分享给朋友:

相关文章

js实现轮播

js实现轮播

实现基础轮播效果 使用HTML结构创建轮播容器和图片元素: <div class="carousel"> <div class="carousel-inner">…

vue实现js休眠

vue实现js休眠

实现 JavaScript 休眠的方法 在 Vue 中实现 JavaScript 休眠(延迟执行)可以通过以下方式实现。由于 JavaScript 本身没有内置的 sleep 函数,通常使用 Prom…

js 实现跳转

js 实现跳转

使用 window.location.href 进行跳转 通过修改 window.location.href 可以跳转到指定 URL,浏览器会加载新页面: window.location.hre…

js实现显示隐藏

js实现显示隐藏

显示隐藏的实现方法 在JavaScript中,实现元素的显示和隐藏可以通过多种方式完成。以下是几种常见的方法: 修改CSS的display属性 通过改变元素的display属性可以在none(隐藏)…

js 实现递归

js 实现递归

递归的基本概念 递归是指函数直接或间接调用自身的过程。在JavaScript中,递归通常用于解决可以分解为相似子问题的问题,如阶乘、斐波那契数列、树形结构遍历等。 递归的实现要点 基线条件(Base…

js实现复选框

js实现复选框

实现复选框的基本方法 使用HTML的<input type="checkbox">元素创建复选框,并通过JavaScript监听其状态变化。 <input type="checkb…