FFmpeg——在Vue项目中使用FFmpeg(安装、配置、使用、SharedArrayBuffer、跨域隔离、避坑...)

news2024/11/29 20:47:58

个人简介

👀个人主页: 前端杂货铺
🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js🍒Three.js🍖数据结构与算法体系教程

🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

内容参考链接
Canvas 录制视频Canvas 录制视频
录制视频的解决方案使用 Canvas 录制视频尚存问题的解决方案
在 Vue 项目中使用 FFmpeg

文章目录

    • 前言
    • 在 Vue 项目中使用 FFmpeg
      • FFmpeg.wasm 简介
      • 在 Vue 项目中安装并配置 FFmpeg
      • 在 Vue 项目中使用 FFmpeg
        • SharedArrayBuffer 的前世今生
        • 解决 SharedArrayBuffer 报错问题
        • FFmpeg 的一些坑
    • 总结

前言

大家好,这里是前端杂货铺

在 Canvas 录制视频 一文中,我们使用了 MediaRecorder API 在 Canvas 画布中进行了页面的视频录制,并成功输出了 WebM 格式 的视频。

在 使用 Canvas 录制视频尚存问题的解决方案 一文中,我们通过下载 FFmpeg,进行了视频格式的转换及视频帧率的设置。

但在 Vue 项目中怎么使用 FFmpeg 呢?接下来,我们一起进行详细探索!


在 Vue 项目中使用 FFmpeg

在浏览器中我们是无法直接使用 FFmpeg 软件的,但好在有个东西叫 FFmpeg.wasm,它可以让 FFmpeg 的功能在浏览器中使用!当然,我们可以在 Vue 项目中使用 FFmpeg.wasm 来代替手动输入命令行操作的 FFmpeg 软件!!

FFmpeg.wasm 简介

什么是 FFmpeg.wasm?

FFmpeg.wasm 是 FFmpeg 的纯 WebAssembly 接口,可以在浏览器内录制音频和视频,并进行转换和流式传输。

什么是 WebAssembly?

WebAssembly(简称wasm)是一个虚拟指令集体系架构(virtual ISA),整体架构包括核心的ISA定义、二进制编码、程序语义的定义与执行,以及面向不同的嵌入环境(如Web)的应用编程接口(WebAssembly API)。其目标是为 C/C++等语言编写的程序经过编译,在确保安全和接近原生应用的运行速度更好地在 Web 平台上运行。

所以,FFmpeg.wasm 就是 C语言 编写的程序,通过编译后,它可以在 Web 平台(比如浏览器)上运行。

FFmpeg.wasm(Github源码)

在这里插入图片描述


在 Vue 项目中安装并配置 FFmpeg

第一步:想要在 Vue 项目中使用 FFmpeg 第一步当然是要有个 Vue 项目,Vue 项目的搭建就不做介绍了,不清楚的同学可以自行百度查询(资料很多)。在此,博主使用的是 Vue2 的项目(具体版本为 ^2.6.11)【说明:大家并不需要刻意与我的项目版本保持一致】。

第二步:找到 package.json 文件,在指定区域输入下图中蓝框的内容【说明:@ffmpeg/ffmpeg 和 @ffmpeg/ffmpeg 并非最新版本,请按照自己需要安装所需版本】

在这里插入图片描述

第三步:终端键入 npm icnpm i, 回车

在这里插入图片描述

我们可以在 node_modules 文件夹中查看是否真正安装完成

在这里插入图片描述

第四步:复制 ffmpeg-core.jsffmpeg-core.wasmffmpeg-core.worker.js 文件,放入静态资源文件夹中【说明:Vue项目创建完之后默认生成 public 文件夹(用来存放静态资源的),所以我们需要把它们三个复制一份放入 public 文件夹中(若静态资源文件夹名称改了,就放入改到的地方即可)】

在这里插入图片描述

第五步:在需要使用 ffmpeg 的 vue 组件中引入 ffmpeg

import FFmpeg from "@ffmpeg/ffmpeg";
const { createFFmpeg, fetchFile } = FFmpeg;
const ffmpeg = createFFmpeg({
  corePath: "./ffmpeg-core.js", // 核心文件的路径
  log: true, // 是否在控制台打印日志,true => 打印
});

至此,安装和配置 FFmpeg 就告一段落…


