[FFmpeg] Seeking (跳轉 / 定位)

FFmpeg

簡介與其他資料:
 http://www.mobile01.com/topicdetail.php?f=510&t=3734550

其他範例:
  http://www.mobile01.com/topicdetail.php?f=510&t=4487462


參考資料

FFmpeg 官方資料:
  https://trac.ffmpeg.org/wiki/Seeking


介紹

假如只是要提取輸入的特定的一部份,你需要使用 seeking 選項來得到特定的一部份。

Seeking 方式

Input seeking

參數 -ss 需要被指定在 -i 之前位置:
ffmpeg -ss 00:23:00 -i input.mkv cut.mkv

這個例子將擷取 00:23:00 之後的片段。
輸入將使用 keyframes 進行解析,這速度非常快。

當 -ss 作為輸入選項 (位於 -i 之前) 時,將會定位到指定時間點並歸零的當前時間戳記,如果有使用 subtitles filter (-vf subtitles=sub.st),字幕與影音將不會正確同步。

在 FFmpeg 2.1 之後 -ss 也是精準畫格(挑轉到指定時間),無論作為輸出或輸入選項。可以使用輸入選項 -noaccurate_seek 來恢復之前的特性(跳轉到指定時間前最近的 keyframes,即使時間不準確)。

從 02:00 之前最接近的 keyframes 開始分割:
ffmpeg -noaccurate_seek -ss 00:02:00 -i input.mp4 -c copy cut.mp4


Output seeking

參數 -ss 需要被指定在 -i 之後位置:
ffmpeg -i input.mkv -ss 00:23:00 cut.mkv

這個例子將擷取 00:23:00 之後的片段。
在這裡,該輸入將被從頭解碼 (與丟棄) 直到它到達 -ss 所給定的時間點才開始輸出。


分割一部分

如果只是要影片中間提取某一片段,可以搭配使用 -t 指定持續時間,例如 -ss 60 -t 10 可以擷取輸入的 60 至 70 秒片段。或者可以使用 -to 指定一個時間點結束寫入輸出, 例如 -ss 60 -to 70 可以擷取輸入的 60 至 70 秒片段。 -t 與 -to 是互斥的,如果同時使用兩者,只有 -t 會被使用。

注意 當作 -ss 位於 -i 之前時,該時間戳記將會被歸零,所以 -t 與 -to 將會有相同的效果:
ffmpeg -ss 00:01:00 -i video.mp4 -to 00:02:00 cut.mp4
ffmpeg -i video.mp4 -ss 00:01:00 -to 00:02:00 cut.mp4

在這裡,第二個命令將直接從 `00:01:00` 至 `00:02:00` 分割出一個片段,而第一個命令將從輸入 `00:01:00` 至 `00:03:00` 分割出一個片段,因為 `00:01:00` 被歸零,所以原本 `00:03:00` 就變成了 `00:02:00`。

假如使用複製串流 (-c copy) 來分割,必須要使用 -avoid_negative_ts 1 選項,如果想要在 concat demuxer 上使用該分割的話。

例如:
ffmpeg -ss 00:03:00 -i video.mp4 -t 60 -c copy -avoid_negative_ts 1 cut.mp4


時間碼語法

注意 你可以使用兩種時間單位格式: 六十進位 (HOURS:MM:SS.MICROSECONDS,例如 01:23:45.678) 或是秒數。


Seeking 並做串流複製

使用 -ss 作為輸入選項 (位於 -i 之前) 並與 -c:v copy 一起使用則可能會不準確,因為 ffmpeg 被迫只能 使用/分割 在 I畫格 (i-frames)。如果不複製視訊串流,而是重新編碼的話,無論 -ss 作為輸入或輸出選項則都能精準時間點。

如果 -ss 作為輸出選項 並與 -c:v copy 一起使用,則輸出可能會無法正常播放:
ffmpeg  -i input.mkv -ss 00:02:00 -c copy output.mkv

分割點可以準確在 00:02:00,但輸出片段可能無法正常播放,
因為輸出的第一張畫格 (frame) 可能不是 I畫格 (i-frame)。

