ffmpegで動画の一部を切り出す

OS:Ubuntu Server 12.04
FFmpeg: 2.8.14

動画ファイルの一部をうまい具合に切り出してそのシーンばかりを楽しみたいという動機にもとづいてffmpegを用いるものである。-ssオプションで切り出しの開始時刻を指定し、終了時刻を-toオプションで示してやるのである。しかしながら-ssオプションを-iオプションの前へ遣るか後ろに置くかで-toオプションの挙動が転じてしまうので細やかな注意を要する。

動画vid.mkvの3分8秒の地点から3分17秒の地点までの9秒間を切り出すためにはこんな具合である。

$ ffmpeg -ss 03:08 -i vid.mkv -to 00:09 -c copy cut.mkv

-iオプションよりも手前に-ssオプションを設置した場合タイムスタンプがリセットされ、切り出し開始時刻の03:08を00:00と捉えることになるから9秒後の地点は勿論00:09ということである。切り出す時間を計算して割り出すのが面倒な向きには-copytsオプションも追加することでタイムスタンプをそのまま解釈させることもできるということであった。

$ ffmpeg -ss 03:08 -i vid.mkv -to 03:17 -c copy -copyts cut.mkv

-ssの位置取りが-iよりも手前であるとキーフレームにもとづいて処理をするから大変迅速だということである。一方、-iオプションよりも後方へ-ssオプションを構える場合はタイムスタンプがリセットされることは無いからこうである。此れは処理が遅いということであったけれどもテストに使用した動画ファイルでは-ssを-iの前においた場合と然程変化は見られなかった。

$ ffmpeg -i vid.mkv -ss 3:08 -to 3:17 -c copy cut.mkv

然しながらどちらも切り取った動画は最初の5秒間が真っ黒な画面でスタートして困った。どうも-c copyオプションで単純に切り出しを試みる場合はIフレームで以って切断するから其の位置が大変重要になるようである。元の動画のIフレームがどこに挟まれているのかを確認してみるとこういう具合であった。

$ ffprobe -show_frames -select_streams v -show_entries frame=pkt_pts_time,pict_type vid.mkv | grep -B1 "=I"
(snip)
--
pkt_pts_time=186.645000
pict_type=I
--
pkt_pts_time=193.652000
pict_type=I

3分8秒(=188秒)から切り取りたいけれどもそこにIフレームがないために5秒後の193.652秒地点まで動画が真っ暗になってしまうような風情である。切り出し開始より手前のIフレームから動画を切り取ってffmpeg -i cut.mkv -g 1 iframe.mkvとしてIフレームがみっしりと詰まった動画に変換してから改めて精緻に切り出そうと試みたがどうしても思惑通りにならないのでffmpegは奥が深いものである。

参考:
Seeking – FFmpeg
How to get time stamp of closest keyframe before a given timestamp with FFmpeg?
キーフレームとは?Iフレーム・Pフレーム・Bフレームの違い【GOP】

Similar Posts:

“ffmpegで動画の一部を切り出す” への1件の返信

cobbsteven へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください