成人免费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#深拷貝技術

2024-05-07 07:58:47

C#程序類型

2024-10-21 07:05:14

C#特性語言

2022-06-16 07:50:35

數據結構鏈表

2024-05-17 08:42:52

AttributeMyClass方法

2024-02-02 11:03:11

React數據Ref

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#字符串表達式

2024-07-29 10:35:44

KubernetesCSI存儲

2023-12-27 07:31:45

json產品場景

2023-10-30 07:05:31

2024-01-19 08:25:38

死鎖Java通信

2024-02-04 00:00:00

Effect數據組件

2023-07-26 13:11:21

ChatGPT平臺工具
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美在线小视频 | 中文字幕高清在线 | 毛片毛片毛片毛片 | 亚洲视频在线看 | 国产日韩欧美一区二区 | 免费视频一区二区 | 中文字幕日韩欧美一区二区三区 | 亚洲电影成人 | 久久新视频 | 欧美a区| 欧美成人一级 | 国产一级片av | 中文字幕欧美在线观看 | 精品国产一区二区三区四区在线 | 韩日一区二区三区 | 欧美日韩网站 | 成人欧美一区二区三区黑人孕妇 | 久久久2o19精品 | 午夜在线小视频 | 国产亚洲精品久久久久久豆腐 | 国产成人一区二区三区 | 亚洲午夜视频在线观看 | 久久国产欧美日韩精品 | 国产清纯白嫩初高生视频在线观看 | 欧美色综合一区二区三区 | 亚洲成av人片在线观看无码 | 羞羞网站在线观看 | 日韩精品一区二区三区在线 | 日韩欧美在线视频播放 | 自拍视频国产 | 国产视频久久久 | 精品国产乱码久久久久久丨区2区 | 久久综合一区 | 免费视频99 | 欧美精品a∨在线观看不卡 欧美日韩中文字幕在线播放 | 国产成人精品综合 | 久久久久免费精品国产 | 日韩国产中文字幕 | 91免费观看国产 | 日韩淫片免费看 | 欧美日韩亚洲在线 |