视频水印是保护版权、标识视频来源的重要技术。本文将详细介绍如何使用C#和FFmpeg为视频添加水印,并提供多种实现方式。
使用Package Manager Console安装:
PowerShellInstall-Package Xabe.FFmpeg
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xabe.FFmpeg;
namespace App08
{
public class VideoWatermarker
{
/// <summary>
/// 为视频添加文字水印
/// </summary>
/// <param name="inputVideo">输入视频路径</param>
/// <param name="outputVideo">输出视频路径</param>
/// <param name="watermarkText">水印文字内容</param>
public async Task AddTextWatermarkAsync(
string inputVideo,
string outputVideo,
string watermarkText)
{
try
{
// 确保已设置 FFmpeg 执行文件路径
FFmpeg.SetExecutablesPath("D:\\Software\\ffmpeg-master-latest-win64-gpl-shared\\bin");
// 创建转换
IMediaInfo mediaInfo = await FFmpeg.GetMediaInfo(inputVideo);
// 配置转换参数
var conversion = FFmpeg.Conversions.New()
.AddStream(mediaInfo.VideoStreams)
.AddStream(mediaInfo.AudioStreams)
.AddParameter($"-vf \"drawtext=fontfile=msyh.ttc:" +
$"text='{watermarkText}':" +
"fontcolor=white:" +
"fontsize=24:" +
"box=1:" +
"boxcolor=black@0.5:" +
"boxborderw=5:" +
"x=(w-text_w)/2:" +
"y=(h-text_h)/2\"")
.SetOutput(outputVideo);
// 执行转换
await conversion.Start();
}
catch (Exception ex)
{
Console.WriteLine($"水印添加失败:{ex.Message}");
throw;
}
}
}
}
C#static async Task Main(string[] args)
{
VideoWatermarker watermarker = new VideoWatermarker();
await watermarker.AddTextWatermarkAsync("D:\\Video\\1.mp4", "d:\\output.mp4", "IDIOSOFT");
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xabe.FFmpeg;
namespace App08
{
public class ImageWatermarker
{
public async Task AddImageWatermarkAsync(
string inputVideo,
string outputVideo,
string watermarkImage)
{
try
{
// 设置 FFmpeg 路径
FFmpeg.SetExecutablesPath("D:\\Software\\ffmpeg-master-latest-win64-gpl-shared\\bin");
// 创建转换配置
IConversion conversion = FFmpeg.Conversions.New()
.AddParameter($"-i \"{inputVideo}\" -i \"{watermarkImage}\" " +
$"-filter_complex \"[0:v][1:v] overlay=W-w-10:10\" " +
$"-c:a copy")
.SetOutput(outputVideo);
// 添加进度报告
conversion.OnProgress += (sender, args) =>
{
var percent = args.Percent;
Console.WriteLine($"处理进度: {percent:F1}%");
};
// 添加完成处理程序
conversion.OnDataReceived += (sender, args) =>
{
if (!string.IsNullOrEmpty(args.Data))
{
Console.WriteLine($"FFmpeg输出: {args.Data}");
}
};
// 执行转换
await conversion.Start();
Console.WriteLine("水印添加成功!");
}
catch (Exception ex)
{
Console.WriteLine($"图片水印添加失败:{ex.Message}");
if (ex.InnerException != null)
{
Console.WriteLine($"内部错误:{ex.InnerException.Message}");
}
throw;
}
}
}
}
如果需要调整水印位置,可以修改overlay参数:
overlay=W-w-10:10overlay=10:H-h-10overlay=W-w-10:H-h-10overlay=(W-w)/2:(H-h)/2其中:
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xabe.FFmpeg;
namespace App08
{
public class ImageWatermarker
{
public async Task AddImageWatermarkAsync(
string inputVideo,
string outputVideo,
string watermarkImage)
{
try
{
// 设置 FFmpeg 路径
FFmpeg.SetExecutablesPath("D:\\Software\\ffmpeg-master-latest-win64-gpl-shared\\bin");
// 创建转换配置
IConversion conversion = FFmpeg.Conversions.New()
.AddParameter($"-i \"{inputVideo}\" -i \"{watermarkImage}\" " + // Added input video parameter
"-filter_complex \"" +
"[0:v][1:v]overlay='if(gte(t,2),main_w-overlay_w-10,10):" +
"if(gte(t,2),main_h-overlay_h-10,10)'" +
"\" -codec:a copy")
.SetOutput(outputVideo);
// 添加进度报告
conversion.OnProgress += (sender, args) =>
{
var percent = args.Percent;
Console.WriteLine($"处理进度: {percent:F1}%");
};
// 添加完成处理程序
conversion.OnDataReceived += (sender, args) =>
{
if (!string.IsNullOrEmpty(args.Data))
{
Console.WriteLine($"FFmpeg输出: {args.Data}");
}
};
// 执行转换
await conversion.Start();
Console.WriteLine("水印添加成功!");
}
catch (Exception ex)
{
Console.WriteLine($"图片水印添加失败:{ex.Message}");
if (ex.InnerException != null)
{
Console.WriteLine($"内部错误:{ex.InnerException.Message}");
}
throw;
}
}
}
}

C#// 创建转换配置
IConversion conversion = FFmpeg.Conversions.New()
.AddParameter($"-i \"{inputVideo}\" -i \"{watermarkImage}\" " +
"-filter_complex \"" +
"[0:v][1:v]overlay=" +
"'if(lt(mod(t,8),2),10," + // 0-2秒:左上角
"if(lt(mod(t,8),4),main_w-overlay_w-10," + // 2-4秒:右上角
"if(lt(mod(t,8),6),10," + // 4-6秒:左下角
"main_w-overlay_w-10))):" + // 6-8秒:右下角
"if(lt(mod(t,8),2),10," + // 0-2秒:左上角
"if(lt(mod(t,8),4),10," + // 2-4秒:右上角
"if(lt(mod(t,8),6),main_h-overlay_h-10," + // 4-6秒:左下角
"main_h-overlay_h-10)))'" + // 6-8秒:右下角
"\" -codec:a copy")
.SetOutput(outputVideo);
参数说明:
水印位置循环逻辑:
使用mod(t,8)将时间分成8秒一个循环,然后在这8秒内分配四个不同的位置
C#// 创建转换配置
IConversion conversion = FFmpeg.Conversions.New()
.AddParameter($"-i \"{inputVideo}\" -i {watermarkImage} " +
"-filter_complex \"" +
"[1:v]format=rgba,colorchannelmixer=aa=0.5[watermark];" +
"[0:v][watermark]overlay=10:10" +
"\" -codec:a copy")
.SetOutput(outputVideo);
通过C#和FFmpeg,我们可以灵活地为视频添加各种类型的水印,保护内容并增加版权标识。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!