java ffmpeg 视频水印_java 实现视频转换通用工具类:视频加水印-Ffmpeg(五-1)

java 实现视频转换通用工具类:视频相互转换-Ffmpeg(三)

说明:

视频加水印支持右上角、左上角、左下角、右下角、底部居中几个方位

1.根据水印文字---添加视频水印

/**

* 根据水印文字---添加视频水印

* @param srcPath 原视频路径

* @param tarVideoPath 生成后的视频路径

* @param wmPosition 水印位子

* @param alpha 透明度

* @param txt String 文字

* @param fontSize 每个字的宽度和高度是一样的

* @param fontColor Color 字体颜色

* @param isBold 字体是否加粗

* @param fontType 字体样式

* @param fontPath 字体文件

* @return

*/

public static boolean processFfmpegWatermkByFont(String srcPath,String tarVideoPath,int wmPosition, float alpha,String txt, int fontSize,Color fontColor,boolean isBold,String fontType,String fontPath) {

//通过文字生成的图片临时路径

String waterMarkPath = WebAppUtils.getWebAppRoot() +BaseCommonUtil.TXTIMGPATH + BaseCommonUtil.getDateNum() + ".png";

//waterMarkPath = "D:/project/BSRCM_TRUNK/WebRoot/swf/txtImg/1.png";

//通过文字生成透明图片

ImageHelps.createJpgByFont(txt,fontSize,fontColor,isBold,fontType,fontPath,waterMarkPath);

//avs ---通过水印图片添加水印视频

//return processFfmpegWatermarkByImage(srcPath,tarVideoPath,waterMarkPath,wmPosition,alpha);

//vfilters ---通过水印图片添加水印视频

boolean boo = processFfmpegWatermarkByImg(srcPath,tarVideoPath,waterMarkPath,wmPosition,alpha);

if(boo){

logger.info("【" + srcPath +"】 视频添加文字水印图片成功! ");

return true;

}else{

logger.error("【" + srcPath +"】 processFfmpegWatermkByFont 视频添加文字水印图片失败! ");

return false;

}

}

2.根据水印图片---添加视频水印

/**

*根据水印图片---添加视频水印

* @param srcPath 原视频路径

* @param tarVideoPath 生成后的视频路径

* @param waterMarkPath 水印图片路径

* @param wmPosition 水印位子

* @param alpha 透明度

* @return

*/

public static boolean processFfmpegWatermarkByImg(String srcPath,String tarVideoPath,String waterMarkPath,int wmPosition, float alpha) {

if (!checkfile(srcPath)) {

logger.error("【" + srcPath + "】 不存在 !");

return false;

}

if (!checkfile(waterMarkPath)) {

logger.error("【" + waterMarkPath + "】 不存在 !");

return false;

}

//如果父目录不存在就创建一个

tarVideoPath = BaseCommonUtil.replaceFliePathStr(tarVideoPath);

BaseCommonUtil.mkdir(tarVideoPath);

//缩放图片

zooImage(srcPath, waterMarkPath);

//要执行的shell脚本路径

String shellPath = WebappConfigUtil.getParameter("shellPath");

if (!checkfile(shellPath)) {

logger.error("【" + shellPath + "】shell脚本路径 不存在 !");

}

String extendTarName = tarVideoPath.substring(tarVideoPath.lastIndexOf(".")+1,tarVideoPath.length());

Process process = null;

try {

String os = System.getProperty("os.name");

if (os != null && os.toLowerCase().startsWith("windows")) {

String picPath = waterMarkPath.substring(waterMarkPath.indexOf("WebRoot"),waterMarkPath.lastIndexOf("/"));

waterMarkPath = waterMarkPath.substring(waterMarkPath.lastIndexOf("/")+1,waterMarkPath.length());

process = Runtime.getRuntime().exec(shellPath +" "+picPath+" " + ffmpegPath + " " + srcPath + " " + waterMarkPath + " " + getVideoPosition(wmPosition) + " " + tarVideoPath);

} else{

process = Runtime.getRuntime().exec(shellPath + " " + ffmpegPath + " " + srcPath + " " + waterMarkPath + " " + getVideoPosition(wmPosition) + " " + tarVideoPath);

}

doWaitFor(process);

//转换mate信息

if("MP4".equals(extendTarName.toUpperCase())){

return execMp4Box(tarVideoPath);

}

if (!checkfile(tarVideoPath)) {

logger.error("【" + srcPath + "】processFfmpegWatermarkByImage 视频添加水印不成功 !");

return false;

}

return true;

} catch (Exception e) {

logger.error("【" + srcPath + "】processFfmpegWatermarkByImage 视频添加水印不成功 !");

return false;

}finally{

if(process != null){

process.destroy();

}

}

}

