video素材格式转换--mp4转webm(vue3+Nodejs)

news2024/11/12 17:20:40

总体实现使用ffmpeg


自动化demo实现 vue3+Nodejs+ffmpeg

一、官网下载ffmpeg

https://ffmpeg.org/

1-1选择对应系统下载

1-2下载完成后配置环境变量

1-2-1将下载文件的bin目录配置到环境变量中

例如:D:\ffmpeg\bin

1-3测试ffmpeg是否安装成功

ffmpeg -version

如图 证明安装成功!!!!

二、手动使用命令转video格式

cmd 打开视频所在目录 

等待完成即可!

三、自动化demo

工作中 有比较大的素材量 可直接上传文件等待转type即可 完成后下载视频

代码示例:

3-1 vue3

<template>
  <div>
    <a-upload
      name="file"
      action="http://localhost:3000/uploadWebm"
      @change="handleChange"
    >
      <a-button>
        <upload-outlined></upload-outlined>
        请上传视频
      </a-button>
    </a-upload>
    <video :src="url" controls v-if="url"></video>
  </div>
</template>
<script setup>
import { ref } from "vue";
import { message } from "ant-design-vue";
import { UploadOutlined } from "@ant-design/icons-vue";

const url = ref("");
const checkTaskInterval = ref(null); // 将定时器ID存储在响应式引用中

const checkTaskStatus = async () => {
  try {
    const response = await fetch("http://localhost:3000/status", {
      method: "GET",
    });
    if (response.ok) {
      const data = await response.json();
      console.log(data.event, "data.event");
      if (data.event === "end") {
        console.log("endend");
        clearInterval(checkTaskInterval.value); // 使用响应式引用的值来清除定时器
        checkTaskInterval.value = null; // 将响应式引用的值设置为null
        url.value = data.data.url;
      } else if (data.event === "error") {
        clearInterval(checkTaskInterval.value);
        checkTaskInterval.value = null;
        message.error("上传失败:" + data.data);
      }
    }
  } catch (error) {
    message.error("上传失败");
    console.error("上传失败:", error);
    clearInterval(checkTaskInterval.value);
    checkTaskInterval.value = null;
  }
};

const handleChange = async (info) => {
  console.log(info);
  // 清除之前的定时器(如果有)
  if (checkTaskInterval.value) {
    clearInterval(checkTaskInterval.value);
  }
  checkTaskInterval.value = setInterval(() => {
    checkTaskStatus();
  }, 3000);
};
</script>
<style lang="less" scoped>
</style>

3-2 Nodejs

3-2-1安装 fluent-ffmpeg

npm install fluent-ffmpeg --save

3-2-2 完整代码示例 

var express = require('express');
var router = express.Router();
var multiparty = require('multiparty');
const multer = require('multer')
const upload = multer({ dest: 'upload/' })
const { execFile } = require('child_process');
const path = require('path');
const fs = require('fs');
const ffmpeg = require('fluent-ffmpeg');
const ffmpegPath = path.join('d:', 'ffmpeg', 'bin', 'ffmpeg.exe');//ffmpeg.exe的路径
const iconv = require('iconv-lite'); // 用于处理中文路径
ffmpeg.setFfmpegPath(ffmpegPath);

//video转webm
router.post('/uploadWebm', upload.single('file'), (req, res) => {
  const file = req.file;
  const srcPath = file.path;
  console.log(file.originalname, "file.originalname");

  const originalNameBuffer = Buffer.from(file.originalname, 'binary');
  const utf8Name = iconv.decode(originalNameBuffer, 'UTF-8'); // 将文件名从二进制转换为 UTF-8 编码
  const dstPath = path.join('upload', `${path.basename(utf8Name, path.extname(utf8Name))}.webm`);
  console.log(dstPath, "dstPath");
  // 初始化状态信息
  statusInfo = {
    event: "start",
    data: `Started processing ${file.originalname}`,
    finished: false
  };

  ffmpeg(srcPath)
  .on('start', (commandLine) => {
    statusInfo.event = "start";
    statusInfo.data = commandLine;
  })
  .on('progress', (progress) => {
    statusInfo.event = "progress";
    statusInfo.data = progress;
  })
  .on('error', (err) => {
    statusInfo.event = "error";
    statusInfo.data = err;
    statusInfo.finished = true;
    res.status(500).send({ code: 500, event: "error", data: err });
    fs.unlinkSync(srcPath);
  })
  .on('end', () => {
    statusInfo.event = "end";
    statusInfo.data = {message: "Processing finished", url: `http://localhost:3000/upload/${path.basename(dstPath)}`};
    statusInfo.finished = true;
    fs.unlinkSync(srcPath);
  })
  .addOption('-c:v libvpx-vp9')
  .addOption('-c:a libopus')
  .addOption('-b:v 1M')
  .addOption('-b:a 128k')
  .toFormat('webm')
  .save(dstPath);
});

