成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用C#封裝FFmpeg實現視頻格式轉換,你學會了嗎?

開發 架構
FFmpeg是一個功能強大的開源多媒體框架,可以用于視頻和音頻的編碼、解碼、轉碼等操作。本文將介紹如何使用C#封裝FFmpeg,實現一個簡單但功能完整的視頻格式轉換工具。

1. 簡介

FFmpeg是一個功能強大的開源多媒體框架,可以用于視頻和音頻的編碼、解碼、轉碼等操作。本文將介紹如何使用C#封裝FFmpeg,實現一個簡單但功能完整的視頻格式轉換工具。

2. 環境準備

  • Visual Studio 2022
  • .NET 6.0或更高版本
  • FFmpeg可執行文件 (ffmpeg.exe) 可以從官網下載:https://ffmpeg.org/download.html

3. 項目實現

3.1 創建FFmpeg包裝類

首先,我們創建一個FFmpegWrapper類來封裝FFmpeg的核心功能:

using System.Diagnostics;

public class FFmpegWrapper
{
    private readonly string _ffmpegPath;

    // FFmpeg進程執行的事件委托
    public delegate void OnProgressHandler(double percentage);
    public event OnProgressHandler OnProgress;

    // 構造函數
    public FFmpegWrapper(string ffmpegPath)
    {
        _ffmpegPath = ffmpegPath;
        if (!File.Exists(_ffmpegPath))
        {
            throw new FileNotFoundException("FFmpeg executable not found!", _ffmpegPath);
        }
    }

    /// <summary>
    /// 獲取視頻信息
    /// </summary>
    public async Task<VideoInfo> GetVideoInfoAsync(string inputPath)
    {
        if (!File.Exists(inputPath))
        {
            throw new FileNotFoundException("Input video file not found!", inputPath);
        }

        var startInfo = new ProcessStartInfo
        {
            FileName = _ffmpegPath,
            Arguments = $"-i \"{inputPath}\"",
            RedirectStandardError = true,
            UseShellExecute = false,
            CreateNoWindow = true
        };

        using var process = new Process { StartInfo = startInfo };
        process.Start();

        string output = await process.StandardError.ReadToEndAsync();
        await process.WaitForExitAsync();

        // 解析視頻信息
        return ParseVideoInfo(output);
    }

    /// <summary>
    /// 轉換視頻格式
    /// </summary>
    public async Task ConvertVideoAsync(string inputPath, string outputPath, VideoConversionOptions options)
    {
        if (!File.Exists(inputPath))
        {
            throw new FileNotFoundException("Input video file not found!", inputPath);
        }

        // 構建FFmpeg命令
        string arguments = BuildFFmpegArguments(inputPath, outputPath, options);

        var startInfo = new ProcessStartInfo
        {
            FileName = _ffmpegPath,
            Arguments = arguments,
            RedirectStandardError = true,
            UseShellExecute = false,
            CreateNoWindow = true
        };

        using var process = new Process { StartInfo = startInfo };

        // 添加輸出數據接收處理
        process.ErrorDataReceived += (sender, e) =>
        {
            if (e.Data != null)
            {
                UpdateProgress(e.Data);
            }
        };

        process.Start();
        process.BeginErrorReadLine();

        await process.WaitForExitAsync();

        if (process.ExitCode != 0)
        {
            throw new Exception($"FFmpeg process exited with code {process.ExitCode}");
        }
    }

    /// <summary>
    /// 構建FFmpeg命令參數
    /// </summary>
    private string BuildFFmpegArguments(string inputPath, string outputPath, VideoConversionOptions options)
    {
        var args = new List<string>
        {
            "-i", $"\"{inputPath}\"",
            "-y" // 覆蓋輸出文件
        };

        // 添加視頻編碼器
        if (!string.IsNullOrEmpty(options.VideoCodec))
        {
            args.Add("-c:v");
            args.Add(options.VideoCodec);
        }

        // 添加音頻編碼器
        if (!string.IsNullOrEmpty(options.AudioCodec))
        {
            args.Add("-c:a");
            args.Add(options.AudioCodec);
        }

        // 設置視頻比特率
        if (options.VideoBitrate > 0)
        {
            args.Add("-b:v");
            args.Add($"{options.VideoBitrate}k");
        }

        // 設置音頻比特率
        if (options.AudioBitrate > 0)
        {
            args.Add("-b:a");
            args.Add($"{options.AudioBitrate}k");
        }

        // 設置分辨率
        if (!string.IsNullOrEmpty(options.Resolution))
        {
            args.Add("-s");
            args.Add(options.Resolution);
        }

        // 添加輸出文件路徑
        args.Add($"\"{outputPath}\"");

        return string.Join(" ", args);
    }

