我找到了這個腳本,但它需要輸入檔案名和輸出檔案名才能作業
我是 Windows 用戶,所以我不知道如何為檔案夾中的每個檔案運行此腳本
我想要的是:
sourcefile=$1 -> 這應該是輸入目錄
destfile=$2 -> 輸出目錄或只是 originalfilename_preview
所以當我嘗試執行腳本時,它將運行輸入目錄中的檔案并執行里面的兩個 ffmpeg 腳本
第一個 ffmpeg 腳本將視頻拆分為臨時檔案夾
中的多個檔案第二個 ffmpeg 合并臨時檔案夾中的這些檔案并使用輸出檔案夾或 originalfilename_preview 完成整個程序
-> 回圈下一個檔案直到完成
sourcefile=$1
destfile=$2
# Overly simple validation
if [ ! -e "$sourcefile" ]; then
echo 'Please provide an existing input file.'
exit
fi
if [ "$destfile" == "" ]; then
echo 'Please provide an output preview file name.'
exit
fi
# Get video length in seconds
length=$(ffprobe $sourcefile -show_format 2>&1 | sed -n 's/duration=//p' | awk '{print int($0)}')
# Start 20 seconds into the video to avoid opening credits (arbitrary)
starttimeseconds=20
# Mini-snippets will be 2 seconds in length
snippetlengthinseconds=2
# We'll aim for 5 snippets spread throughout the video
desiredsnippets=5
# Ensure the video is long enough to even bother previewing
minlength=$(($snippetlengthinseconds*$desiredsnippets))
# Video dimensions (these could probably be command line arguments)
dimensions=640:-1
# Temporary directory and text file where we'll store snippets
# These will be cleaned up and removed when the preview image is generated
tempdir=snippets
listfile=list.txt
# Display and check video length
echo 'Video length: ' $length
if [ "$length" -lt "$minlength" ]
then
echo 'Video is too short. Exiting.'
exit
fi
# Loop and generate video snippets
mkdir $tempdir
interval=$(($length/$desiredsnippets-$starttimeseconds))
for i in $(seq 1 $desiredsnippets)
do
# Format the second marks into hh:mm:ss format
start=$(($(($i*$interval)) $starttimeseconds))
formattedstart=$(printf "d:d:d\n" $(($start/3600)) $(($start%3600/60)) $(($start%60)))
echo 'Generating preview part ' $i $formattedstart
# Generate the snippet at calculated time
ffmpeg -i $sourcefile -vf scale=$dimensions -preset fast -qmin 1 -qmax 1 -ss $formattedstart -t $snippetlengthinseconds -threads $(nproc) $tempdir/$i.mp4
done
# Concat videos
echo 'Generating final preview file'
# Generate a text file with one snippet video location per line
# (https://trac.ffmpeg.org/wiki/Concatenate)
for f in $tempdir/*; do echo "file '$f'" >> $listfile; done
# Concatenate the files based on the generated list
ffmpeg -f concat -safe 0 -i $listfile -threads $(nproc) -an -tune zerolatency -x264opts bitrate=2000:vbv-maxrate=2000:vbv-bufsize=166 -vcodec libx264 -f mpegts -muxrate 2000K -y $destfile.mp4
echo 'Done! Check ' $destfile '.mp4!'
# Cleanup
rm -rf $tempdir $listfile
來源:https ://davidwalsh.name/video-preview
@Christopher Hoffman wsl 已經安裝,當然,我已經毫無問題地運行了這個腳本,但我需要手動輸入/輸出檔案名
./preview.sh input.mp4 out
@雷諾帕卡萊特
- 是的,輸入目錄中的所有檔案或拖放檔案(但目錄中的所有檔案似乎更容易)
- 我想修改腳本
- 輸出檔案的名稱后綴為“_preview”
- 如果它有后綴,相同的輸入檔案夾是可以的,
- 視頻檔案 (mkv,mp4,avi,..)
- 一些檔案名有 unicode 字符,所以我認為輸入檔案將在“”內
uj5u.com熱心網友回復:
最簡單的可能是保持腳本不變并使用 bash 回圈來處理輸入目錄中的所有檔案。讓我們假設:
- 輸入目錄是
/my/video/files, - 您想將所有輸出存盤在目錄
/some/where中, - 你展示的腳本在
/else/where/myscript.sh, - 您要處理輸入目錄中的所有檔案。
只需打開bash互動式 shell 所在的終端并鍵入:
shopt -s nullglob
chmod x /else/where/myscript.sh
mkdir -p /some/where
cd /my/video/files
for f in *; do
/else/where/myscript.sh "$f" "/some/where/$f"
done
shopt -u nullglob
說明:
shopt -s nullglob啟用該nullglob選項。如果沒有這個,如果輸入目錄中根本沒有檔案,那么回圈仍然會迭代一次f=*.shopt -u nullglob完成后禁用它。chmod x /else/where/myscript.sh使您的腳本可執行,以防萬一它還沒有。mkdir -p /some/where創建輸出目錄,以防萬一它還不存在。cd /my/video/files將當前目錄更改為您擁有視頻檔案的輸入目錄。for f in *; do回圈遍歷當前目錄中的所有檔案(這就是*代表的意思)。在每個迭代變數f中都分配了當前檔案名。/else/where/myscript.sh "$f" "/some/where/$f"使用兩個引數執行您的腳本:輸入檔案的名稱和輸出檔案的名稱,兩者都用雙引號引起來以防止分詞。
注意:如果所有檔案都不是視頻檔案,您可以更具體:
for f in *.mkv *.mp4 *.avi; do
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/414661.html
標籤:
