当前位置:首页 > 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实现vue

js实现vue

Vue.js 简介 Vue.js 是一个渐进式 JavaScript 框架,用于构建用户界面。其核心库专注于视图层,易于与其他库或现有项目整合。 实现 Vue.js 的基本步骤 安装 Vue.j…

js实现动画

js实现动画

使用 CSS 动画与 JavaScript 控制 通过 JavaScript 动态添加或移除 CSS 类来触发动画。CSS 定义关键帧(@keyframes),JavaScript 通过 classL…

js实现乘

js实现乘

JavaScript 实现乘法运算 在 JavaScript 中实现乘法运算可以通过多种方式完成,包括基本运算符、函数封装以及高级算法(如大数乘法)。以下是几种常见方法: 使用基本乘法运算符 Jav…

js实现图表

js实现图表

在JavaScript中实现图表通常使用流行的图表库,以下是几种常见的方法和工具: 使用Chart.js Chart.js是一个简单灵活的库,适合快速生成响应式图表。安装方式包括CDN引入或npm安…

js实现图

js实现图

JavaScript 实现图的常用方法 在 JavaScript 中,图(Graph)可以通过多种方式实现,常见的包括邻接表(Adjacency List)和邻接矩阵(Adjacency Matrix…

js实现投球

js实现投球

实现投球动画的基本思路 使用JavaScript和CSS动画结合的方式模拟投球效果。核心是通过改变元素的位置、旋转和缩放属性,配合定时器或CSS过渡实现平滑动画。 创建基础HTML结构 <…