    /// <summary>
    /// 更新轉換進度
    /// </summary>
    private void UpdateProgress(string data)
    {
        // 解析FFmpeg輸出,計算進度
        if (data.Contains("time="))
        {
            try
            {
                var timeIndex = data.IndexOf("time=");
                var timeStr = data.Substring(timeIndex + 5, 11);
                var time = TimeSpan.Parse(timeStr);

                // 假設我們已經知道總時長,這里簡化處理
                double percentage = (time.TotalSeconds / 100.0) * 100;
                OnProgress?.Invoke(Math.Min(percentage, 100));
            }
            catch
            {
                // 解析失敗時忽略
            }
        }
    }

    /// <summary>
    /// 解析視頻信息
    /// </summary>
    private VideoInfo ParseVideoInfo(string ffmpegOutput)
    {
        var videoInfo = new VideoInfo();

        // 解析時長
        var durationMatch = System.Text.RegularExpressions.Regex.Match(ffmpegOutput, @"Duration: (\d{2}):(\d{2}):(\d{2})\.(\d{2})");
        if (durationMatch.Success)
        {
            videoInfo.Duration = TimeSpan.Parse($"{durationMatch.Groups[1]}:{durationMatch.Groups[2]}:{durationMatch.Groups[3]}.{durationMatch.Groups[4]}");
        }

        // 解析分辨率
        var resolutionMatch = System.Text.RegularExpressions.Regex.Match(ffmpegOutput, @"(\d{2,4})x(\d{2,4})");
        if (resolutionMatch.Success)
        {
            videoInfo.Width = int.Parse(resolutionMatch.Groups[1].Value);
            videoInfo.Height = int.Parse(resolutionMatch.Groups[2].Value);
        }

        return videoInfo;
    }
}

/// <summary>
/// 視頻轉換選項類
/// </summary>
public class VideoConversionOptions
{
    public string VideoCodec { get; set; }
    public string AudioCodec { get; set; }
    public int VideoBitrate { get; set; }
    public int AudioBitrate { get; set; }
    public string Resolution { get; set; }
}

/// <summary>
/// 視頻信息類
/// </summary>
public class VideoInfo
{
    public TimeSpan Duration { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}

3.2 使用示例

下面是如何使用FFmpegWrapper類的示例代碼:

static async Task Main(string[] args)
{
    try
    {
        // 初始化FFmpeg包裝器
        var ffmpeg = new FFmpegWrapper(@"D:\Software\ffmpeg-master-latest-win64-gpl-shared\bin\ffmpeg.exe");

        // 設置進度回調
        ffmpeg.OnProgress += (percentage) =>
        {
            Console.WriteLine($"轉換進度: {percentage:F2}%");
        };

        // 獲取視頻信息
        string inputPath = @"D:\Video\1.mp4";
        var videoInfo = await ffmpeg.GetVideoInfoAsync(inputPath);
        Console.WriteLine($"視頻時長: {videoInfo.Duration}");
        Console.WriteLine($"分辨率: {videoInfo.Width}x{videoInfo.Height}");

        // 設置轉換選項
        var options = new VideoConversionOptions
        {
            VideoCodec = "libx264", // H.264編碼
            AudioCodec = "aac",     // AAC音頻編碼
            VideoBitrate = 2000,    // 2000kbps視頻比特率
            AudioBitrate = 128,     // 128kbps音頻比特率
            Resolution = "1280x720" // 720p分辨率
        };

        // 執行轉換
        string outputPath = @"D:\output.mkv";
        await ffmpeg.ConvertVideoAsync(inputPath, outputPath, options);

        Console.WriteLine("視頻轉換完成!");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"錯誤: {ex.Message}");
    }
}