3.根据方位数字获取值

/**

* 根据方位数字获取值

* @param wmPosition

* Top left corner

* ffmpeg –i inputvideo.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=10:10 [out]" outputvideo.flv

* Top right corner

* ffmpeg –i inputvideo.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=main_w-overlay_w-10:10 [out]" outputvideo.flv

* Bottom left corner

* ffmpeg –i inputvideo.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=10:main_h-overlay_h-10 [out]" outputvideo.flv

* Bottom right corner

* ffmpeg –i inputvideo.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=main_w-overlay_w-10:main_h-overlay_h-10 [out]" outputvideo.flv

* @return

*/

public static String getVideoPosition(int wmPosition){

String positionStr = "main_w-overlay_w-10:main_h-overlay_h-10"; //默认右上角

switch (wmPosition) {

case 0:

positionStr ="10:10"; //左上角

break;

case 1:

positionStr ="main_w-overlay_w-10:10"; //右上角

break;

case 2:

positionStr ="10:main_h-overlay_h-10"; //左下角

break;

case 3:

positionStr ="main_w-overlay_w-10:main_h-overlay_h-10"; //右下角

break;

case 4:

positionStr ="(main_w-overlay_w)/2:main_h-overlay_h:1"; //底部居中

break;

default:

break;

}

return positionStr;

}

4.缩放图片

/**

* 缩放图片

* @param srcPath 视频路径

* @param wmImgPath 水印图片路径

* @return

*/

public static void zooImage(String srcPath,String wmImgPath){

//获取视频信息

VideoInfo videoInfo = VideoInfoHelps.getVideoInfo(srcPath);

int width = 0; //视频宽

int height = 0; //视频高

if(videoInfo != null){

String widthStr = videoInfo.getWidth(); //宽

if(StringUtils.isNotEmpty(widthStr)) width = Integer.parseInt(widthStr);

String heightStr = videoInfo.getHeight(); //高

if(StringUtils.isNotEmpty(heightStr)) height = Integer.parseInt(heightStr);

}

if(width !=0 || height !=0){ //如果获取到视频宽高

//进行图片缩放

ImageHelps.zoomPerImg(wmImgPath, wmImgPath,width,height);

}

}

5.获取x,y坐标值,返回String数组

/**

* 获取x,y坐标值,返回String数组

* @param wmPosition

* 0:左上角

* 1:右上角

* 2:左下角

* 3:右下角

* 4:居中

* @param srcPath 视频路径

* @param wmImgPath 水印图片路径

* @return

*/