所以如果分割點不是 I畫格 (i-frame),為了讓輸出能正常被解碼/播放,
不能使用複製視訊的方法而必須改用重新編碼的方法來改變 GOP 結構。
2015-07-17 15:13 發佈
文章關鍵字 FFmpeg Seeking

kingdragon wrote:
分割點可以準確在 00:02:00,但輸出片段可能無法正常播放,
因為輸出的第一張畫格 (frame) 可能不是 I畫格 (i-frame)。

所以如果分割點不是 I畫格 (i-frame),為了讓輸出能正常被解碼/播放,
不能使用複製視訊的方法而必須改用重新編碼的方法來改變 GOP 結構。


一般來說,常需要作 無損 CUT 輸出,
若是無法得到這確分割時間點,影片前後可能會出現卡片1,2秒的情況
(通常未來更好的裁切,就要靠其它剪輯軟體,重關鍵幀剪切)
但仍不及 ffmpeg 的快速直覺。。。

不知k大,有無方法取得 如 00:02:00 最靠近關鍵幀的 分割點時間
(目前只會滙出關鍵幀圖片,卻無法取得該幀時間?!)
(滙出的圖片,是否能加註時間在檔名上,或印在圖片上?!)

或 可以讓ffmpeg 自己判斷,從I-frame 開始截取?
笑看風雲 wrote:
讓ffmpeg 自己判斷,從I-frame 開始截取

在 FFmpeg 2.1 之後 -ss 也是精準畫格,即使作為輸入選項時也是。
你可以使用輸入選項 -noaccurate_seek 來恢復之前的特性(只尋找最近前面一個keyframe)

請試試下列命令...
ffmpeg -noaccurate_seek -ss 00:02:00 -i input.mp4 -c copy cut.mp4


kingdragon wrote:
當 -ss 作為輸入選項 (位於 -i 之前) 時,將會定位/跳轉(seek)到指定時間點並歸零的當前時間戳記,
如果有使用 subtitles filter (-vf subtitles=sub.st),字幕與影音將不會正確同步。



K大你好,我來貢獻一個input seeking 解決字幕的問題:

先來描述我的問題:
主要是實在無法忍受output seeking 這個致命巨大延遲的問題
假設我cut一段10秒的影片 (本來只要幾秒鐘就能解決了 input seeking的話)
若從05:00 開始cut (則需要 16-22秒*5 約延遲1分半)
若從1:00:00 開始cut (則延遲 16-22杪*60 約 16分-22分 才開始cut)

後來在官網trac有找到解法:
(原來3年前就有解法,其實我也是用一般人也一定會有同樣狀況遇到同問題的思路,才拼命去找解法)

cut 50-70秒的影片,語法如下:

ffmpeg -ss 50.92 -t 20 -i input.mp4 -vf "setpts=PTS+50.92/TB,ass=22.ass,setpts=PTS-STARTPTS" output.mp4



另外關於input seeking,整理一下這幾天心得:
input seeking -ss
不能撘配-to(效果等同-t,所以用-t就好)
-t 可以放在-i 之前或之後 效果一樣


另還想請教K大:

個人想用下列語法:

-ss 0:01:50.92 需自行計算PTS為130.92 (因為PTS需為秒數)

ffmpeg -ss 0:01:50.92 -t 20 -i input.mp4 -vf "setpts=PTS+130.92/TB,ass=22.ass,setpts=PTS-STARTPTS" output.mp4


是否有函式可以直接setpts=PTS+xxxx(0:01:50.92)/TB 自動轉換為秒數?

可否提供教學語法?!
如果您想切割影片又要字幕同步的話,介紹您試試這個軟體--FCT影像轉檔
只要把影像,字幕檔拉進來,並填上起始及結束時間,再點轉檔即大功告成
下載網址:
https://drive.google.com/file/d/0B7qdXmka9XgwNG5iZlNiSjdEX2M/view?usp=sharing
內文搜尋
X
評分
評分
複製連結
Mobile01提醒您
您目前瀏覽的是行動版網頁
是否切換到電腦版網頁呢?