圖片圖片

4. 常見視頻轉換場景

4.1 轉換為MP4格式

var options = new VideoConversionOptions
{
    VideoCodec = "libx264",
    AudioCodec = "aac",
    VideoBitrate = 2000,
    AudioBitrate = 128
};
await ffmpeg.ConvertVideoAsync("input.avi", "output.mp4", options);

4.2 轉換為WebM格式

var options = new VideoConversionOptions
{
    VideoCodec = "libvpx-vp9",
    AudioCodec = "libvorbis",
    VideoBitrate = 1500,
    AudioBitrate = 128
};
await ffmpeg.ConvertVideoAsync("input.mp4", "output.webm", options);

4.3 壓縮視頻

var options = new VideoConversionOptions
{
    VideoCodec = "libx264",
    AudioCodec = "aac",
    VideoBitrate = 1000, // 降低比特率
    Resolution = "1280x720" // 降低分辨率
};
await ffmpeg.ConvertVideoAsync("input.mp4", "compressed.mp4", options);

5. 總結

本文介紹了如何使用C#封裝FFmpeg實現視頻格式轉換功能。通過封裝,我們可以:

  • 更方便地調用FFmpeg功能
  • 監控轉換進度
  • 獲取視頻信息
  • 靈活設置轉換參數

這個實現可以作為基礎,根據實際需求進行擴展,比如添加更多的轉換選項、支持更多的格式等。

責任編輯:武曉燕 來源: 技術老小子
相關推薦

2024-10-16 11:28:42

2024-12-31 00:08:37

C#語言dynamic?

2024-09-10 10:34:48

2024-11-06 11:38:59

C#單例模式

2024-12-23 10:06:45

C#深拷貝技術

2022-06-16 07:50:35

數據結構鏈表

2024-05-07 07:58:47

C#程序類型

2024-05-17 08:42:52

AttributeMyClass方法

2024-02-02 11:03:11

React數據Ref

2024-10-21 07:05:14

C#特性語言

2022-03-05 23:29:18

LibuvwatchdogNode.js

2024-01-29 08:21:59

AndroidOpenCV車牌

2025-06-20 09:57:42

2024-07-03 08:15:39

C#字符串表達式

2023-08-01 12:51:18

WebGPT機器學習模型

2024-01-02 12:05:26

Java并發編程

2021-12-01 07:19:44

C# Npoi Excel

2024-07-29 10:35:44

KubernetesCSI存儲

2023-12-27 07:31:45

json產品場景

2023-10-30 07:05:31

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久国产精品视频 | 91天堂| 日韩三区在线 | 亚洲精品1区 | 毛片链接 | 天天综合网天天综合 | 亚洲欧美精品国产一级在线 | 欧美天堂 | 欧美日韩在线视频一区 | 91福利网| 亚洲一区二区三区在线视频 | 老外几下就让我高潮了 | 国产精品久久久久久久久久久久 | 18成人在线观看 | 欧美日韩高清免费 | a级片在线观看 | 国产精品一二三区 | 精品日韩一区 | 一区二区三区四区在线免费观看 | 亚洲精品自在在线观看 | 精品无码久久久久久国产 | 日韩成年人视频在线 | 国产一区精品在线 | 亚洲国产成人精品女人久久久 | hitomi一区二区三区精品 | 亚洲精品欧美 | 久久久婷| 亚洲精品一区二区三区四区高清 | 亚洲91av| 精品国产精品国产偷麻豆 | 日韩国产精品一区二区三区 | 蜜桃毛片 | 亚洲精品二区 | 国产伊人精品 | 国产成人一区二区三区久久久 | 天天综合久久 | 伊人影院99 | 一区二区三区不卡视频 | 在线视频日韩 | 羞视频在线观看 | 亚洲欧美在线观看 |