在 Vue 项目中使用 FFmpeg

在 Canvas 录制视频 一文中,我们编写了通过 MediaRecorder API 在 Canvas 画布中进行了页面的视频录制的代码,把它稍作改变放入 vue 组件中就得到了下面的代码

简单讲解一下:

  1. draw() 方法用于绘制画布上显示的内容
  2. startRecording() 方法用于开始对画布进行视频录制
  3. stopAndblobDownload() 方法用于结束对画布进行的视频录制,并使用 FFmpeg 对视频流进行处理(转换格式、设置帧率等)
<template>
  <div>
    <canvas id="webm-canvas" height="500" width="500" style="margin: auto"></canvas>
    <button @click="startRecording">开始录制</button>
    <button @click="stopAndblobDownload">停止录制</button>
  </div>
</template>

<script>
import FFmpeg from "@ffmpeg/ffmpeg";
const { createFFmpeg, fetchFile } = FFmpeg;
const ffmpeg = createFFmpeg({
  corePath: "./ffmpeg-core.js", // 核心文件的路径
  log: true, // 是否在控制台打印日志,true => 打印
});

export default {
  name: "HelloWorld",
  data() {
    return {
      recorder: null,
      allChunks: []
    };
  },
  mounted() {
    this.draw();
  },
  methods: {
    draw() {
      let canvas = document.getElementById("webm-canvas");
      let context = canvas.getContext("2d");
      // window.requestAnimationFrame(draw);
      var x = 0;
      var speed = 1;
      var text = "前端杂货铺";
      var fontSize = 20;
      setInterval(() => {
        // 清空画布(否则字体移动后颜色会遗留在画布上)
        context.clearRect(0, 0, canvas.width, canvas.height);
        // 设置字体
        context.font = fontSize + "px Arial"; //设置字体大小和类型
        context.fillStyle = "orange"; //设置文本颜色
        context.fillText(text, x, canvas.height / 2); //绘制文本
        // x要移动
        x += speed;
        // 如果文本达到画布边缘,改变方向
        if (x > canvas.width - 100 || x < 0) {
          speed = -speed;
        }
      }, 10);
    },
    startRecording() {
      let canvas = document.getElementById("webm-canvas");
      // 实时视频捕获画布,参数为帧率
      const stream = canvas.captureStream(60); // 60 FPS
      // 创建一个对指定的 stream 进行录制的 MediaRecorder 对象
      this.recorder = new MediaRecorder(stream, {
        mimeType: "video/webm;codecs=vp9", // 设置媒体类型
      });
      // 当数据有效时触发的事件,数据有效时可以把数据存储到缓存区里
      this.recorder.ondataavailable = (e) => {
        console.log("TCL: e", e);
        this.allChunks.push(e.data);
      };
      this.recorder.start(10);
    },
    async stopAndblobDownload() {
      // 异步加载 ffmpeg
      await ffmpeg.load();
      // 结束录像
      this.recorder.stop();
      // createElement() 方法通过指定名称创建一个元素
      const link = document.createElement("a");
      link.style.display = "none";
      // 创建一个 Blob 对象,用于存储二进制数据
      const fullBlob = new Blob(this.allChunks);
      let name = "demo";
      // 写文件,fullBlob 存放录制视频流的 blob 数据
      ffmpeg.FS("writeFile", name, await fetchFile(fullBlob));
      // 执行 ffmpeg ('-r', '10' 表示设置视频帧率为 10fps)('output.avi' 表示生成视频的格式为 .avi)
      await ffmpeg.run('-i', name, '-r', '10', 'output.avi');
      // 读取刚刚执行的文件,存放到 data 中
      const data = ffmpeg.FS('readFile', 'output.avi');
      // 把 data 的 buffer 数据传入 blob 实例中,创建一个包含所需数据的 URL
      const downloadUrl = window.URL.createObjectURL(new Blob([data.buffer], {type:'video/avi'}));
      // 获取或设置链接的 URL 属性
      link.href = downloadUrl;
      // 点击链接时,浏览器下载文件
      link.download = `前端杂货铺${Math.random().toFixed(4)}.avi`;
      // 向节点的子节点列表的末尾添加新的子节点
      document.body.appendChild(link);
      // 模拟用户点击链接的操作
      link.click();
      // 删除 HTML 文档中的链接元素
      link.remove();
    },
  },
};
</script>
<style>
canvas {
  box-shadow: 0 0 10px gray;
  display: block;
}

