当前位置:首页 > JavaScript

js实现视频压缩

2026-01-30 19:28:09JavaScript

使用FFmpeg.wasm进行视频压缩

FFmpeg.wasm是FFmpeg的WebAssembly版本,可以在浏览器中直接运行。安装FFmpeg.wasm后,可以通过JavaScript调用其功能进行视频压缩。

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

const ffmpeg = createFFmpeg({ log: true });

async function compressVideo(file) {
  await ffmpeg.load();
  ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(file));
  await ffmpeg.run('-i', 'input.mp4', '-vf', 'scale=640:-1', '-c:v', 'libx264', '-crf', '28', 'output.mp4');
  const data = ffmpeg.FS('readFile', 'output.mp4');
  return new Blob([data.buffer], { type: 'video/mp4' });
}

使用Canvas API和MediaRecorder

对于简单的视频压缩,可以使用Canvas API和MediaRecorder组合实现。这种方法适合需要降低分辨率或帧率的场景。

async function compressWithCanvas(videoFile, width = 640, quality = 0.7) {
  const videoElement = document.createElement('video');
  videoElement.src = URL.createObjectURL(videoFile);
  await new Promise(resolve => videoElement.onloadedmetadata = resolve);

  const canvas = document.createElement('canvas');
  canvas.width = width;
  canvas.height = (videoElement.videoHeight / videoElement.videoWidth) * width;

  const stream = canvas.captureStream();
  const recorder = new MediaRecorder(stream, {
    mimeType: 'video/webm',
    bitsPerSecond: 500000
  });

  const ctx = canvas.getContext('2d');
  const chunks = [];
  recorder.ondataavailable = e => chunks.push(e.data);
  recorder.start(100);

  const drawFrame = () => {
    ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
    if (!videoElement.ended) requestAnimationFrame(drawFrame);
    else recorder.stop();
  };
  videoElement.play();
  drawFrame();

  return new Promise(resolve => {
    recorder.onstop = () => {
      const blob = new Blob(chunks, { type: 'video/webm' });
      resolve(blob);
    };
  });
}

使用第三方库videoconverter.js

videoconverter.js是一个专门用于视频转换的JavaScript库,支持多种格式的压缩和转换。

const converter = new videojs.VideoConverter();
converter.setInputFormat('mp4');
converter.setOutputFormat('mp4');
converter.setQuality(50); // 质量百分比

converter.on('complete', function(outputBlob) {
  console.log('压缩完成', outputBlob);
});

converter.convert(videoFile);

使用Web Worker处理大文件

对于大型视频文件,建议使用Web Worker避免阻塞主线程。将压缩逻辑放在Worker中执行。

// main.js
const worker = new Worker('video-worker.js');
worker.postMessage({ file: videoFile });
worker.onmessage = function(e) {
  const compressedBlob = e.data;
  // 处理压缩后的视频
};

// video-worker.js
self.onmessage = function(e) {
  const file = e.data.file;
  // 执行压缩逻辑
  const compressed = compressVideo(file);
  self.postMessage(compressed);
};

优化压缩参数

调整视频编码参数可以平衡文件大小和质量。常用的x264编码器参数示例:

await ffmpeg.run(
  '-i', 'input.mp4',
  '-c:v', 'libx264',
  '-preset', 'slow',
  '-crf', '28',
  '-c:a', 'aac',
  '-b:a', '128k',
  'output.mp4'
);

其中CRF值范围18-28(值越大压缩率越高),预设值可选ultrafast到veryslow(越慢压缩效率越高)。

浏览器兼容性处理

不同浏览器对视频编码的支持不同,需要检测并回退处理:

function getSupportedMimeType() {
  const types = [
    'video/webm; codecs=vp9',
    'video/webm; codecs=vp8',
    'video/mp4; codecs=avc1'
  ];
  return types.find(type => MediaRecorder.isTypeSupported(type)) || 'video/webm';
}

const mimeType = getSupportedMimeType();
const recorder = new MediaRecorder(stream, { 
  mimeType,
  bitsPerSecond: 1000000 
});

js实现视频压缩

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

相关文章

js实现验证码

js实现验证码

实现验证码的JavaScript方法 生成随机验证码 使用Math.random()生成随机字符串,结合数字和字母: function generateCaptcha() { const cha…

vue实现js休眠

vue实现js休眠

Vue 中实现 JavaScript 休眠 在 Vue 中实现 JavaScript 休眠通常需要使用异步方式,以避免阻塞主线程。以下是几种常见方法: 使用 setTimeout 和 Pro…

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽功能。以下是核心代码逻辑: const draggableElement = document.…

js实现图片预览

js实现图片预览

使用FileReader API实现图片预览 通过FileReader对象读取用户选择的图片文件并显示预览: const input = document.getElementById('imag…

js 实现vue

js 实现vue

Vue.js 的基本实现 在 JavaScript 中实现 Vue.js 的核心功能,可以通过数据绑定、响应式系统和虚拟 DOM 来实现。以下是实现 Vue.js 核心功能的简化版本。 数据响应式系…

js实现论坛

js实现论坛

实现论坛的基本功能 使用JavaScript实现一个论坛需要结合前端和后端技术。前端可以使用React、Vue或Angular等框架,后端可以选择Node.js配合Express或Koa框架。数据库可…