// 客户端轮询的接口
router.get('/status', (req, res) => {
  const filename = req.params.filename;
  if (statusInfo && !statusInfo.finished) {
    res.send({ code: 200, event: statusInfo.event, data: statusInfo.data });
  } else if (statusInfo) {
    res.send({ code: 200, event: statusInfo.event, data: statusInfo.data });
  } else {
    res.status(404).send({ code: 404, message: "File not found" });
  }
});


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

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

相关文章

YOLOPv2论文翻译

YOLOPv2: Better, Faster, Stronger for Panoptic Driving Perception 摘要 在过去的十年中&#xff0c;多任务学习方法在解决全景驾驶感知问题方面取得了令人鼓舞的成果&#xff0c;既提供了高精度又具备高效能的性能。在设计用于实时实际自动驾驶系统的网络时&#xff0c;这…

Golang | Leetcode Golang题解之第553题最优除法

题目&#xff1a; 题解&#xff1a; func optimalDivision(nums []int) string {n : len(nums)if n 1 {return strconv.Itoa(nums[0])}if n 2 {return fmt.Sprintf("%d/%d", nums[0], nums[1])}ans : &strings.Builder{}ans.WriteString(fmt.Sprintf("%d…

基于LORA的一主多从监测系统_实物展示

提供&#xff1a;成品硬件 4G模块 详细开发流程 源码 原理图 主节点和子节点A的合照来一张 主节点 子节点A

教程:FFmpeg结合GPU实现720p至4K视频转换

将一个 720p 的视频放大编码到 4K&#xff0c;这样的视频处理在很多业务场景中都会用到。很多视频社交、短视频、视频点播等应用&#xff0c;都会需要通过服务器来处理大量的视频编辑需求。 本文我们会探讨一下做这样的视频处理&#xff0c;最低的 GPU 指标应该是多少。利用开源…

css | padding vs margin

前置知识 height是作用域内容(content)区域的 padding和margin用百分比的时候是怎么算的&#xff1f;父元素的宽度。注意&#xff0c;不是根据父元素相应的属性&#xff0c;就是父亲的width 自身的height是0 以下代码&#xff0c;外面盒子是100x10的&#xff0c;里面的widt…

监控架构- Grafana-监控大屏

1. Grafana极速上手指南 1.1 环境准备 主机ip地址grafana10.0.0.66zabbix_server10.0.0.62 1.2 部署grafana 9.3.6 ##去官网找rpm包下载并上传 ## 安装 yum localinstall -y grafana-9.3.6-1.x86_64.rpm## 启动服务并设置开机自启动 systemctl enable --now grafana-server…

数据分析反馈:提升决策质量的关键指南

内容概要 在当今快节奏的商业环境中&#xff0c;数据分析与反馈已成为提升决策质量的重要工具。数据分析不仅能为企业提供全面的市场洞察&#xff0c;还能帮助管理层深入了解客户需求与行为模式。掌握数据收集的有效策略和工具&#xff0c;企业能够确保获得准确且相关的信息&a…

SpringBoot助力的共享汽车业务优化系统

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

【启程Golang之旅】从零开始构建可扩展的微服务架构

欢迎来到Golang的世界&#xff01;在当今快节奏的软件开发领域&#xff0c;选择一种高效、简洁的编程语言至关重要。而在这方面&#xff0c;Golang&#xff08;又称Go&#xff09;无疑是一个备受瞩目的选择。在本文中&#xff0c;带领您探索Golang的世界&#xff0c;一步步地了…