body {
  text-align: center;
}

button {
  margin-top: 20px;
}
</style>

此时,运行我们的项目,点击开始录制后,再点击结束录制

在这里插入图片描述

SharedArrayBuffer 的前世今生

此时,控制台就会暴露出一个问题:SharedArrayBuffer is not defined

在这里插入图片描述

不要慌,我们先来了解一下 SharedArrayBuffer 是什么?

MDN 上是这样解释的:SharedArrayBuffer 对象用来表示一个通用的原始二进制数据缓冲区,类似于 ArrayBuffer 对象,但它可以用来在共享内存上创建视图。与可转移的 ArrayBuffer 不同,SharedArrayBuffer 不是可转移对象。

官方的说明有点抽象。其实 SharedArrayBuffer 就是一种 JavaScript 对象,它允许多个 Web Worker 线程共享相同的内存空间。这就意味着不同的线程可以同时访问和修改相同的数据,而无需复制数据或担心数据同步的问题。它允许以更有效的方式进行多线程编程,从而提高性能。

那么此时为什么会报 SharedArrayBuffer is not defined 的错误呢?

这就要溯源到 2018 年了,其实在 2018 之前,在支持 SharedArrayBuffer 的各大主流浏览器中都是可以正常使用它的。直到 2018 年暴露出了 幽灵漏洞(Spectre漏洞)*,它导致了浏览器性能的严重倒退,各大主流浏览器厂商便都禁用了 SharedArrayBuffer!!

直到 2021 年才正式放开了对 SharedArrayBuffer 的使用。

SharedArrayBuffer 在各大主流浏览器中的支持情况:

在这里插入图片描述

既然都放开了对 SharedArrayBuffer 的使用,那么为什么还会报错呢?

虽然各大主流浏览器都已经陆续开始支持 SharedArrayBuffer ,但它也不是那么随便就能使用的,而是需要我们进行一些配置,开启了跨域隔离 才能正常使用。

在控制台中输入 crossOriginIsolated 回车,为 false,则说明并没有开启跨域隔离

在这里插入图片描述

解决 SharedArrayBuffer 报错问题

在我们的项目中创建并打开 vue.config.js 文件,如果你的项目使用了 webpack 打包工具,那么就打开你的 webpack.config.js 文件,进行如下配置,配置完成之后记得重启一下项目,让我们刚刚的配置生效

在这里插入图片描述

module.exports = {
    devServer: {
        headers: {
            "Cross-Origin-Opener-Policy": "same-origin", // 保护你的源站点免受攻击
            "Cross-Origin-Embedder-Policy": "require-corp", // 保护受害者免受你的源站点的影响
        },
    },
}

我们看一下是否开启了跨域隔离,为 true,确实已开启

在这里插入图片描述

此时,再点击开始录制后点击结束录制,控制台便不会报错了,并且还会生成我们所需要的视频文件,很完美

在这里插入图片描述


FFmpeg 的一些坑

我们解决了 SharedArrayBuffer 问题后,在 ffmpeg 执行的时候也可能遇到执行失败的问题。

比如说,在 webm 转 mp4 格式时当你的分辨率设置成奇数(比如:499x499)时,就可能导致 ffmpeg 转码失败(错误:width not divisible by 2 (499x499)),所以我们尽量控制把分辨率为偶数。

建议大家在开发过程中把 log: true 打开,方便调试开发!!


总结

本文,我们首先讲解了 FFmpeg 在 Vue 项目中的安装与配置,之后在 Vue 项目中编码简单使用了一下 FFmpeg,然后在运行项目时报了错让我们认识到了 SharedArrayBuffer 并成功找到了解决方案,最后我们了解到了 FFmpeg 在使用时的一些坑,明确了要注意查看 log 日志内容…

FFmpeg 无疑是一款非常强大的多媒体处理工具,在 Vue 项目中利用 “纯前端” 就能实现视频的录制和视频编码转码后的输出,这看起来确实是一件非常 cool 的事!

其实坚持学习,热爱生活得你更 cool

好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!


