FFmpegコマンドラインからRustへ：多シーン実践ガイド


FFmpegは、動画編集やフォーマット変換など多岐にわたる用途で使われる強力なマルチメディア処理ツールです。しかし、FFmpegのコマンドラインインターフェース（CLI）を直接使う際、次のような課題に直面することがあります：

1. **コマンドの複雑さ**  
   FFmpegのコマンドライン引数は数が多く、初心者には覚えるのが大変です。設定を間違えるとデバッグが難しくなることも。
2. **Rustとの統合の難しさ**  
   Rustのようなモダンなプログラミング言語でFFmpegのC言語APIを直接呼び出す場合、メモリ管理や安全性が複雑になり、メモリリークや不正アクセスのリスクが伴います。

こうした問題を解決するため、Rustコミュニティでは[`ez-ffmpeg`](https://github.com/YeautyYE/ez-ffmpeg)のようなラッパーライブラリが提供されています。これを使えば、RustでFFmpegをシンプルかつ安全に活用できます。

ここでは、よくあるシーンをもとに、FFmpegのCLIコマンドをRustコードに変換する方法を紹介します。実践的なコード例で、あなたのプロジェクトにすぐ活かせるアイデアをお届けします！

---

## 1. 動画フォーマットの変換

**FFmpeg CLIでのコマンド：**

```bash
ffmpeg -i input.mp4 output.avi
```

**Rustでの実装：**

```rust
use ez_ffmpeg::{FfmpegContext, FfmpegScheduler};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let context = FfmpegContext::builder()
        .input("input.mp4")
        .output("output.avi")
        .build()?;

    FfmpegScheduler::new(context)
        .start()?
        .wait()?;
    Ok(())
}
```

**ポイント**：`ez-ffmpeg`を使えば、シンプルなメソッドチェーンで動画を変換。CLIの煩雑さから解放されます！

---

## 2. 音声の抽出

**FFmpeg CLIでのコマンド：**

```bash
ffmpeg -i input.mp4 -vn -acodec copy output.aac
```

**Rustでの実装：**

```rust
use ez_ffmpeg::{FfmpegContext, FfmpegScheduler};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let context = FfmpegContext::builder()
        .input("input.mp4")
        .output("output.aac")
        .no_video()
        .build()?;

    FfmpegScheduler::new(context)
        .start()?
        .wait()?;
    Ok(())
}
```

**ポイント**：`-vn`（ビデオなし）をRustでは`.no_video()`で簡単に指定。直感的でミスが減ります。

---

## 3. 動画のクリッピング

**FFmpeg CLIでのコマンド：**

```bash
ffmpeg -i input.mp4 -ss 00:00:10 -t 00:00:05 -c copy output.mp4
```

**Rustでの実装：**

```rust
use ez_ffmpeg::{FfmpegContext, Input, FfmpegScheduler};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let context = FfmpegContext::builder()
        .input(Input::from("input.mp4")
            .set_start_time_us(10_000_000)
            .set_recording_time_us(5_000_000))
        .output("output.mp4")
        .build()?;

    FfmpegScheduler::new(context)
        .start()?
        .wait()?;
    Ok(())
}
```

**ポイント**：開始時間や再生時間をマイクロ秒単位で細かく設定。CLIより柔軟性が高く、可読性も抜群です。

---

## 4. 動画からGIFを作成

**FFmpeg CLIでのコマンド：**

```bash
ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos" -c:v gif output.gif
```

**Rustでの実装：**

```rust
use ez_ffmpeg::{FfmpegContext, FfmpegScheduler};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let context = FfmpegContext::builder()
        .input("input.mp4")
        .filter_desc("fps=10,scale=320:-1:flags=lanczos")
        .output("output.gif")
        .build()?;

    FfmpegScheduler::new(context)
        .start()?
        .wait()?;
    Ok(())
}
```

**ポイント**：フィルターを`.filter_desc()`でそのまま適用。GIF作成がこんなに簡単に！

---

## 5. 動画の結合

**FFmpeg CLIでのコマンド：**

```bash
ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
```

**Rustでの実装：**

```rust
use ez_ffmpeg::{FfmpegContext, FfmpegScheduler};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let inputs = vec!["file1.mp4", "file2.mp4"];

    let context = FfmpegContext::builder()
        .inputs(inputs)
        .output("output.mp4")
        .build()?;

    FfmpegScheduler::new(context)
        .start()?
        .wait()?;
    Ok(())
}
```

**ポイント**：テキストファイル不要で、Rustのベクターを使って直感的にファイルを指定。手間が激減します。

---

## まとめ：RustでFFmpegをもっと快適に

[`ez-ffmpeg`](https://github.com/YeautyYE/ez-ffmpeg)は、RustにおけるFFmpegの操作を安全かつシンプルにする強力な味方です。CLIの複雑さやC言語APIのリスクを回避しつつ、動画編集やマルチメディア処理を効率よく実現できます。

ぜひこのガイドを参考に、あなたのRustプロジェクトで`ez-ffmpeg`を試してみてください。コードを書く楽しさが倍増すること間違いなしです！