ffmpeg转码与加水印
文章目录
- 转码 与加水印
- 引入jar包
- 代码
- ffmpeg安装
- 错误
- 解决方法
转码 与加水印
引入jar包
<dependency><groupId>net.bramp.ffmpeg</groupId><artifactId>ffmpeg</artifactId><version>0.6.2</version></dependency>
代码
import lombok.extern.slf4j.Slf4j;
import net.bramp.ffmpeg.FFmpeg;
import net.bramp.ffmpeg.builder.FFmpegBuilder;
import net.bramp.ffmpeg.job.FFmpegJob;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;/*** @description 阿里云文件上传** @author lilinchun* @date 2024/10/17*/
@Slf4j
public class OssUtil {public static void main(String[] args) {String videoUrl = "xxx.mp4";try {convertAndUpload(videoUrl);} catch (Exception e) {e.printStackTrace();System.err.println("转换和上传失败: " + e.getMessage());}}/*** 将mp4文件url地址转换并上传到oss中* @param url mp4地址* @return m3u8文件地址*/public static String convertAndUpload(String url) throws Exception {String vodId = null;// 截取文件名称String fileName = url.substring(url.lastIndexOf('/') + 1);int lastDotIndex = fileName.lastIndexOf('.');String name = fileName.substring(0, lastDotIndex);String fileNameNew = name+"mark"+".mp4";// 当前项目的文件路径Path tempDir = Files.createTempDirectory("ffmpeg-temp");Path inputFilePath = tempDir.resolve(fileName);Path inputFilePathWatermark = tempDir.resolve(fileNameNew);Path outputM3U8Path = tempDir.resolve(name + ".m3u8");// 创建TS文件输出目录Path outputTSDir = tempDir.resolve(name + "_ts");Files.createDirectories(outputTSDir);log.info("临时文件路径:{}", tempDir.toString());try {downloadFileNew(url, tempDir.toString());// 设置水印watermarkVoid(inputFilePath,inputFilePathWatermark);// 转换生成M3U8和TS文件 指定播放片段为20sString ffmpegCommand = String.format("ffmpeg -i %s -codec: copy -start_number 0 -hls_time 20 -hls_list_size 0 -f hls -hls_segment_filename %s/%s_%%03d.ts %s",inputFilePathWatermark.toAbsolutePath(),outputTSDir.toAbsolutePath(),name,outputM3U8Path.toAbsolutePath());// 执行FFmpeg命令转换视频Process process = Runtime.getRuntime().exec(ffmpegCommand);process.waitFor();String indexFile = outputM3U8Path.toString();List<String> tsFiles = new ArrayList<>();System.out.println("解析文件路径地址:" + outputM3U8Path);for (int i = 0; ; i++) {Path tsFilePath = outputTSDir.resolve(String.format("%s_%03d.ts", name, i));if (!Files.exists(tsFilePath)) {break;}System.out.println("解析文件路径ts地址:" + tsFilePath);tsFiles.add(tsFilePath.toString());}// 上传阿里云视屏点播服务vodId = UploadVodByApi.uploadVideo(indexFile, tsFiles, name + ".m3u8");// 清理临时文件cleanup(tempDir);log.info("临时文件路径:{}", tempDir.toString());} catch (IOException e) {e.printStackTrace();log.error("文件转换失败:{}", e.getMessage());}return vodId;}/*** 设置视屏水印* @param inputFilePath 原始视屏路径* @param inputFilePathWatermark 水印视屏路径*/private static void watermarkVoid(Path inputFilePath,Path inputFilePathWatermark){log.info("文件名称:{},{}",inputFilePath.toAbsolutePath(),inputFilePathWatermark.toAbsolutePath());// 构建FFmpeg命令String ffmpegCommandWatermark = String.format("ffmpeg -i \"%s\" -vf \"drawtext=text='nk.benwunet.com':x=mod(n\\,w+tw)-tw:y=10:fontsize=24:fontcolor=white\" -codec:a copy \"%s\"",inputFilePath.toAbsolutePath(),inputFilePathWatermark.toAbsolutePath());log.info("执行加水印的命令:{}",ffmpegCommandWatermark);try {// 使用ProcessBuilder来启动外部进程// 使用ProcessBuilder来启动外部进程ProcessBuilder processBuilder = new ProcessBuilder("ffmpeg", "-i", inputFilePath.toAbsolutePath().toString(),"-vf", "drawtext=text='nk.benwunet.com':x=mod(n\\,w+tw)-tw:y=10:fontsize=24:fontcolor=white","-codec:a", "copy",inputFilePathWatermark.toAbsolutePath().toString());// 将错误输出重定向到标准输出processBuilder.redirectErrorStream(true);Process process = processBuilder.start();// 读取输出BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));String line;while ((line = reader.readLine()) != null) {log.info(line);}// 等待进程完成int exitCode = process.waitFor();if (exitCode == 0) {log.info("Video watermarking completed successfully.");} else {log.error("FFmpeg command failed with exit code: " + exitCode);}// 关闭资源reader.close();}catch (Exception e){log.error("Error occurred while processing the video: ", e);}}/*** 下载文件* @param urlStr 文件地址* @param saveDir 文件路径* @throws IOException 异常*/public static void downloadFileNew(String urlStr, String saveDir) throws IOException {CloseableHttpClient httpClient = HttpClientSingleton.getInstance();HttpGet request = new HttpGet(urlStr);try (CloseableHttpResponse response = httpClient.execute(request)) {int responseCode = response.getStatusLine().getStatusCode();if (responseCode == 200) {String fileName = urlStr.substring(urlStr.lastIndexOf('/') + 1);String saveFilePath = saveDir + File.separator + fileName;try (InputStream inputStream = response.getEntity().getContent();FileOutputStream outputStream = new FileOutputStream(saveFilePath)) {byte[] buffer = new byte[4096];int bytesRead;while ((bytesRead = inputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, bytesRead);}}} else {throw new IOException("No file to download. Server replied HTTP code: " + responseCode);}}}/*** 清理文件* @param dir 文件地址 示例:/tmp/ffmpeg-temp9193762578321295193* @throws IOException 异常*/private static void cleanup(Path dir) throws IOException {Files.walk(dir)// 逆序遍历,先删除子文件.sorted((a, b) -> -a.compareTo(b)).forEach(path -> {try {Files.delete(path);} catch (IOException e) {e.printStackTrace();}});}}
ffmpeg安装
可以安装宝塔的
1、安装管理器

2、安装ffmpeg的版本
3、测试
检查版本
ffmpeg -version

错误
No such filter: ‘drawtext’
[vost#0:0/libx264 @ 0x7eabd00] Error initializing a simple filtergraph
Error opening output file 01mark.mp4
转码中使用到了drawtext,但是ffmpeg并没有drawtext,所以报错了
解决方法
1、确认FFmpeg版本
确保你安装的FFmpeg版本支持drawtext滤镜。运行以下命令来查看所有可用的滤镜:
ffmpeg -filters

我之前是安装的ffmpeg-6.1 发现没有这个滤镜,之后我安装了ffmpeg-4.4.1 就有了,可以正常使用

相关文章:
ffmpeg转码与加水印
文章目录 转码 与加水印引入jar包代码ffmpeg安装错误解决方法 转码 与加水印 引入jar包 <dependency><groupId>net.bramp.ffmpeg</groupId><artifactId>ffmpeg</artifactId><version>0.6.2</version></dependency>代码 impo…...
Leetcode 104. 二叉树的最大深度(Java-深度遍历)
题目描述: 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例: 输入:root [3,9,20,null,null,15,7] 输出:3示例 2: 输入:…...
阳明心学-传习录学习总结
资料 王阳明介绍:明代杰出的思想家、军事家、教育家;自刑部主事历任贵州龙场驿丞、庐陵知县、右佥都御史、南赣巡抚、两广总督等职,接连平定南赣、两广盗乱及宸濠之乱,因功获封“新建伯”,成为明代因军功封爵的三位文…...
macOS sequoia 15.1中应用程序“程序坞”没有权限打开
在macOS sequoia 15.1版本中新安装的应用程序在访达中打开报错显示应用程序“程序坞”没有权限打开“(null)”。 解决办法 在启动台中找到终端,点击打开,切换到应用目录下,输入 cd /Applications/ 找到需要打开的应用程序目录࿰…...
使用 MinIO 和 KKFileView 实现在线文件预览功能
在项目开发中,文件的在线预览是常见的需求,尤其是对 PDF、Word、Excel 等格式的文件进行无客户端依赖的直接查看。本文将介绍如何通过 MinIO 和 KKFileView 搭建在线文件预览服务,并通过 docker-compose 一键部署。 一、环境准备 1. Docker …...
Conda-Pack打包:高效管理Python环境
在Python开发中,环境管理是一个不可忽视的重要环节。Conda是一个流行的包管理器和环境管理器,它允许用户创建隔离的环境,以避免不同项目之间的依赖冲突。Conda-pack是一个工具,可以帮助我们将一个conda环境打包成一个可移植文件&a…...
云服务器上搭建 WordPress 全流程指南
WordPress 是全球最受欢迎的开源内容管理系统(CMS),通过 WordPress,你可以轻松搭建博客、企业网站或电子商务平台。而通过云服务器搭建 WordPress,可以使网站获得更好的性能和灵活性。本文将为你提供详细的步骤&#x…...
图像超分辨率技术新进展:混合注意力聚合变换器HAAT
目录 1. 引言: 2. 混合注意力聚合变换器(HAAT): 2.1 Swin-Dense-Residual-Connected Block(SDRCB): 2.2 Hybrid Grid Attention Block(HGAB): 3. 实验结…...
文件IO——01
1. 认识文件 1)文件概念 “文件”是一个广义的概念,可以代表很多东西 操作系统里,会把很多的硬件设备和软件资源抽象成“文件”,统一管理 但是大部分情况下的文件,都是指硬盘的文件(文件相当于是对“硬…...
【opencv入门教程】5. Mat 类用法
文章选自: 一、BackGround Mat对象是一种图像数据结构,它是一个容器,存储任何通道任何数的图片数据以及对应的矩阵,使用完成后,内存自动释放。二、Code void Samples::MatFunc() {1. 图像处理// 方法1:…...
SSM虾米音乐项目2--分页查询
1.分页查询的底层逻辑 首先根据用户输入的流派,进行模糊查询根据查询的数据进行分页需要前端用户提供pageNo(当前页数)和pageSize(每页的数据量)并且要从后端计算count(总数据量)和totalPage(总页数),以及startNum(每页开始的记录)从而将对应的页面数据…...
nodejs 获取本地局域网 ip 扫描本地端口
因为傻逼老板的垃圾需求,不得不成长 示例代码: 获取本地局域网 ip 地址: 需要注意的是:如果存在虚拟机网络,则返回的是虚拟机网络的 ipv4 地址 import os from os; export const getLocalIp () > {const in…...
区块链签名种类
1. eth_sign 简介:最早实现的签名方法,用于对任意数据进行签名。签名内容:直接对原始消息的哈希值进行签名。特点: 安全性较低,因为签名的消息没有明确的上下文或结构。很容易被滥用,攻击者可以伪造签名内…...
【062B】基于51单片机无线病房呼叫系统(+时间)【Keil程序+报告+原理图】
☆、设计硬件组成:51单片机最小系统NRF24L01无线模块DS1302时钟芯片LCD1602液晶显示按键设置蜂鸣器LED灯。 1、本设计采用STC89C51/52、AT89C51/52、AT89S51/52作为主控芯片,采用LCD1602液晶显示呼叫信息,系统共有两个板子(一个接…...
突破空间限制!从2D到3D:北大等开源Lift3D,助力精准具身智能操作!
文章链接:https://arxiv.org/pdf/2411.18623 项目链接:https://lift3d-web.github.io/ 亮点直击 提出了Lift3D,通过系统地提升隐式和显式的3D机器人表示,提升2D基础模型,构建一个3D操作策略。 对于隐式3D机器人表示&a…...
【pyspark学习从入门到精通24】机器学习库_7
目录 聚类 在出生数据集中寻找簇 主题挖掘 回归 聚类 聚类是机器学习中另一个重要的部分:在现实世界中,我们并不总是有目标特征的奢侈条件,因此我们需要回归到无监督学习的范式,在那里我们尝试在数据中发现模式。 在出生数据…...
Echart折线图属性设置 vue2
Echart折线图 官方配置项手册 Documentation - Apache ECharts 下面代码包含:设置标题、线条样式、图例圆圈的样式、显示名称格式、图片保存、增加Y轴目标值 updateChart(data) {const sortedData data.slice().sort((a, b) > new Date(a.deviceTime) - ne…...
LabVIEW-简单串口助手
LabVIEW-简单串口助手 串口函数VISA配置串口VISA写入函数VISA读取函数VISA资源名称按名称解除捆绑 函数存放位置思维导图主体界面为以下 串口函数 VISA配置串口 VISA写入函数 VISA读取函数 VISA资源名称 按名称解除捆绑 函数存放位置 思维导图 主体界面为以下 从创建好的“枚举…...
Linux下,用ufw实现端口关闭、流量控制(二)
本文是 网安小白的端口关闭实践 的续篇。 海量报文,一手掌握,你值得拥有,让我们开始吧~ ufw 与 iptables的关系 理论介绍: ufw(Uncomplicated Firewall)是一个基于iptables的前端工具…...
C#开发-集合使用和技巧(九)Join的用法
在C#中,IEnumerable 的 Join 方法用于根据键将两个序列中的元素进行关联。Join 方法通常用于执行类似于 SQL 中的内连接操作。以下是 Join 方法的基本用法: 基本语法 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult…...
第08章 FastAPI 与 SSE 流式 RAG 后端
第08章 FastAPI 与 SSE 流式 RAG 后端 到目前为止,知识库、检索工具、MCP 客户端都已经就绪,但仍缺少一个面向最终用户的入口。本章用 FastAPI 把整条 RAG 链路串起来:接收前端发来的自然语言问题,调用 MCP 工具检索相关工单&…...
Codesys ST语言PID调参避坑指南:从仿真到实战,手把手教你搞定温控/电机项目
Codesys ST语言PID调参避坑指南:从仿真到实战的工程化解决方案 在工业自动化领域,PID控制算法占据着核心地位。无论是恒温控制、电机调速还是压力调节,一个精心调校的PID控制器往往能决定整个系统的性能表现。然而,许多工程师在掌…...
手把手教你用三菱FX3U PLC的RS指令和RS2指令与电脑串口调试助手‘对话’
三菱FX3U PLC串口通信实战:从零搭建RS485数据收发系统 第一次接触工业控制系统的串口通信时,我被那些密密麻麻的接线和晦涩的协议参数弄得晕头转向。直到在自动化生产线上亲眼看到PLC通过两根电线与十几台设备稳定通信,才意识到串口技术的精妙…...
AutoCut终极指南:如何用文本编辑器快速剪辑100个视频
AutoCut终极指南:如何用文本编辑器快速剪辑100个视频 【免费下载链接】autocut 用文本编辑器剪视频 项目地址: https://gitcode.com/GitHub_Trending/au/autocut 还在为手动剪辑视频而烦恼吗?AutoCut项目让你告别复杂的视频编辑软件,通…...
攻克R与Python的壁垒:Giotto空间转录组分析环境一站式搭建指南
1. 为什么你的Giotto安装总是失败? 每次看到空间转录组数据就手痒想用Giotto分析,结果安装环节就被劝退?这可能是大多数生物信息学新手都会遇到的尴尬。作为一个在生信领域摸爬滚打多年的"环境配置工程师",我太理解这种…...
Java 大厂面试 200 题完整版含答案解析
前言本文整理了近两年从阿里、腾讯、字节、美团、京东、拼多多等大厂面试中高频出现的 200 道 Java 面试题,覆盖 Java 基础、集合、并发、JVM、Spring、MySQL、Redis、消息队列、分布式、场景设计 等核心模块,每题都附有简明扼要的答案解析,助…...
g1810,g3810,ip2700,g5080,g1800,ts3380,TS8380,ts6480报错5B00,P07,E08,5b02,1704,1700,5b04,佳能v6.200,亲测有用。
下载:点这里下载 备用下载:https://pan.baidu.com/s/1WrPFvdV8sq-qI3_NgO2EvA?pwd0000 常见型号如下: G系列 G1000、G1100、G1200、G1400、G1500、G1800、G1900、G1010、G1110、G1120、G1410、G1420、G1411、G1510、G1520、G1810、G1820、…...
基于GitHub Actions的自动化代码质量守护:CodeBuddy实战指南
1. 项目概述与核心价值最近在和一些团队做代码评审和协作时,我经常遇到一个痛点:大家写的代码风格各异,注释要么缺失要么过时,一些潜在的安全漏洞和性能问题在提交前很难被系统性地发现。虽然市面上有各种静态分析工具,…...
AI智能体操作安卓设备:基于agent-droid-bridge的自动化实践
1. 项目概述:连接AI与安卓设备的桥梁 最近在折腾AI智能体(Agent)和自动化流程时,遇到了一个挺有意思的需求:如何让运行在服务器上的AI程序,直接去操作一台真实的安卓手机或模拟器,完成一些复杂的…...
面向开发者的轻量级计划管理工具:配置驱动与命令行优先
1. 项目概述:一个为开发者而生的计划管理工具在软件开发的世界里,我们每天都在与各种“计划”打交道:版本迭代计划、个人学习计划、项目里程碑、甚至是每日的待办清单。然而,一个尴尬的现实是,市面上大多数项目管理工具…...
