⚠️ 注意
本記事に掲載している内容は、個人が学習・検証目的のものです。
業務情報、社外秘情報、特定の企業・組織に関する内容は一切含まれていません。
利用は自己責任でお願いします。
概要
ffmpegでLGPL版に差し替えたことで libx264 / libx265 が使えなくなり、切り出し(=再エンコード)が失敗してしまった場合の対処法を記載します
今回のcase
case1(動画の切り出しを想定)
cmd = [
ffmpeg_cmd,
"-y",
"-ss", f"{start_sec:.3f}",
"-to", f"{end_sec:.3f}",
"-fflags", "+genpts",
"-i", in_p,
"-avoid_negative_ts", "make_zero",
"-map", "0:v:0",
"-c:v", "libx264",
"-preset", "fast",
"-pix_fmt", "yuv420p",
"-movflags", "+faststart",
out_p,
]
case2(動画切り出し進捗バー用を想定)
args = [
"-y",
"-ss", f"{start_sec:.3f}",
"-to", f"{end_sec:.3f}",
"-fflags", "+genpts",
"-i", input_path,
"-avoid_negative_ts", "make_zero",
"-map", "0:v:0",
"-c:v", "libx264",
"-preset", "fast",
"-pix_fmt", "yuv420p",
"-movflags", "+faststart",
"-progress", "pipe:1",
"-nostats",
output_path,
]
方針1:「再エンコードなし(stream copy)」にする
H.264/AAC の mp4 を切り出すだけなら、基本これでOKです。
(めちゃ速い・劣化なし)
-c copy:再エンコードしない
-avoid_negative_ts make_zero:開始時刻ズレ対策
※ ただし GOP(キーフレーム)境界の関係で、開始が数フレームずれることがあります
case1(動画の切り出しを想定)
cmd = [
ffmpeg_cmd,
"-y",
"-ss", f"{start_sec:.3f}",
"-to", f"{end_sec:.3f}",
"-fflags", "+genpts",
"-i", in_p,
"-avoid_negative_ts", "make_zero",
"-map", "0:v:0",
"-c:v", "copy",
"-movflags", "+faststart",
out_p,
]
case2(動画切り出し進捗バー用を想定)
args = [
"-y",
"-ss", f"{start_sec:.3f}",
"-to", f"{end_sec:.3f}",
"-fflags", "+genpts",
"-i", input_path,
"-avoid_negative_ts", "make_zero",
"-map", "0:v:0",
"-c:v", "copy",
"-movflags", "+faststart",
"-progress", "pipe:1",
"-nostats",
output_path,
]
結論(最大どのくらいズレる?)
▶ 最大で「1 GOP(キーフレーム間隔)」分ズレます
= 0.5 秒 ~ 数秒が理論上の最大です。
ただし 現実的にはもっと小さいことがほとんどです。
もう少し正確に言うと
-c copy(再エンコードなし)の切り出しは:
開始位置:
👉 指定時刻 より前の直近キーフレーム まで戻る
終了位置:
👉 指定時刻 以降の次のキーフレーム まで進むことがある
つまり:
[ 前のキーフレーム ]----指定start----(理想)
実際は 👇
[ 前のキーフレーム ]←ここから始まる
ちょっと前から始まって、ちょっと後で終わるイメージ
ズレ量を決める要因
1)GOPサイズ(キーフレーム間隔)
| 動画の種類 | GOPの目安 | 最大ズレ |
|---|---|---|
| スマホ動画 | 0.5〜1秒 | ~1秒 |
| 一般MP4 | 1〜2秒 | ~2秒 |
| 長尺圧縮動画 | 2〜5秒 | ~5秒 |
| 極端な圧縮 | 10秒以上 | まれ |
2)フレームレート
30fps / 60fps → 体感ズレは小さく見える
低fps → ズレが目立ちやすい
参考:ズレを最小化するコマンド小技 これを使うと copyでもズレが小さくなりやすいです:
-ss を -i の後ろに置く
ただし速度は落ちます
理由は ffmpeg の「-ss の置き場所」で処理方式が変わるからです。
copy のズレが減りやすいのは、その差が効きます。
-ss を「-i の前」に置く場合(高速だけどズレやすい)
ffmpeg -ss 10 -to 20 -i in.mp4 -c copy out.mp4
これは **入力を開く前に“だいたいこの辺”へジャンプ(シーク)**します。
このとき ffmpeg は キーフレーム(Iフレーム)単位でしか正確に飛べないので、
指定時刻の 直前のキーフレーム から始まる
その結果、開始が少し前にずれるという動作になりやすいです。
(その代わりめちゃ速い)
-ss を「-i の後」に置く場合(遅いけどズレが減りやすい)
ffmpeg -i in.mp4 -ss 10 -to 20 -c copy out.mp4
これは まず入力を開いてから、
いったんデコード(読み進め)指定の時刻まで到達したところで出力を開始
という動きになりやすく、結果として
目標時刻に より近い位置から切り出せる
ことが多いです。
(ただし -c copy だと完全にフレーム単位の厳密さは出ません。GOP境界の制約は残ります)
方針2:「LGPLビルドで利用可能なエンコーダ」にする
リスクとして以下が挙げられます
1) 速度が遅い・CPU負荷が高い
-c copy と比べると 数倍〜数十倍時間がかかることがあります。
Core i5 / RAM8GB だと、長尺や高解像度は体感で重くなります。
2) 出力品質(画質劣化)とビットレート増
再エンコードなので、
・多少の画質劣化
・出力サイズが大きくなる/小さくなる
が起きます。
case1(動画の切り出しを想定)
cmd = [
ffmpeg_cmd,
"-y",
"-ss", f"{start_sec:.3f}",
"-to", f"{end_sec:.3f}",
"-fflags", "+genpts",
"-i", in_p,
"-avoid_negative_ts", "make_zero",
"-map", "0:v:0",
"-c:v", "libopenh264",
"-pix_fmt", "yuv420p",
"-movflags", "+faststart",
out_p,
]
case2(動画切り出し進捗バー用を想定)
args = [
"-y",
"-ss", f"{start_sec:.3f}",
"-to", f"{end_sec:.3f}",
"-fflags", "+genpts",
"-i", input_path,
"-avoid_negative_ts", "make_zero",
"-map", "0:v:0",
"-c:v", "libopenh264",
"-pix_fmt", "yuv420p",
"-movflags", "+faststart",
"-progress", "pipe:1",
"-nostats",
output_path,
]
どのくらい時間がかかる?
前提条件
CPU:Core i5(第8〜10世代クラス)
メモリ:8GB
OS:Windows
入力:H.264 MP4
出力:H.264(libopenh264)
音声:なし
フィルタ:なし
切り出し長 × 処理時間の目安
| 切り出し長 | 体感処理時間 | 備考 |
|---|---|---|
| 5秒 | 0.5〜2秒 | ほぼ一瞬 |
| 10秒 | 1〜4秒 | UI待ち許容 |
| 30秒 | 10~30秒 | 少し待つ |
| 1分 | 30~90秒 | 実時間前後 |
| 3分 | 2~6分 | やや重い |
| 5分 | 4~10分 | 人によって不満 |
| 10分 | 8~20分 | 実務では難しい |
なぜ libopenh264 は遅いのか
CPUエンコードのみ
x264 のような高度な最適化がない
並列化効率がやや低い
品質あたりのビット効率が控えめ
つまり
👉 **「正確だけど速くはない」**エンコーダです。
速度を左右する主因(重要)
① 解像度
720p:速い
1080p:普通
4K:激遅
② フレームレート
30fps:標準
60fps:約1.5〜2倍遅い
③ 切り出し開始位置
-ss を前に置く → 少し速い
-ss を後に置く → 正確だが遅い
copy / libopenh264 の最終使い分け指針
| 用途 | おすすめ |
|---|---|
| プレビュー・仮切り | -c copy |
| 再解析用動画 | -c copy |
| 教育・比較・報告 | libopenh264 |
| 秒単位が重要 | libopenh264 |
※ちなみに今回は以下を使用しています
ffmpeg-N-122221-g1fcb201ab1-win64-lgpl.zip
