[英]I'm trying to batch convert different video files into mkv using arrays in a bash script using mkvmerge or ffmpeg
我有一個腳本,用於將我的視頻文件轉換為 bash 腳本,使用 ffmpeg 或 mkvmerge 從多個視頻格式擴展名轉換。 通過使用read extension
輸入擴展名,我可以毫無問題地對腳本中的單個擴展名進行批量轉換,但是我試圖弄清楚如何使用視頻擴展名數組來做到這一點,所以我沒有輸入要轉換的每個分機。 我想我可以根據需要向數組添加更多擴展。
我對在 bash 文件中使用 arrays 完全陌生,所以這對我來說是全新的領域。
我正在嘗試做的是,這樣我就可以將腳本放入包含要轉換的視頻的目錄中,運行腳本並將它找到的所有視頻(從數組列表中的視頻)轉換為 mkv。 我正在嘗試使用數組來做到這一點,但它並不完全正確。 它適用於列表中的第一項,avi,但是當它到達第二項並進入數組中擴展名的 rest 時,它不會將通配符文件名放入腳本中,因此不處理文件名。 這是我目前擁有的:
#!/bin/bash
auto_ext=(avi mp4 m4p m4v webm mpg mp2 mpeg mpe mpv ogg wmv mov qt)
menu_option_one() {
echo ""
echo ""
echo -n " Enter file extension of file to convert: "
read extension
for f in *.$extension; do mkvmerge -o "${f%}.mkv" "$f";done
}
menu_option_two() {
for f in *.${auto_ext[*]}; do mkvmerge -o "${f%}.mkv" "$f";done
}
menu_option_three() {
echo ""
echo ""
echo -n " Enter file extension of file to convert: "
read extension
for f in *.$extension; do ffmpeg -i "$f" "${f%}.mkv";done
}
menu_option_four() {
for f in *.${auto_ext[*]}; do ffmpeg -i "$f" "${f%}.mkv";done
}
press_enter() {
unset auto_ext
unset extension
echo ""
echo -n " Press Enter to continue... "
read
clear
}
incorrect_selection() {
echo "Incorrect selection! Try again."
}
until [ "$selection" = "0" ]; do
clear
echo ""
echo " This file converts video files to mkv in the current directory only... "
echo ""
echo " 1 - Use mkvmerge (fastest, decent quality)"
echo " 2 - Autoconvert all files using mkvmerge"
echo " 3 - Use ffmpeg (slowest, best quality)"
echo " 4 - Autoconvert all files using ffmpeg"
echo " 0 - Exit"
echo ""
echo -n " Enter selection: "
read selection
echo ""
case $selection in
1 ) clear ; menu_option_one ; press_enter ;;
2 ) clear ; menu_option_two ; press_enter ;;
3 ) clear ; menu_option_three ; press_enter ;;
4 ) clear ; menu_option_four ; press_enter ;;
0 ) clear ; exit ;;
* ) clear ; incorrect_selection ; press_enter ;;
esac
done
exit 0
當目錄中有.mp4、.webm 和.m4p 時,我為 mkvmerge 獲得的 output 是:
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file '*.avi' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mp4' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'm4p' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'm4v' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'webm' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mpg' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mp2' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mpeg' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mpe' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mpv' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'ogg' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'wmv' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'mov' could not be opened for reading: open file error.
mkvmerge v45.0.0 ('Heaven in Pennies') 64-bit
Error: The file 'qt' could not be opened for reading: open file error.
ffmpeg 只是說*.: No such file or directory
我曾嘗試在 for 循環中同時使用通配符數組 [*] 和數組 [@],但我得到了相同的結果。 老實說,我不確定兩者之間有什么區別。 我在這里和其他論壇中進行了搜索,問題都集中在僅將一種視頻類型轉換為另一種視頻類型上,而不是同時查找和轉換多種格式。 我想我可能錯過了處理數組的步驟,但這只是一個猜測。
由於 output 為未找到的擴展添加了錯誤,我想我也會將錯誤定向到腳本中某處的 null 但我不確定在哪里。
在menu_option_two()
function 中,語句
for f in *.${auto_ext[*]}
擴展為:
for f in *.avi mp4 m4p m4v webm ...
將 f 分配給 *.avi(如果存在)、mp4、m4p、...的每個全局文件
您將需要創建雙循環:
for ext in "${auto_ext[@]}"; do
for f in *."$ext"; do
if [[ -f $f ]]; then
mkvmerge -o "${f%$ext}mkv" "$f"
fi
done
done
if [[ -f $f ]]
條件來避免將變量f
分配給文字*.avi
,例如,當類型 glob 失敗時。 (或者,您可以設置nullglob
shopt 選項。)
正如 Ishiano 建議的那樣,我最終做的是一個雙循環,但有一點不同的轉折。
for ext in ${auto_ext_2[@]}; do
count_file=`ls -1 *.${ext} 2>/dev/null | wc -l`
if [ $count_file != 0 ]
then
for f in *.$ext; do
ffmpeg -i "$f" "${f%.$ext}.mkv";
done
fi
在運行雙循環的第一部分以轉換文件后,我想檢查擴展名是否真的在目錄中。 線
count_file=`ls -1 *.${ext} 2>/dev/null | wc -l
檢查目錄中是否有任何擴展名大於零的文件,如果 count_file 數量大於零,它將運行雙循環的第二部分,如果數量為零,它將跳過第二部分共。 我的過程有點不同,但它奏效了,所以我很高興。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.