ハンディカムのMTSファイルをGPUで高速MP4変換



## 1. 背景

この週末は、あるセミナーのZoomウェビナー配信を担当した。配信後は、動画アーカイブを用意するのだが、通常は、Zoomの場合は、用意された録画アーカイブを用いるのが普通で、MP4ファイルを配信の内容そのままか、講演者ごとに編集ツールで無劣化でMPEG4ファイルに分割、Youtubeにアップロードの手順でスムーズに公開できていた。
カメラは **HDMI パススルーが使える Sony HDR-CX370V** を会場後方に配置し、HDMI-USB変換アダプタでWindows PCに接続して、Zoom配信と同時に、バックアップで内部メモリにも同時録画していた。
今回、**配信に載らなかったトーク部分を限定メンバーに視聴させたい**という要望が寄せられたが、Zoom録画のファイルは配信と同じ内容なので使えない。そこでカメラにバックアップしたファイルを活用することになった。
ソニーのハンディカムから録画ファイルをPCにコピーするには、USB-A ⇄ Mini-Bのケーブルがあればいい。ハンディカムのUSB接続のメニューを探して、PCからストレージに見えるようにして、ファイルをコピーした。
しかし このファイル形式はあまりなじみのない`.MTS`（AVCHD）ファイル形式で、そのままではいつも使ってる動画編集ツールが使えない。
じゃあMPEG4に変換すればいいやと、普段使いの**GPU非搭載 Windows11＋HandBrake** で変換したら、１時間素材に１時間半かかってしまった。イベントは２日間に渡り長時間だったので、これを全部変換するのは大変だなと思って、**LLM 検証用の Ubuntu 22.04＋RTX 3060/12GB** でMP4変換を試してみることにした。

## MTS (AVCHD)とMP4比較

| 項目                    | **MTS (AVCHD)**                                            | **MP4（変換後／YouTube推奨）**                       |
|-------------------------|-------------------------------------------------------------|------------------------------------------------------|
| **コンテナ**            | MPEG-TS（Transport Stream）                                | ISO Base Media File Format（`ftyp=isom/mp42` など） |
| **拡張子**              | `.mts` / `.m2ts`                                           | `.mp4`                                               |
| **動画コーデック**      | H.264/AVC *High Profile* Level 4.0<br>1080 **60i** (interlace) | H.264/AVC *High Profile* Level 4.1–4.2<br>1080 **30p** (progressive) |
| **平均ビットレート**    | 5–17 Mbps（CX370V は約 6–7 Mbps）                          | 8–14 Mbps（`-cq 19`・`maxrate 14M` 設定例）         |
| **音声コーデック**      | Dolby Digital (AC-3) 2ch 48 kHz 256 kbps                   | AAC-LC 2ch 48 kHz 192 kbps（可変 128–320 kbps 推奨） |
| **タイムコード分割**    | 2 GB / 約 17 分ごとに自動分割（連番クリップ）               | 分割なし・1ファイル                                   |
| **互換性**              | 再生ソフト依存・編集ソフトで読み込めない例あり             | Web／スマホ／NLE ほぼ全対応                           |
| **インタレース処理**    | 60i → 要デインタレ                                          | 30p／60p → そのまま                                   |
| **YouTube 自動再エンコード** | 対応外扱い（アップ可だが処理が遅い・音ズレ報告あり）         | サポート形式。`-movflags +faststart` で即ストリーム可 |


---
## 2. 環境と初期設定

| 項目 | 内容 |
|------|------|
| カメラ | Sony HDR-CX370V（1080/60i・HDMI パススルー） |
| GPU／OS | NVIDIA RTX 3060 12 GB / Ubuntu 22.04LTS |
| ドライバ | 535.xx (`ubuntu-drivers autoinstall`) |
| FFmpeg | 4.4 系（Ubuntu 標準ビルド。NVENC 有効） |

```bash
# □ OS を最新状態に
sudo apt update && sudo apt full-upgrade -y

# □ 推奨ドライバーを一発導入（535 以上想定）
sudo ubuntu-drivers autoinstall
sudo reboot

# □ 動作確認
nvidia-smi        # GPU 型番・ドライバー版が出れば OK

# □ CUDA Toolkit（任意：開発/検証用）
sudo apt install cuda-toolkit-12-4 -y
echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc
source ~/.bashrc  # nvcc が使えるようになる

# □ FFmpeg（Ubuntu 標準 4.4 系で NVENC 有効）
sudo apt install ffmpeg -y
ffmpeg -encoders | grep nvenc   # h264_nvenc が出れば準備完了
```

---

## 3. 単発エンコード（テスト）  
まずは１ファイルでテスト変換。
```bash
ffmpeg -hwaccel cuda -hwaccel_output_format cuda \
  -i 00035.MTS \
  -vf "yadif_cuda=mode=send_frame:parity=auto,scale_cuda=1920:1080" \
  -c:v h264_nvenc -preset p4 -profile:v high \
  -rc vbr -cq 19 -b:v 0 -maxrate 14M -bufsize 28M \
  -movflags +faststart \
  -c:a aac -b:a 192k \
  00035.mp4
```
- **CUDAフィルタ**利用
- CX370V は 1440×1080 60i ですが、1920×1080 30p 化すると YouTube が扱いやすいそうです
- **1080i → 1080p** を GPU 側でデインタレ＋スケール
- **h264_nvenc** でNVENC（GPU エンコード）を指定
 
30分素材の変換が１分強で完了しました。は、**速い！**

---

## 4. フォルダ一括スクリプト  
あとは、指定フォルダ以下のMTSファイルを全部変換するようにAIにスクリプトを書かせました。
```bash
#!/usr/bin/env bash
cd "${1:-.}" || exit 1
IN_OPTS=(-hwaccel cuda -hwaccel_output_format cuda)
ENC_OPTS=(-vf "yadif_cuda=mode=send_frame:parity=auto,scale_cuda=1920:1080" \
          -c:v h264_nvenc -preset p4 -rc vbr -cq 19 -b:v 0 \
          -maxrate 14M -bufsize 28M -movflags +faststart \
          -c:a aac -b:a 192k)
shopt -s nullglob nocaseglob
for mts in *.MTS; do
  mp4="${mts%.*}.mp4"
  [[ -e $mp4 ]] && { echo "SKIP $mp4"; continue; }
  s=$(date +%s)
  ffmpeg -hide_banner -loglevel error "${IN_OPTS[@]}" -i "$mts" "${ENC_OPTS[@]}" "$mp4"
  echo "DONE $mp4 $(($(date +%s)-s))s"
done
```

- 同名 MP4 があればスキップ  
- 各ファイルの所要時間を秒表示  

今回のイベント動画 30分×7本が **合計 12 分** で終了しました！

---

## 5. 所感  

せっかくのGPU資産は有効利用するべきですよね！