public static int[] getXy(int wmPosition,String srcPath,String wmImgPath){

int x=10,y=10; //定义默认为左上角

int[] xy = new int[2];

//获取视频信息

VideoInfo videoInfo = VideoInfoHelps.getVideoInfo(srcPath);

int width = 0; //视频宽

int height = 0; //视频高

if(videoInfo != null){

String widthStr = videoInfo.getWidth(); //宽

if(StringUtils.isNotEmpty(widthStr)) width = Integer.parseInt(widthStr);

String heightStr = videoInfo.getHeight(); //高

if(StringUtils.isNotEmpty(heightStr)) height = Integer.parseInt(heightStr);

}

if(width !=0 || height !=0){ //如果获取到视频宽高

//取得坐标方位编码

int position =BaseCommonUtil.getWmDegree(wmPosition);

int wideth_biao =0; //水印图片的宽

int height_biao = 0; //水印图片的高

try {

//首先进行图片缩放

ImageHelps.zoomPerImg(wmImgPath, wmImgPath,width,height);

//水印文件

Image src_biao = ImageIO.read(new File(wmImgPath));

wideth_biao = src_biao.getWidth(null);

height_biao = src_biao.getHeight(null);

} catch (IOException e) {

logger.error("【" + wmImgPath + "】getXy 读取水印图片失败 !");

}

//左上角距离边距10像素

int leftUpWideth = 10;

int leftUpHeight = 10;

//右上角距离边距10像素

int rightUpWideth = (width - wideth_biao) - 10;

int rightUpHeight = 10;

//左下角距离边距10像素

int leftDownWideth = 10;

int leftDownHeight = (height - height_biao) - 10;

//右下角距离边距10像素

int rightDownWideth = (width - wideth_biao) - 10;

int rightDownHeight = (height - height_biao) - 10;

//居中

int centerWideth = (width - wideth_biao) / 2;

int centerHeight = (height - height_biao) / 2;

switch (position) {

case 0:

x = leftUpWideth;

y = leftUpHeight;

break;

case 1:

x = rightUpWideth;

y = rightUpHeight;

break;

case 2:

x = leftDownWideth;

y = leftDownHeight;

break;

case 3:

x = rightDownWideth;

y = rightDownHeight;

break;

case 4:

x = centerWideth;

y = centerHeight;

break;

default:

break;

}

}

//设值

xy[0] =x;

xy[1] =y;

return xy;

}

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

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

相关文章

手动 clone 安装 Homebrew

文章目录 手动 clone 安装 HomebrewHomebrew 换源替换 homebrew 源替换 homebrew-core 源替换 homebrew-bottles 源bash用户zsh 用户更新 Homebrew手动 clone 安装 Homebrew 首先进入 homebrew 目录:cd "$(brew --repo)/Library/Taps/homebrew/"创建目录 homebrew-c…

lambda 匿名内部类_Lambda运行时内部:窥视无服务器巢穴

lambda 匿名内部类有没有想过lambda里面是什么样的? 不要怀疑了 让我们找出答案。 自从2014年问世以来,AWS的lambda函数就成为一个热门话题,在无服务器计算领域开辟了全新的历史。 无状态,零维护,按次执行的好东西实际…

java VM argument_java之program arguments与VM arguments

program arguments 中的值作为 args[] 的参数传入的,而 VM Arguments 是设置的虚拟机的属性。program arguments 是要传给你的应用程序的,它通过主函数中的 args 来传值。 VM arguments是系统的属性,要传给 java 虚拟机的。如图:是…

java iterator 嵌套_Java中的集合嵌套