参考资料:

  1. 百度百科 · FFmpeg、幽灵漏洞
  2. MDN官方文档 · SharedArrayBuffer
  3. 由一个报错引发的浏览器跨域隔离探索【作者:网络安全小肖_知乎】
  4. Canvas录制视频【作者:前端杂货铺_CSDN】
  5. FFmpeg——使用Canvas录制视频尚存问题的解决方案 【作者:前端杂货铺_CSDN】

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1318151.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

滑动窗口训练

1.原理 我们用这道题目 LCR 008. 长度最小的子数组 来讲解“滑动窗口”的解法。 1.1.暴力解法 遍历每一个子数组&#xff08;都要大于等于 7&#xff09;&#xff0c;最统计出最小的数组。 这样做的话&#xff0c;划分左右区间&#xff08;left 和 right&#xff09;就需要…

怎样长时间保持SSH会话连接不断开?

操作场景 使用SSH方式登录CentOS Stream操作系统的云服务器时&#xff0c;过一段时间就会自动断开连接。 该文档适用于CentOS/EulerOS系统。 操作方法 编辑/etc/ssh/sshd_config文件设置心跳&#xff0c;保持连接。 编辑/etc/ssh/sshd_config&#xff0c;添加配置项&#x…

Flink系列之:监控反压

Flink系列之&#xff1a;监控反压 一、反压二、Task 性能指标三、示例四、反压状态 Flink Web 界面提供了一个选项卡来监控正在运行 jobs 的反压行为。 一、反压 如果你看到一个 task 发生 反压警告&#xff08;例如&#xff1a; High&#xff09;&#xff0c;意味着它生产数…

Android动画

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、动画实现3.1 帧动画资源文件中实现…

Linux线程的设计

文章目录 一.理解Linux线程的本质进程地址空间是进程访问系统资源的窗口Linux系统中,线程是比进程更轻量级的执行流 二.Linux线程独立运行的原理三.基础线程控制 一.理解Linux线程的本质 进程地址空间是进程访问系统资源的窗口 Linux系统中,线程是比进程更轻量级的执行流 线程…

IIS如何本地部署网站,作为局域网内的服务器

文章目录 IIS本地部署WebService1.使用IIS及WebService的原因:2.相关文件说明及网络条件说明&#xff1a;&#xff08;1&#xff09;文件说明&#xff1a;&#xff08;2&#xff09;网络条件说明&#xff1a; 3.IIS安装与配置&#xff1a;第一步&#xff1a;安装第二步&#xf…

全国职业院校技能大赛“大数据应用开发”赛项说明

1、赛项介绍 &#xff08;1&#xff09;赛项名称 全 国 职 业 院 校 技 能 大 赛 “大数据应用开发” 赛 项 职业院校技能大赛官网 (vcsc.org.cn)https://www.vcsc.org.cn/ 大赛组织机构介绍 全国职业院校技能大赛(以下简称大…

Python 爬虫开发完整环境部署,爬虫核心框架安装

Python 爬虫开发完整环境部署 前言&#xff1a; ​ 关于本篇笔记&#xff0c;参考书籍为 《Python 爬虫开发实战3 》 笔记做出来的一方原因是为了自己对 Python 爬虫加深认知&#xff0c;一方面也想为大家解决在爬虫技术区的一些问题&#xff0c;本篇文章所使用的环境为&#x…

网络攻击1——网络安全基本概念与终端安全介绍(僵尸网路、勒索病毒、木马植入、0day漏洞)

目录 网络安全的基本术语 黑客攻击路径 终端安全 僵尸网络 勒索病毒 挖矿病毒 宏病毒 木马的植入 0day漏洞 流氓/间谍软件 网络安全的基本术语 网络安全的定义&#xff08;CIA原则&#xff09; 数据的保密性Confidentiality&#xff08;对称/非对称秘钥&#xff09; …

mysql innodb知识记录

官方文档 官网架构图 innodb 特性 内存 buffer pool 采用优化后的LRU算法&#xff0c; 3/8 of the buffer pool is devoted to the old sublist.The midpoint of the list is the boundary where the tail of the new sublist meets the head of the old sublist.When In…

C语言-Makefile

