C#实现为视频添加水印
作者:Csharp小记 时间:2022-02-16 05:30:07
文章描述
以下主要还是使用到了ffmpeg命令,分别实现了给视频添加图片水印以及文字水印。
开发环境
.NET Framework版本:4.5
开发工具
Visual Studio 2013
实现代码
public static void Run(string cmd)
{
try
{
string ffmpeg = AppDomain.CurrentDomain.BaseDirectory + "ffmpeg.exe";
ProcessStartInfo startInfo = new ProcessStartInfo(ffmpeg);
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = cmd;
Process process = Process.Start(startInfo);
process.WaitForExit(3000);
process.Kill();
}
catch { }
}
/// <summary>
/// 按时间获取某帧图片
/// </summary>
/// <param name="videoPath">视频路径</param>
/// <param name="outPath">输出路径</param>
/// <param name="frameTime">时间(格式:00:00:01)</param>
public static void GetFrame(string videoPath, string outPath, string frameTime)
{
Run(string.Format("-ss 00:00:01 -i {1} {2}", frameTime, videoPath, outPath));
}
/// <summary>
/// 批量添加图片水印
/// </summary>
/// <param name="videoPath"></param>
/// <param name="outPath"></param>
/// <param name="listImg"></param>
public static void AddImageMark(string videoPath, string outPath, List<ImgMark> listImg)
{
string imgs = "", postions = "";
foreach (ImgMark mark in listImg)
{
imgs += " -i " + mark.ImgPath;
postions += "overlay=" + mark.Postion.X + ":" + mark.Postion.Y+",";
}
postions = postions.Remove(postions.Length - 1);
Run(string.Format("-i {0}{1} -filter_complex \"{2}\" {3}", videoPath, imgs, postions, outPath));
}
/// <summary>
/// 添加文字水印
/// </summary>
/// <param name="videoPath">视频路径</param>
/// <param name="outPath">输出路径</param>
/// <param name="textMark">水印属性</param>
public static void AddTextMark(string videoPath, string outPath, TextMark textMark)
{
Run(string.Format(" -i {0} -vf \"drawtext=fontfile={1}: text='{2}':x={3}:y={4}:fontsize={5}:fontcolor={6}\" {7}", videoPath, textMark.FontFile, textMark.Text, textMark.X, textMark.Y, textMark.FontSize, textMark.FontColor.Name.ToLower(), outPath));
//@"%{localtime\:%Y\-%m\-%d %H-%M-%S}"
}
private void btn_select_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "视频|*.mp4;*.avi";
ofd.Title = "请选择视频文件";
ofd.InitialDirectory = Application.StartupPath;
if (ofd.ShowDialog() == DialogResult.OK)
{
axWindowsMediaPlayer1.URL = ofd.FileName;
}
}
private void btn_text_Click(object sender, EventArgs e)
{
if (!File.Exists(axWindowsMediaPlayer1.URL))
{
MessageBox.Show("未选择视频");
return;
}
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "视频|*.mp4";
sfd.AddExtension = true;
if (sfd.ShowDialog() == DialogResult.OK)
{
TextMark mark = new TextMark
{
Text = "这里是水印",
FontColor = Color.Red,
FontFile = "simsun.ttc",
FontSize = 100,
X = 80,
Y = 60
};
FFmpegUtil.AddTextMark(axWindowsMediaPlayer1.URL, sfd.FileName, mark);
axWindowsMediaPlayer2.URL = sfd.FileName;
}
}
private void btn_img_Click(object sender, EventArgs e)
{
if (!File.Exists(axWindowsMediaPlayer1.URL))
{
MessageBox.Show("未选择视频");
return;
}
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "视频|*.mp4";
sfd.AddExtension = true;
if (sfd.ShowDialog() == DialogResult.OK)
{
FFmpegUtil.AddImageMark(axWindowsMediaPlayer1.URL, sfd.FileName, new List<ImgMark>{
new ImgMark {
ImgPath=@"C:\Users\Zero\Desktop\a\\1.png", Postion=new Point(60,60)},
new ImgMark {ImgPath=@"C:\Users\Zero\Desktop\a\\1.png", Postion=new Point(60,200)}});
axWindowsMediaPlayer2.URL = sfd.FileName;
}
}
实现效果
代码解析:着重介绍下添加文字水印的,由于很多时候我们需要添加的是中文,所以需要将字体包先放入到ffmepg的同级目录,然后指定该字体。
来源:https://mp.weixin.qq.com/s/g6Rx7mnIK4rhJxmZS3gX5A
标签:C#,视频,水印
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java实现小型图书馆管理系统
2021-06-14 04:27:35
![](https://img.aspxhome.com/file/2023/8/64878_0s.jpg)
Java 异步线程监听与结果回调及异常捕获总结分析
2021-10-14 01:23:40
![](https://img.aspxhome.com/file/2023/3/86773_0s.png)
C#集合之位数组的用法
2021-07-25 18:31:08
![](https://img.aspxhome.com/file/2023/6/108786_0s.jpg)
SpringCloud灾难性雪崩效应处理方法之降级实现流程详解
2022-03-24 15:31:36
微信小程序微信登录的实现方法详解(JAVA后台)
2023-08-29 12:37:25
![](https://img.aspxhome.com/file/2023/0/58370_0s.jpg)
C#实现rar压缩与解压缩文件的方法
2021-11-04 20:33:28
Android compose气泡升起和水滴下坠动画实现示例
2023-04-09 01:52:22
![](https://img.aspxhome.com/file/2023/4/96764_0s.gif)
Shiro 控制并发登录人数限制及登录踢出的实现代码
2023-09-18 02:03:56
![](https://img.aspxhome.com/file/2023/5/68515_0s.jpg)
Spring mvc如何实现数据处理
2023-06-20 09:36:35
Java 反射机制知识详细介绍及总结
2023-12-15 01:08:15
MyBatis实现多表联合查询resultType的返回值
2023-03-11 22:25:37
Java Excel透视表相关操作实现代码
2022-02-27 00:11:01
![](https://img.aspxhome.com/file/2023/8/65218_0s.png)
详解安装Eclipse Maven插件的几种方法
2022-06-01 06:15:20
![](https://img.aspxhome.com/file/2023/1/69941_0s.png)
详解Java递归实现树形结构的两种方式
2023-02-18 07:24:47
![](https://img.aspxhome.com/file/2023/7/84267_0s.png)
Unity3D实现分页系统
2022-06-28 22:53:37
![](https://img.aspxhome.com/file/2023/5/116555_0s.gif)
java实现双色球抽奖算法
2023-11-28 23:51:51
![](https://img.aspxhome.com/file/2023/3/60543_0s.jpg)
C#将布尔类型转换成字节数组的方法
2023-06-21 15:30:16
Android入门之画图详解
2023-11-09 11:47:47
![](https://img.aspxhome.com/file/2023/4/93264_0s.jpg)
Java守护线程实例详解_动力节点Java学院整理
2023-03-29 08:14:30
![](https://img.aspxhome.com/file/2023/5/60175_0s.png)
Java 如何调用long的最大值和最小值
2021-07-24 02:27:18
![](https://img.aspxhome.com/file/2023/0/60590_0s.jpg)