0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🧪 第7回:【ffmpeg連携編】複数の動画区間を一括書き出しする処理を生成AIと構築

Posted at

はじめに:

前回までで、動画の再生・操作・区間指定・ジョブ管理が整いました。
でも、それらがすべて揃っていても「出力できないなら意味がない」のです。

この回では、ffmpeg を C# から制御することで、ユーザーが指定した分割区間を高速かつ無劣化でMP4に書き出す機能を作っていきます。

もちろん、Copilotへのプロンプトだけで実装しています。


ffmpeg の基本コマンドを生成AIに聞いてみた

筆者がCopilotに出した指示:

💬「C#からffmpeg.exeを呼び出して、指定区間だけをMP4で出力したい」
💬「入力ファイル、開始時間、出力ファイル名、ffmpegのコーデック指定を加えて」

Copilotから提案されたコマンド構文は:

ffmpeg -y -ss [開始時間] -i "input.mp4" -to [継続時間] -c:v copy -c:a aac "output.mp4"

このコマンドは無劣化で映像をコピーしつつ、音声を AAC でエンコードする最適な構成になっています。

💡 -ss は開始時間、-to は抽出する「継続時間」なので、終了時間 - 開始時間 で算出しています。


書き出し処理の C# 実装コード(BtnExportAll_Click)

private void BtnExportAll_Click(object sender, EventArgs e)
{
    string input = txtVideoPath.Text;
    string dir = txtOutputPath.Text;

    if (!File.Exists(input) || !Directory.Exists(dir))
    {
        MessageBox.Show("動画ファイルまたは出力先フォルダが見つかりません。");
        return;
    }

    string ffmpegPath = EnsureFfmpegPath();
    if (string.IsNullOrEmpty(ffmpegPath))
    {
        MessageBox.Show("ffmpeg.exe が準備できませんでした。");
        return;
    }

    var validJobs = dgvJobs.Rows
        .Cast<DataGridViewRow>()
        .Where(row =>
            TimeSpan.TryParse(row.Cells[0]?.Value?.ToString(), out var start) &&
            TimeSpan.TryParse(row.Cells[1]?.Value?.ToString(), out var end) &&
            !string.IsNullOrWhiteSpace(row.Cells[2]?.Value?.ToString()) &&
            end > start
        ).ToList();

    if (!validJobs.Any())
    {
        MessageBox.Show("有効なジョブがありません。");
        return;
    }

    progressBarExport.Visible = true;
    progressBarExport.Maximum = validJobs.Count;
    progressBarExport.Value = 0;

    foreach (var row in validJobs)
    {
        string startStr = row.Cells[0].Value.ToString();
        string endStr   = row.Cells[1].Value.ToString();
        string name     = row.Cells[2].Value.ToString();

        TimeSpan start = TimeSpan.Parse(startStr);
        TimeSpan end   = TimeSpan.Parse(endStr);
        string output  = Path.Combine(dir, name + ".mp4");

        string args = $"-y -ss {start} -i \"{input}\" -to {end - start} -c:v copy -c:a aac \"{output}\"";

        using (var proc = new Process())
        {
            proc.StartInfo = new ProcessStartInfo
            {
                FileName = ffmpegPath,
                Arguments = args,
                UseShellExecute = false,
                CreateNoWindow = true
            };
            proc.Start();
            proc.WaitForExit();
        }

        progressBarExport.Value++;
        progressBarExport.Refresh();
    }

    progressBarExport.Visible = false;
    MessageBox.Show("出力が完了しました");
}

出力先フォルダの選択機能(Copilotに追加実装してもらった)

private void BtnSelectOutput_Click(object sender, EventArgs e)
{
    using (var fbd = new FolderBrowserDialog())
    {
        if (fbd.ShowDialog() == DialogResult.OK)
            txtOutputPath.Text = fbd.SelectedPath;
    }
}

Copilotに「保存先を選ぶ機能を追加したい」と伝えるだけで、即座に適切な FolderBrowserDialog を使ったコードが返ってきます。


ffmpeg.exe の自動取得機能

最初から ffmpeg を導入しているユーザーばかりではないため、「ffmpeg.exe が見つからないなら自動で取得してくれないか?」とCopilotに頼んでみました。

返ってきたコード(概要):

string url = "https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip";
WebClient.DownloadFile(url, zipPath);
ZipFile.ExtractToDirectory(zipPath, ffmpegDir);
Directory.EnumerateFiles(ffmpegDir, "ffmpeg.exe", ...);

このコードは、ZIPで一式ダウンロードして、ffmpeg.exe を探し出し、コピーして配置するところまで行います。
結果、ユーザーの操作なしにffmpegが準備されるという煩わしい処理の自動化が実現しました。

もちろん using (...) {} に置き換えることで、C# 7.3 に対応済みです。


出力処理の視覚化:プログレスバーとの連動

ユーザーが複数ジョブを登録して一括出力する際、進捗が見えないと不安になるものです。
そこでプログレスバーを追加しました。

progressBarExport.Visible = true;
progressBarExport.Maximum = validJobs.Count;
progressBarExport.Value = 0;

foreach (var row in validJobs)
{
    ...
    progressBarExport.Value++;
    progressBarExport.Refresh();
}

生成AIには:

💬「出力が終わるたびに進捗バーを進めてほしい」
とだけ伝えれば、必要な処理と表示制御を一括で返してくれます。


出力処理の高速化と安全性

Copilotからの助言:

  • -c:v copy を使うことで映像は無変換で高速書き出し可能
  • -c:a aac により音声だけ適正エンコード
  • -y オプションで上書き確認を省略
  • UseShellExecute = false にして GUIを開かないように

これらは全部、Copilotが「おすすめ構成はこちらです」とコードに含めてくれたもの。信頼感あります。


まとめ:書き出し処理もCopilotにとっては“得意分野”

この回で得られた学び:

機能 実装方法 AIとの連携
ffmpeg呼び出し ProcessStartInfo + 引数構築 プロンプトで構文と実行制御を一式生成
自動取得 WebClient + Zip解凍 + 探索 CopilotがURLと展開処理を提案
プログレスバー 有効ジョブ数と連動 AIが進捗管理まで視野に入れる
C# 7.3 対応 using (...) {} AIが文法まで合わせてくれる

ffmpeg連携は「ツールの機能性に直結する」領域ですが、生成AIが最も得意とする分野でもありました。
コマンド構文も、エラーハンドリングも、実行制御も、Copilotが完璧に組み立ててくれます。


次回:【エラー対策編】

どんなアプリでもトラブルはつきもの。

次回では、以下のような問題にどう対応したかをご紹介:

  • C#バージョンが古くて using var が使えない
  • VLCのDLLが見つからず起動しない
  • ffmpeg の展開先に ffmpeg.exe がない
  • ジョブの終了時間が開始時間より前になっている
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?