编辑
2025-11-22
C#
00

目录

前言
准备工作
视频变换详细示例
缩放和拉伸
视频裁剪
视频旋转
镜像翻转
注意事项
结论

前言

Xabe.FFmpeg 是一个强大的 .NET 视频处理库,提供了丰富的视频转换和处理功能。本文将详细介绍如何使用 Xabe.FFmpeg 实现视频的形状和大小变换。

准备工作

首先,安装 NuGet 包:

C#
Install-Package Xabe.FFmpeg

视频变换详细示例

缩放和拉伸

C#
using System; using System.Threading.Tasks; using Xabe.FFmpeg; using System.IO; namespace App15 { public class VideoResize { public VideoResize() { // 设置 FFmpeg 可执行文件路径 FFmpeg.SetExecutablesPath("D:\\Software\\ffmpeg-master-latest-win64-gpl-shared\\bin"); } public async Task ResizeVideo(string inputPath = "input.mp4") { try { // 1. 使用预定义尺寸缩放到720p var conversion1 = await FFmpeg.Conversions.New() .AddParameter($"-i {inputPath}") .AddParameter("-vf scale=1280:720") // 直接使用720p的分辨率 .SetOutput("d:\\output_720p.mp4") .Start(); // 2. 自定义精确尺寸缩放 var conversion2 = await FFmpeg.Conversions.New() .AddParameter($"-i {inputPath}") .AddParameter("-vf scale=1280:720") .SetOutput("d:\\output_custom.mp4") .Start(); // 3. 保持宽高比缩放 var conversion3 = await FFmpeg.Conversions.New() .AddParameter($"-i {inputPath}") .AddParameter("-vf scale=1280:-1") // 宽度固定,高度自适应 .SetOutput("d:\\output_proportional.mp4") .Start(); // 4. 更复杂的缩放,设置编码和质量 var conversion4 = await FFmpeg.Conversions.New() .AddParameter($"-i {inputPath}") .AddParameter("-vf scale=1280:720") .AddParameter("-c:v libx264") .AddParameter("-crf 23") .SetOutput("d:\\output_advanced.mp4") .Start(); // 5. 压缩同时缩放 (使用2K分辨率作为参考) var conversion5 = await FFmpeg.Conversions.New() .AddParameter($"-i {inputPath}") .AddParameter("-vf scale=2560:1440") // 2K分辨率 .AddParameter("-b:v 1000k") .SetOutput("d:\\output_compressed.mp4") .Start(); Console.WriteLine("视频缩放完成!"); } catch (Exception ex) { Console.WriteLine($"视频处理错误: {ex.Message}"); } } // 获取视频信息的方法 public async Task GetVideoInfo(string inputFile) { try { var mediaInfo = await FFmpeg.GetMediaInfo(inputFile); var videoStream = mediaInfo.VideoStreams.First(); Console.WriteLine($"视频时长: {mediaInfo.Duration}"); Console.WriteLine($"视频分辨率: {videoStream.Width}x{videoStream.Height}"); } catch (Exception ex) { Console.WriteLine($"获取视频信息错误: {ex.Message}"); } } // 额外的实用方法:检查文件是否存在 private void ValidateInputFile(string inputPath) { if (!File.Exists(inputPath)) { throw new FileNotFoundException($"输入文件不存在: {inputPath}"); } } } }

image.png

视频裁剪

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Xabe.FFmpeg; namespace App15 { public class VideoProcessor { /// <summary> /// 裁剪视频的方法 /// </summary> /// <param name="inputPath">输入视频文件路径</param> /// <param name="outputPath">输出视频文件路径</param> /// <param name="x">裁剪区域的X坐标</param> /// <param name="y">裁剪区域的Y坐标</param> /// <param name="width">裁剪区域的宽度</param> /// <param name="height">裁剪区域的高度</param> /// <returns>Task representing the asynchronous operation</returns> public async Task CropVideoAsync( string inputPath, string outputPath, int x, int y, int width, int height) { try { // 获取媒体信息 IMediaInfo mediaInfo = await FFmpeg.GetMediaInfo(inputPath); // 创建转换 IConversion conversion = FFmpeg.Conversions.New() .AddStream(mediaInfo.VideoStreams.First()) .AddParameter($"-filter:v crop={width}:{height}:{x}:{y}",ParameterPosition.PostInput) // 添加音频流 .AddStream(mediaInfo.AudioStreams) .SetOutput(outputPath); // 执行转换 IConversionResult result = await conversion.Start(); Console.WriteLine($"视频裁剪完成。耗时:{result.Duration}"); } catch (Exception ex) { Console.WriteLine($"转换错误: {ex.Message}"); throw; } } } }

视频旋转

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Xabe.FFmpeg; namespace App15 { public class VideoRotate { /// <summary> /// 视频旋转方法(90度旋转) /// </summary> /// <param name="inputPath">输入视频路径</param> /// <param name="outputPath">输出视频路径</param> /// <param name="rotationDegree">旋转角度(90, 180, 270)</param> /// <returns></returns> public async Task RotateVideoAsync( string inputPath, string outputPath, int rotationDegree = 90) { try { // 获取媒体信息 IMediaInfo mediaInfo = await FFmpeg.GetMediaInfo(inputPath); // 创建转换 IConversion conversion = FFmpeg.Conversions.New() .AddStream(mediaInfo.VideoStreams.First()) .AddParameter($"-vf {GetRotationFilter(rotationDegree)}", ParameterPosition.PostInput) .AddStream(mediaInfo.AudioStreams) // 保留音频 .SetOutput(outputPath); // 执行转换 IConversionResult result = await conversion.Start(); Console.WriteLine($"视频旋转完成。耗时:{result.Duration}"); } catch (Exception ex) { Console.WriteLine($"视频旋转错误: {ex.Message}"); throw; } } /// <summary> /// 获取旋转滤镜 /// </summary> /// <param name="degrees">旋转角度</param> /// <returns>FFmpeg旋转滤镜字符串</returns> private string GetRotationFilter(int degrees) { return degrees switch { 90 => "transpose=1", // 顺时针旋转90度 180 => "hflip,vflip", // 水平和垂直翻转 270 => "transpose=2", // 逆时针旋转90度 _ => throw new ArgumentException("仅支持 90, 180, 270 度旋转") }; } } }

镜像翻转

C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Xabe.FFmpeg; namespace App15 { public class VideoFlip { /// <summary> /// 水平翻转视频 /// </summary> /// <param name="inputPath">输入视频路径</param> /// <param name="outputPath">输出视频路径</param> /// <returns></returns> public async Task HorizontalFlipAsync( string inputPath, string outputPath) { try { // 获取媒体信息 IMediaInfo mediaInfo = await FFmpeg.GetMediaInfo(inputPath); // 创建转换 IConversion conversion = FFmpeg.Conversions.New() .AddStream(mediaInfo.VideoStreams.First()) .AddParameter("-vf hflip", ParameterPosition.PostInput) // 水平翻转 .AddStream(mediaInfo.AudioStreams) // 保留音频 .SetOutput(outputPath); // 执行转换 IConversionResult result = await conversion.Start(); Console.WriteLine($"水平翻转完成。耗时:{result.Duration}"); } catch (Exception ex) { Console.WriteLine($"水平翻转错误: {ex.Message}"); throw; } } /// <summary> /// 垂直翻转视频 /// </summary> /// <param name="inputPath">输入视频路径</param> /// <param name="outputPath">输出视频路径</param> /// <returns></returns> public async Task VerticalFlipAsync( string inputPath, string outputPath) { try { // 获取媒体信息 IMediaInfo mediaInfo = await FFmpeg.GetMediaInfo(inputPath); // 创建转换 IConversion conversion = FFmpeg.Conversions.New() .AddStream(mediaInfo.VideoStreams.First()) .AddParameter("-vf vflip", ParameterPosition.PostInput) // 垂直翻转 .AddStream(mediaInfo.AudioStreams) // 保留音频 .SetOutput(outputPath); // 执行转换 IConversionResult result = await conversion.Start(); Console.WriteLine($"垂直翻转完成。耗时:{result.Duration}"); } catch (Exception ex) { Console.WriteLine($"垂直翻转错误: {ex.Message}"); throw; } } /// <summary> /// 同时进行水平和垂直翻转 /// </summary> /// <param name="inputPath">输入视频路径</param> /// <param name="outputPath">输出视频路径</param> /// <returns></returns> public async Task BothFlipAsync( string inputPath, string outputPath) { try { // 获取媒体信息 IMediaInfo mediaInfo = await FFmpeg.GetMediaInfo(inputPath); // 创建转换 IConversion conversion = FFmpeg.Conversions.New() .AddStream(mediaInfo.VideoStreams.First()) .AddParameter("-vf hflip,vflip", ParameterPosition.PostInput) // 水平和垂直翻转 .AddStream(mediaInfo.AudioStreams) // 保留音频 .SetOutput(outputPath); // 执行转换 IConversionResult result = await conversion.Start(); Console.WriteLine($"水平垂直翻转完成。耗时:{result.Duration}"); } catch (Exception ex) { Console.WriteLine($"翻转错误: {ex.Message}"); throw; } } } }

image.png

注意事项

  • 确保输入视频存在
  • 处理大文件时注意内存占用
  • 转换过程可能耗时,建议异步处理
  • 部分复杂变换可能影响视频质量

结论

Xabe.FFmpeg 是一个功能强大且灵活的视频处理库,它通过提供简洁易用的 API 接口,使开发者能够轻松实现复杂的视频变换和处理需求。无论是视频剪辑、格式转换、添加水印、调整分辨率还是音频提取等任务,Xabe.FFmpeg 都能高效地完成。该库基于著名的 FFmpeg 项目构建,继承了其丰富的多媒体处理能力,并在此基础上进行了封装,简化了使用难度。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!