多个NVR同时管理EasyNVR多品牌NVR管理工具/设备:IP常见问题解决方案

随着视频监控技术的不断发展&#xff0c;NVR&#xff08;网络视频录像机&#xff09;已经成为现代安防系统的重要组成部分。而为了更高效地管理多个品牌的NVR设备&#xff0c;EasyNVR这一多品牌NVR管理工具应运而生。然而&#xff0c;在实际使用过程中&#xff0c;尤其是在多个…

GS-Blur数据集:首个基于3D场景合成的156,209对多样化真实感模糊图像数据集。

2024-10-31&#xff0c;由韩国首尔国立大学的研究团队创建的GS-Blur数据集&#xff0c;通过3D场景重建和相机视角移动合成了多样化的真实感模糊图像&#xff0c;为图像去模糊领域提供了一个大规模、高覆盖度的新工具&#xff0c;显著提升了去模糊算法在真实世界场景中的泛化能力…

一文熟悉新版llama.cpp使用并本地部署LLAMA

0. 简介 最近是快到双十一了再给大家上点干货。去年我们写了一个大模型的系列&#xff0c;经过一年&#xff0c;大模型的发展已经日新月异。这一次我们来看一下使用llama.cpp这个项目&#xff0c;其主要解决的是推理过程中的性能问题。主要有两点优化&#xff1a; llama.cpp …

VMWareTools安装及文件无法拖拽解决方案

文章目录 1 安装VMWare Tools2 安装vmware tools之后还是无法拖拽文件解决方案2.1 确认vmware tools安装2.2 客户机隔离2.3 修改自定义配置文件2.4 安装open-vm-tools-desktop软件 1 安装VMWare Tools 打开虚拟机VMware Workstation&#xff0c;启动Ubuntu系统&#xff0c;菜单…

Maven的依赖管理、传递、冲突、父子工程的继承和聚合

目录 一、基于IDEA 进行Maven依赖管理 (一)依赖管理概念 (二)Maven工程核心信息配置和解读&#xff08;GAVP&#xff09; (三)Maven工程依赖管理配置 1.依赖管理和依赖添加 2.依赖版本统一提取和维护 (四)依赖范围 (五)Maven工程依赖下载失败错误解决&#xff08;重点…

华为云计算知识总结——及案例分享

目录 一、华为云计算基础知识二、华为云计算相关案例实战案例一&#xff1a;搭建弹性云服务器&#xff08;ECS&#xff09;并部署Web应用案例二&#xff1a;构建基于OBS的图片存储和分发系统案例三&#xff1a;基于RDS的高可用数据库应用案例四&#xff1a;使用华为云DDoS防护保…

证件照尺寸168宽240高,如何手机自拍更换蓝底

在提供学籍照片及一些社会化考试报名时&#xff0c;会要求我们提供尺寸为168*240像素的电子版证件照&#xff0c;本文将介绍如何使用“报名电子照助手”&#xff0c;借助手机拍照功能完成证件照的拍摄和背景更换&#xff0c;特别是如何将照片尺寸调整为168像素宽和240像素高&am…

智能出行助手:SpringBoot共享汽车管理平台

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理共享汽车管理系统的相关信息成为必然。开发…

cell队列监控

1.cell队列监控 基于Windows定时计划任务&#xff0c;通过Windows bat脚本监控Cell队列&#xff0c;当Source Cell队列有告警没有传递至Destination Cell时&#xff0c;能够及时发出告警。 Cell_Queue_Monitoring.bat ::关闭命令回显 echo off::日志目录创建 if not exist &…

基于java+SpringBoot+Vue的师生共评作业管理系统设计与实现

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven mysql5.7或8.0等等组成&#x…

Leetcode刷题Python之540.有序数组中的单一元素

提示&#xff1a;使用二分查找降低时间复杂度。 文章目录 一、问题描述示例 二、解题思路三、代码实现代码解析 总结 一、问题描述 给你一个仅由整数组成的有序数组&#xff0c;其中每个元素都会出现两次&#xff0c;唯有一个数只会出现一次。请你找出并返回只出现一次的那个数…