2016-07-07 40 views
2

我試圖在視頻上使用ffmpeg來提取特定幀的列表,用它們的幀編號表示。所以我們可以說我想從'test_video.mp4'中抽取一幀,確切地說幀號150。我可以用下面的命令使用ffmpeg提取特定幀的列表

ffmpeg -i test_video.mp4 -vf "select=gte(n\, 150)" -vframes 1 ~/test_image.jpg

但是如果我想精確幀的列表,如[100, 110, 127, 270, 300]?我一直在看這個頁面(https://ffmpeg.org/ffmpeg-filters.html#select_002c-aselect),並且可以看到有一些方法可以根據幀編號,時間戳等奇偶校驗提取多個幀,但是我找不到執行我需要的操作的語法。

理想情況下,我會提取命名約定out_image%03d.jpg下的給定幀列表,其中%03d被給定的幀編號替換,但時間戳也可以工作。

有沒有辦法做到這一點?

+1

我嘗試了很多使用如下語法的組合:'ffmpeg -i Hamlet.mp4 -vf'select = eq(1000 \,n)+ eq(150 \,n)'-f image2 out_image%03d。 jpg' - 但這並沒有達到我的預期。它所做的是從150幀開始,並給了我下一幀151(和其後)...似乎在這種情況下,選擇卡住了,只是從射擊流....我會玩更多一點。 –

回答

6

使用

ffmpeg -i in.mp4 -vf select='eq(n\,100)+eq(n\,184)+eq(n\,213)' -vsync 0 frames%d.jpg 

FFmpeg的主要是定時錄像,即媒體的處理器具有諸如幀率或採樣率的週期率。它假定輸出應該和來源相同。如果提供的框架不足,則會重複,除非被告知不要。 -vsync 0被添加,在這種情況下,它告訴它抑制重複。

+0

謝謝,完全按照要求工作。 –

1

很天真的答案...

#! /bin/sh -e 
# framegrab v0.1 

frames="$1" 
filename="$2" 
printf '%s' "$frames" | 
sed 's:\[\|\]::g; s:[, ]\+:\n:g' | 
xargs printf '%03d\n' | 
xargs -IFRAME ffmpeg -i "$filename" -vf "select=eq(n\,FRAME)" -vframes 1 out_imageFRAME.jpg 

與參數列表調用它:

framegrab '[100, 110, 127, 270, 300]' test_video.mp4 
+0

感謝您的幫助!我無法自行解決,但是,它是否每個幀數都運行一個ffmpeg進程,還是通過一次ffmpeg調用獲取所有期望的幀? –

+0

我無法得到這個工作,即使給出了一個5幀數列表,它也只輸出一個圖像文件。 –

+0

所以我通過更改'sed'來修復它:\ [:: g; S:\] ::克; s /,*/\ n/g'|'到'sed's:\ [:: g; S:\] ::克; s /,*// g'|',但我現在可以看到它只是多次運行ffmpeg。這在技術上是有效的,但對於我正在運行的嵌入式系統來說並不理想,我希望ffmpeg能夠一舉處理它。 –