当前位置:首页 > 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库,支持多种格式的压缩和转换。

js实现视频压缩

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编码器参数示例:

js实现视频压缩

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实现验证码

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

vue实现js休眠

vue实现js休眠

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

js实现搜索

js实现搜索

实现搜索功能的方法 在JavaScript中实现搜索功能可以通过多种方式完成,以下是几种常见的实现方法。 使用数组的filter方法 通过数组的filter方法可以筛选出符合条件的数据项。假设有一个…

js实现复选框

js实现复选框

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

js 实现验证码

js 实现验证码

实现验证码的 JavaScript 方法 生成随机验证码 验证码通常由随机字符(数字、字母或混合)组成。以下代码生成一个 6 位随机验证码(数字和字母混合): function generateCa…

js实现刷新

js实现刷新

刷新当前页面 使用 location.reload() 方法可以强制刷新当前页面。该方法接受一个布尔参数,默认为 false,表示从缓存中加载页面;设为 true 时强制从服务器重新加载。 // 从…