import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;public classDemo06 {public static voidmain(String[] args) {//大 MapHashMap> oraclenew HashMap>();//小MapHashMap java1018 new HashMap();HashMap java1227 new H…

Linux/Unix 如何查看 man 搜索到的手册页(manual page)的位置及复制手册页的内容

文章目录命令 man 是如何搜索手册页的?如何查看手册页所在的路径通过管道输出给 vim命令 man 是如何搜索手册页的? man uses a sophisticated method of finding manual page files, based on the invocation options and environment variables, the …

xml不利于调试_流利的接口不利于维护

xml不利于调试流畅的界面 (最初由Martin Fowler 创造)是一种与OOP中的对象进行通信的非常便捷的方式。 它使他们的外墙更易于使用和理解。 但是,它破坏了它们的内部设计,使它们更难以维护。 Marco Pivetta在他的博客文章Fluent In…

java输入月份求天数_java输入年份,月份,输出当月天数

package 第二次作业; public class 第二题 { //java文件名 public static void main(String[] args) { //相当于创建主函数 String 年份 = javax.swing.JOptionPane.showInputDialog("输入一个年份:"); //求出输…

java 换行 运算符格式_Java代码样式运算符换行格式

java 换行 运算符格式上周,我发现了什么决定了我在较长时间里一直在努力解决的问题的决定:是否放置&& , ||之类的运算符 或在同一行或下一行。 在构造布尔表达式或隐含字符串时,我们可能需要中断长行。 根据《 Google Ja…

pipeline java_架构模式:pipeline

知名的 Pipeline 模式unix 的 pipelinecat helloworld.txt | grep "hello world" | rev | > output.txt读取文本内容,并过滤 “hello world”,然后反转字符,将最终结果输出到 output.txtWeb 框架中间件Laravel 中的管道Laravel …

MacOS 系统使用命令安装软件包

文章目录 使用 Homebrew 安装软件包先安装 Homebrew使用命令 brew 安装软件包使用命令 installer 安装 pkg 软件包使用命令安装 dmg 格式的软件包包含普通的应用程序文件的 dmg 文件如何使用命令完成安装呢?包含 pkg 安装程序的 dmg 文件又该如何通过命令完成安装呢?Linux 操…

身份证验证 校验码_用户身份验证最佳做法清单

身份证验证 校验码用户身份验证是每个Web应用程序共享的功能。 我们已经实施了很多次了,所以早就应该完善它了。 然而,错误无时无刻不在。 造成这种情况的部分原因是,可能出错的事情列表很长。 您可能会错误地存储密码,可能会具有…

mysql查询不确定的信息_mysql 07.18

1.索引搜索引导,索引是一个特殊的数据结构,期存储的是数据的关键信息与详细详细的位置对应关系。目的:加速查询。索引的影响:不是说拥有索引就能加速,得看你的查询语句有没有正确使用索引,索引也需要占用额…

MacOS 常用命令汇总

文章目录设置环境变量列出所有可以更新的软件包直接更新所有可以更新的软件包打包压缩文件忽略 Mac OS 文件系统中的扩展属性忽略 Mac OS 专有的隐藏文件创建 DMG 格式的文件修改 DMG 文件的大小修改 DMG 格式中的加密口令挂载 DMG 格式的文件推出 DMG 文件将 ISO 格式的文件转…

java多功能钟_Java 11将包含更多功能

java多功能钟Java 11即将发布的功能是什么?它与Java 9和10有何不同? Java 10可能是新手,但现在该谈论Java 11了。Oracle迈向更快的发布周期意味着更多的特性和功能以比以往更快的速度出现。 尽管距离Java 11发行还有六个月的时间&#xff0…

MacOS 好用的插件和图形界面程序

文章目录文件预览插件OS X 图形界面程序文件预览插件 有些插件可以让 Mac 上的文件预览更有效,比如语法高亮、markdown 渲染、json 预览等。 $ brew cask install qlcolorcode $ brew cask install qlstephen $ brew cask install qlmarkdown $ brew cask install…

java 线程安全性_我如何测试Java类的线程安全性

java 线程安全性我在最近的一次网络研讨会中谈到了这个问题,现在是时候以书面形式进行解释了。 线程安全是Java等语言/平台中类的重要品质,在Java中我们经常在线程之间共享对象。 缺乏线程安全性导致的问题很难调试,因为它们是零星的&#xf…

java asin_Java asin()方法

Java asin()方法asin() 方法用于返回指定double类型参数的反正弦值。语法doubleasin(doubled)参数 d -- 任何原生数据类型。返回值返回指定double类型参数的反正弦值。实例public class Test{public static void main(String args[]){double degrees 45.0;double radians Mat…

MacOS 的软件包管理工具 HomeBrew 详解

文章目录一、软件介绍二、安装 Homebrew使用 Ruby 或者 Shell 脚本安装手动 clone 安装三、卸载 Homebrew四、Homebrew 安装目录五、安装包所在位置六、程序安装目录七、软件版本切换八、清除旧版本文件九、brew 命令汇总安装、升级和删除软件包查看和检验软件包参考示例服务相…

java中的深度克隆浅克隆_了解Java中的可克隆接口

java中的深度克隆浅克隆什么是对象克隆? 对象克隆是生成具有不同名称的对象的精确字段到字段副本的过程。 克隆的对象在内存中有自己的空间,可在其中复制原始对象的内容。 这就是为什么在克隆后更改原始对象的内容时,所做的更改不会反映在克隆…

python env_#!/usr/bin/env python 有什么用?

我们经常会在别人的脚本或者项目的入口文件里看到第一行是下面这样#!/usr/bin/python或者这样#!/usr/bin/env python那么他们有什么用呢?要理解它,得把这一行语句拆成两部分。第一部分是 #!第二部分是 /usr/bin/python 或者 /usr/bin/env python关于 #! …