react:ffcreator中FFCreatorCenter视频队例
最近项目要求,一键生成房子的推荐视频,选几张图,加上联系人的方式就是一个简单的视频,因为有web端、小程序端,为了多端口用,决定放在服务器端生成。
目前用的是react中的nextjs来开发项目。
nextjs中怎样用ffcreator上一章有讲到过,这里不再详细说了,考虑多端口用,并发和处理视频合成等一系列对服务器压力过大的情况,这时候队列就有必要了。
一通了解后FFCreatorCenter能实现队列。官方有koa实现队列的例子。看过后怎样在nextjs中实现?
找准思路:
1.制作预设视频动画模板,意思是合成视频的模板提前预设好的,比如静态内容都提前准备好
2.用户选择想要的视频模板,然后根据视频模板添加动态内容,排队生成视频
3.查询视频生成情况
按照上述流程,我们开干:
1。制作预设视频模板,做一个模板比如相册视频,放到模板详情接口中调用AddTPL(id)
import { FFAlbum, FFScene, FFImage, FFCreator, FFRect, FFText, FFCreatorCenter } from 'ffcreator'
const path = require('path');
import colors from 'colors'
export default function AddTPL({ id }) {FFCreatorCenter.createTemplate(id, async ({ }) => {
//用官方图片例子const ROOT_PATH = process.cwd();const bg1 = path.join(ROOT_PATH, '/assets/imgs/bg/05.jpg');console.log(bg1)const bg2 = path.join(ROOT_PATH, '/assets/imgs/bg/04.jpeg');const logo2 = path.join(ROOT_PATH, '/assets/imgs/logo/logo2.png');const cloud = path.join(ROOT_PATH, '/assets/imgs/cloud.png');const mars = path.join(ROOT_PATH, '/assets/imgs/mars.png');const rock = path.join(ROOT_PATH, '/assets/imgs/rock.png');const title = path.join(ROOT_PATH, '/assets/imgs/title.png');const audio = path.join(ROOT_PATH, '/assets/audio/05.wav');const outputDir = path.join(ROOT_PATH, '/video/');const cacheDir = path.join(ROOT_PATH, '/cache/');FFCreator.setFFmpegPath('D:/nextAppV2/H5/ffmpeg-6.0-full_build/bin/ffmpeg.exe');// create creator instanceconst width = 576;const height = 1024;const creator = new FFCreator({cacheDir,outputDir,width,height,//log: true,highWaterMark: '3mb',parallel: 8,fps: 30,audio,});// create FFSceneconst scene1 = new FFScene();const scene2 = new FFScene();scene1.setBgColor('#0b0be6');scene2.setBgColor('#b33771');// add scene1 backgroundconst fbg1 = new FFImage({ path: bg1, x: width / 2, y: height / 2 });scene1.addChild(fbg1);// add bottom cloudconst fcloud = new FFImage({ path: cloud, x: width });fcloud.setAnchor(1);fcloud.addAnimate({from: { y: height + 180 },to: { y: height },time: 0.8,ease: 'Back.Out',});scene1.addChild(fcloud);// add mars ballconst fmars = new FFImage({ path: mars, x: width / 2, y: height / 2 });fmars.addEffect(['rollIn', 'zoomIn'], 1.8, 0.8);scene1.addChild(fmars);// add rock imageconst frock = new FFImage({ path: rock, x: width / 2 + 100 });frock.addAnimate({from: { y: height / 2 + 720 },to: { y: height / 2 + 80 },time: 1,delay: 2.3,ease: 'Cubic.InOut',});scene1.addChild(frock);// add rock imageconst ftitle = new FFImage({ path: title, x: width / 2, y: height / 2 - 300 });ftitle.addEffect('fadeInUp', 1, 4);scene1.addChild(ftitle);// add logoconst flogo1 = new FFImage({ path: logo2, x: width / 2, y: 50 });flogo1.setScale(0.5);scene1.addChild(flogo1);scene1.setDuration(8);scene1.setTransition('InvertedPageCurl', 1.5);creator.addChild(scene1);// add scene2 backgroundconst fbg2 = new FFImage({ path: bg2, x: width / 2, y: height / 2 });scene2.addChild(fbg2);// add logoconst flogo2 = new FFImage({ path: logo2, x: width / 2, y: height / 2 - 80 });flogo2.setScale(0.9);flogo2.addEffect('fadeInDown', 1, 1.2);// 9s removeflogo2.remove(9);scene2.addChild(flogo2);scene2.setDuration(5);creator.addChild(scene2);creator.start();//creator.openLog();creator.on('start', () => {console.log(`FFCreator start`);});creator.on('error', e => {console.log(`FFCreator error: ${e.error}`);});creator.on('progress', e => {console.log(colors.yellow(`FFCreator progress: ${(e.percent * 100) >> 0}%`));});creator.on('complete', e => {console.log(colors.magenta(`FFCreator completed: \n USEAGE: ${e.useage} \n PATH: ${e.output} `),);console.log(colors.green(`\n --- You can press the s key or the w key to restart! --- \n`));});return creator;
})
}
2.添加队列,
//添加队列
export function AddTask({ Templateid }) {const Taskid = FFCreatorCenter.addTaskByTemplate(Templateid, { });res.statusCode = 200res.json({code: 0,data: {taskid: Taskid}})
}
3.查询成功接口,并下载mp4
//下载
import { FFAlbum, FFScene, FFImage, FFCreator, FFRect, FFText, FFCreatorCenter } from 'ffcreator'
export default async (req, res) => {
const taskid = req.query.taskid
var fs = require('fs');FFCreatorCenter.onTaskError(taskid, function (err) {console.log("onTaskError", err)})FFCreatorCenter.onTaskComplete(taskid, function (e) {console.log("onTaskComplete", e)let { file, taskObj } = elet output = file ? file.replace(/\/\//g, "/") : ""fs.readFile(output, function (isErr, data) {if (isErr) {} else {let file_name = new Date().getTime()let Disposition = "inline;";if (scene == "pwa") {Disposition = "attchment;";}if (scene == "mini") {Disposition = "inline;";}res.setHeader('Content-Type', 'video/mp4; charset=utf-8');res.setHeader('Content-Disposition', `${Disposition}filename=${encodeURIComponent(file_name)}.mp4`);res.status(200)res.end(data)}})})}
另附上视频转gif的方法:
let cp = require('child_process');let flie_gif = `${cacheDir}${taskid}.gif`const bb = `ffmpeg -ss 00:00:00 -to 00:00:${videoConfig.duration} -i ${output} -r 10 -vf scale=1050:-1 ${flie_gif}`cp.exec(bb,function (error, stdout, stderr) {if (error) {console.log('执行的结果error:', error)} else {fs.readFile(flie_gif, function (isErr, data) {if (isErr) {console.log('执行的结果error:', isErr)} else {let file_name = new Date().getTime()let Disposition = "inline;";if (scene == "pwa") {Disposition = "attchment;";}if (scene == "mini") {Disposition = "inline;";}res.setHeader('Content-Type', 'image/gif; charset=utf-8');res.setHeader('Content-Disposition', `${Disposition}filename=${encodeURIComponent(file_name)}.gif`);res.status(200)res.end(data)}})}// console.log('执行的结果stdout:', stdout)// console.log('执行的结果stderr:', stderr)})
相关文章:
react:ffcreator中FFCreatorCenter视频队例
最近项目要求,一键生成房子的推荐视频,选几张图,加上联系人的方式就是一个简单的视频,因为有web端、小程序端,为了多端口用,决定放在服务器端生成。 目前用的是react中的nextjs来开发项目。 nextjs中怎样…...
力扣(leetcode)第434题字符串中的单词数(Python)
434.字符串中的单词数 题目链接:434.字符串中的单词数 统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。 请注意,你可以假定字符串里不包括任何不可打印的字符。 示例: 输入: “Hello, my name is John” 输出: 5 解释: 这…...
django学习:页面渲染与请求和响应
1.请求过程 2.页面渲染 在app中新建一个目录(Directory),文件名命名为templates。该文件名命名是固定的,不可命名出错,如若后续步骤出错,该目录文件名是一个检查的重点项目。在该目录下新建一个html文件&a…...
Redis 数据一致性
概述 当我们在使用缓存时,如果发生数据变更,那么你需要同时操作缓存和数据库,而它们两个又分属不同的系统,因此无法做到同时操作成功或失败,因此在并发读写下很可能出现缓存与数据库数据不一致的情况 理论上可以通过…...
Mac环境下反编译apk
Mac环境下反编译apk 安装反编译工具dex2jar:[官网下载](https://sourceforge.net/projects/dex2jar/)JD-GUI:[官网下载](https://jd-gui.apponic.com/) 实操1. 将需要反编译的 .apk 文件放在下载的 dex2jar 文件夹目录下2. 使用 cd /xxx/dex2jar-2.0 命令…...
计算机网络——网络模型的组织、看法以及标准化流程
1. 通信技术和标准化领域中扮演重要角色的组织 1.1 国际和国家官方标准化机构 OSI:国际标准化组织(ISO),负责国际标准的制定,旨在确保全球产品和服务的安全性、可靠性和效率。它有许多国家分支机构,包括法…...
【JAVA】volatile 关键字的作用
🍎个人博客:个人主页 🏆个人专栏: JAVA ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 volatile 的作用: 结语 我的其他博客 前言 在多线程编程中,保障数据的一致性和线程之间的可见性是…...
Next.js 第一次接触
因为需要整个漂亮的在线文档,所以接触了next.js,因为对前端js本身不够熟悉,别说对react.js 又不会,时间又不允许深入研究,所以,为了加一个导航菜单,极其痛苦。 有点小bug,不过不影响…...
CISSP 第7章:PKI和密码学应用
第七章 PKI和密码学应用 7.1 非对称密码学 对称密码系统具有共享的秘钥系统,从而产生了安全秘钥分发的问题 非对称密码学使用公钥和私钥对,无需支出复杂密码分发系统 7.1.1 公钥与私钥 7.1.2 RSA(兼具加密和数字签名) RSA算法依赖…...
dji uav建图导航系列()ROS中创建dji_sdk节点包(二)实现代码
在前文 【dji uav建图导航系列()ROS中创建dji_sdk节点包(一)项目结构】中简单介绍了项目的结构,和一些配置文件的代码。本文详细说明目录src下的节点源代码实现。 文章目录 1、代码结构2、PSDK部分3、ROS部分3.1、头文件3.1.1、外部调用 node_service.h3.1.2、节点类定义…...
数字化工厂产品推荐 带OPC UA的分布式IO模块
背景 近年来,为了提升在全球范围内的竞争力,制造企业希望自己工厂的机器之间协同性更强,自动化设备采集到的数据能够发挥更大的价值,越来越多的传统型工业制造企业开始加入数字化工厂建设的行列,实现智能制造。 数字化…...
使用OHOS SDK构建opus
参照OHOS IDE和SDK的安装方法配置好开发环境。 从github下载源码。 执行如下命令: git clone --depth1 https://github.com/xiph/opus进入源码所在的目录,创建批处理文件ohos_build.cmd,内容如下: echo off setlocalset OHOS_…...
K-means 聚类算法分析
算法简述 K-means 算法原理 我们假定给定数据样本 X ,包含了 n 个对象 ,其中每一个对象都具有 m 个维度的属性。而 K-means 算法的目标就是将 n 个对象依据对象间的相似性聚集到指定的 k 个类簇中,每个对象属于且仅属于一个其到类簇中心距离…...
uniapp获取定位
Uniapp 是一种跨平台应用开发框架,它能够快速地构建出针对不同平台的应用程序。在Uniapp中,实现定位功能也变得十分简单,只需要简单的配置就能轻松实现。 一、高德地图根据指定位置获取经纬度 参考地址:地理/逆地理编码-基础 API…...
Python 面向对象之反射
Python 面向对象之反射 【一】概念 反射是指通过对象的属性名或者方法名来获取对象的属性或调用方法的能力反射还指的是在程序额运行过程中可以动态获取对象的信息(属性和方法) 【二】四个内置函数 又叫做反射函数 万物皆对象(整数、字符串、函数、模块、类等等…...
HPM6750开发笔记《DMA接收和发送数据UART例程深度解析》
目录 概述: 端口设置: 代码分析: 运行现象: 概述: DMA(Direct Memory Access)是一种计算机系统中的数据传输技术,它允许数据在不经过中央处理器(CPU)的直…...
SQL IN 操作符
IN 操作符 IN 操作符允许您在 WHERE 子句中规定多个值。 SQL IN 语法 SELECT column1, column2, ... FROM table_name WHERE column IN (value1, value2, ...); 参数说明: column1, column2, ...:要选择的字段名称,可以为多个字段。如果…...
如何使用Plex在Windows系统搭建个人媒体站点公网可访问
文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 用手机或者平板电脑看视频,已经算是生活中稀松平常的场景了,特别是各…...
web前端——clear可以清除浮动产生的影响
clear可以解决高度塌陷的问题,产生的副作用要小 未使用clear之前 <!DOCTYPE html> <head><meta charset"UTF-8"><title>高度塌陷相关学习</title><style>div{font-size:50px;}.box1{width:200px;height:200px;backg…...
centos用yum安装mysql详细教程
1 查询安装mysql的yum源,命令如下 ls /etc/yum.repos.d/ -l 界面如下图所示,未显示mysql的安装源 2 安装mysql相关的yum源,例如: 例如:rpm -ivh mysql57-community-release-el7.rpm 要注意 mysql的版本和系统的版本匹配 mysql57-communi…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
