• 2

ffmpeg剪輯影片速度??


fedora wrote:
那是「關鍵幀」的問題...(恕刪)

ahwaiyuen98 wrote:
你好像甚麼都没看,#27...(恕刪)


感謝樓上兩位大大的詳細解說

來陰的 wrote:
但又出現一個問題了 就是切出來的影片 前半秒會定格這樣


用ffmpeg無損剪輯(不轉檔)
剪出來的影片有時候會
幾秒後才開始播 (MPC-HC)
剛開始會破圖 (VLC media player)

點時間軸跳到別的時間點時,有一點點卡卡的、不像平常那麼順(PotPlayer)

可以用 -use_editlist 0 來處理
也許就不會出現上述情形
=====
以下內容只是猜測,不確定是不是對的

假設 0:0:10 是 關鍵幀 ,而 0:0:11 不是關鍵幀
現在要從 0:0:11 開始剪

一般剪法:
ffmpeg -ss 0:0:11 -to 0:0:20 -i 1.mp4 -c copy out.mp4

1.因為是 -c copy 無損剪輯,所以從關鍵幀開始剪,把0:0:10 到 0:0:20的資料寫進 out.mp4
2.把editlist寫進out.mp4。在editlist註明從 「第 1 秒」 開始播放。
out.mp4的 0:0:0 的畫面,等於1.mp4的0:0:11的畫面 (PotPlayer)


用 -use_editlist 0 來剪
ffmpeg -ss 0:0:11 -to 0:0:20 -i 1.mp4 -c copy -use_editlist 0 out.mp4

1.因為是 -c copy 無損剪輯,所以從關鍵幀開始剪,把0:0:10 到 0:0:20的資料寫進 out.mp4
2.不使用editlist,沒有把editlist寫進out.mp4
out.mp4的 0:0:0 的畫面,等於1.mp4的0:0:10的畫面 (PotPlayer)

nwm310 wrote:
用ffmpeg無損剪...(恕刪)


根據層主的猜測內容,個人好奇試了一下,因為沒用過 use_editlist 這個參數,
發現結果與樓主的解釋有些落差,但我得出了結論
個人用 ffmpeg 4.1.3 (算最新版) 與 potplayer(也算是最新版)
個人測試的視顏的關鍵幀第一個在5.5s的位置,接著是9.5s 左右的位置

所以都用了fast seek的方式截取了兩個cut(差別是加了editlist 0)

ffmpeg -ss 0:0:09 -to 0:0:16 -i 1.mp4 -c copy 1.out.mp4

ffmpeg -ss 0:0:09 -to 0:0:16 -i 1.mp4 -c copy -use_editlist 0 1.editlist0.mp4

所得結論:
1. 發現ffmpeg 已經都是預設由 截取的開始時間點之前的關鍵幀截取。。。
所以只會截取 (指定時間+與前一關鍵幀的時間距離)的內容,
好處是再無停頓黑畫面的效果。。。
(本例是預計是截取7S內容,但實際截取了10S)
2. 用potplayer 播放 1.out.mp4 則實際是從原始視頻的9s開始播放
若是播放1.editlist0.mp4 則從實際視顏5.5s 開始播放
(由此可以推出editlist 0的效果,也可以推出 1.out.mp4 的 editlist就是3.5)
(也推出potplayer能識別editlist的時間坐標)

感覺一切完美了吧。。。
(對別來說是較好可接受的結,我卻認為是得到較差的效果)!!!

1. 對於一般人來說ffmpeg的這種處理方式是最完美的,不會有太大影像。
2. aegisub、影編軟件、連ffmpeg本身都無法完美識別,都會識別成10S內容(意即影像播放開始時間為5.5s)的影像檔。。。(會有失真的效果,就是potplayer播放與其它軟件處理無法相信所見即所得,當然editlist 0 可以解決,但一切都變成假的了,就無法得到預想結果的檔案內容)
3.對2次處理的該內容的人,也算是災難一場。。。

個人理想的結果。。。
應該是 截取開始時間點的下一個關鍵幀 至 結束時間點 ,一樣無損輸出
而 截取開始時間點的下一個關鍵幀 這段內容重新 壓制 產生首關鍵幀
,再合併兩段內容
(當然這會失去 "無損"的意義,且需犧牲一些壓制時間。。。
但我認為這樣產出的內容,才是較具意義的。。。XDD)
(個人希望這種理想結果,能由ffmpeg的參數代勞,自由選擇,這樣才算完美 XDD)




分享一個bat

選擇mp4裡的幾段時間範圍,另存成一個mp4
(以關鍵幀剪輯,所以時間不會很準確)

需要ffmpeg 和 ffprobe

執行方法:
把mp4拖進bat

如果拖進之後沒反應,先點兩下打開bat,
然後再把mp4拖進cmd窗口


檔名:
mp4檔名不要有單引號
支持unicode檔名(藉由8.3檔名來實現)

時間:
從「起點」往前找「最近的KeyFrame」
如果「起點」是0:0:0 ,可能會往後找

「終點」必須大於「起點」

如果終點沒有指定,就是指:起點開始的以後全部

會有錯誤訊息:
Non-monotonous DTS in output stream 0:1; previous: 7850002, current: 7847497;
changing to 7850003. This may result in incorrect timestamps in the output file.


@echo off

set "aa=.;%path%"
for %%a in (ffmpeg.exe ffprobe.exe) do (
if "%%~$aa:a" == "" echo need %%a & pause & exit /b
)

::=====================
set mp4=

if "%~x1" == ".mp4" set mp4="%~1"
if "%mp4%" == "" echo drag mp4 to here & set /p mp4=

set "mp4=%mp4:"=%"
set mp4="%mp4%"

if not exist %mp4% echo %mp4% not exist & pause & exit /b
if not %mp4% == %mp4:'=% echo single quote exist & pause & exit /b

for %%a in (%mp4%) do (
set mp4="%%~sa"
set outMp4="%%~na_out%%~xa"
)

if exist %outMp4% echo %outMp4% exist & pause & exit /b

::=========================
set timeRange=
echo input startTime endTime startTime endTime
echo for example:
echo 0:10 0:20 1:3:5 1:3:30
set /p timeRange=
if "%timeRange%" == "" echo no startTime exist & pause & exit /b

::===================
set txt=concat.txt

set ffCmd=ffprobe.exe -select_streams v
set ffCmd=%ffCmd% -show_entries "frame=pkt_pts_time"
set ffCmd=%ffCmd% -of csv -sexagesimal

cd.> %txt%
call :aa %timeRange%

ffmpeg -n -safe 0 -f concat -i %txt% -c copy %outMp4%
goto :eof

::=========================
:aa
if "%~1" == "" goto :eof

for %%a in (%mp4:\=/%) do echo file '%%~a' >> %txt%

for /f "delims=, tokens=2" %%a in ('%ffCmd% -read_intervals %~1%%+#1 %mp4%') do (
echo inpoint %%a >> %txt%
)

if not "%~2" == "" echo outpoint %~2 >> %txt%
shift & shift
goto aa
  • 2
限制級
您即將進入之討論頁 需滿18歲 方可瀏覽。
根據「電腦網路內容分級處理辦法」修正條文第六條第三款規定,已於該限制級網頁,依台灣網站分級推廣基金會規定作標示。
評分
複製連結