Makefile 什么是make&#xff1f; make 是个命令&#xff0c;是个可执行程序&#xff0c;用来解析 Makefile 文件的命令这个命令存放在 /usr/bin/ 什么是 makefile? makefile 是个文件&#xff0c;这个文件中描述了我们程序的编译规则咱们执行 make 命令的时候&#xff0c; m…

[DroneCAN]CAN-Convertor控制CAN电调电机

简介 CAN电调电机是一类通过CAN协议控制转速的电调电机&#xff0c;和传统的PWM电调电机不同在于&#xff0c;CAN协议有网络性和抗干扰性&#xff0c;因此其性能比PWM更好&#xff0c;占用的端口数也会更少。在apm或者px4等基于dronecan的飞控来说&#xff0c;想要控制第三方的…

【CMU 15-445】Lecture 10: Sorting Aggregations Algorithms 学习笔记

Sorting & Aggregations Algorithms SortingTop-N Heap SortExternal Merge Sort2-WAY External Merge SortK-WAY External Merge SortDouble Buffering Optimization AggregationsSortingHashing 本节课主要介绍的是数据库系统中的排序算法以及聚合算法 Sorting 排序算法…

大模型自定义算子优化方案学习笔记:CUDA算子定义、算子编译、正反向梯度实现

01算子优化的意义 随着大模型应用的普及以及算力紧缺&#xff0c;下一步对于计算性能的追求一定是技术的核心方向。因为目前大模型的计算逻辑是由一个个独立的算子或者说OP正反向求导实现的&#xff0c;底层往往调用的是GPU提供的CUDA的驱动程序。如果不能对于整个计算过程学习…

LearnDash LMS ProPanel在线学习系统课程创作者的分析工具

点击阅读LearnDash LMS ProPanel在线学习系统课程创作者的分析工具原文 LearnDash LMS ProPanel在线学习系统课程创作者的分析工具通过整合报告和作业管理来增强您的 LearnDash 管理体验&#xff0c;使您能够发送特定于课程的通信&#xff0c;并显示课程的实时活动&#xff01…

分类信息网商业运营版源码系统:适合各类行业分类站点建站 带安装部署教程

随着互联网的快速发展&#xff0c;信息分类网站在各个行业中得到了广泛应用。为了满足不同行业的需求&#xff0c;罗峰给大家分享一款适合各类行业分类站点建站的商业运营版源码系统。该系统旨在提供一套完整的解决方案&#xff0c;帮助用户快速搭建自己的分类信息网站&#xf…

【最新版】在WSL上运行 Linux GUI (图形用户界面)应用(Gnome 文本编辑器、GIMP、Nautilus、VLC、X11 应用)

文章目录 一、 安装WSL0. 先决条件1. 全新安装2. 现有 WSL 安装3. 注意事项 二、运行 Linux GUI 应用1. 更新发行版中的包2. 安装 Gnome 文本编辑器启动 3. 安装 GIMP启动 4. 安装 Nautilus启动 5. 安装 VLC启动 6. 安装 X11 应用 适用于 Linux 的 Windows 子系统 (WSL) 现在支…

Javaweb考前复习冲刺(不断更新版)

Javaweb考前复习冲刺 第一章&#xff1a; JavaWeb 入门 JavaWeb是指&#xff1a;以Java作为后台语言的项目工程。 javaweb项目创建的过程&#xff1a; 首先集成Tomcat服务器环境新建dynamic web project部署工程运行 路由含义&#xff1a; ​ http://localhost:8080/工程…

Redis 主从集群 —— 超详细操作演示!

五、Redis 主从集群 五、Redis 主从集群5.1 主从集群搭建5.1.1、伪集群搭建与配置5.1.2、分级管理5.1.3、容灾冷处理 5.2 主从复制原理5.2.1、主从复制原理5.2.2、数据同步演变过程 5.3 哨兵机制实现5.3.1 简介5.3.2 Redis高可用集群搭建5.3.3 Redis高可用集群的启动5.3.4 Sent…

ubuntu创建apt-mirror本地仓库

首先创建apt-mirror的服务端&#xff0c;也就是存储所有apt-get下载的文件和依赖。大约需要300G&#xff0c;预留400G左右空间就可以开始了。 安装ubuntu省略&#xff0c;用的是ubuntu202204 ubuntu挂载硬盘&#xff08;不需要的可以跳过&#xff09;: #下载挂载工具 sudo apt…